diff options
Diffstat (limited to 'src/gui/kernel/qapplication.cpp')
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 187 |
1 files changed, 162 insertions, 25 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 824d6f1..b142f2e 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -85,10 +85,13 @@ #include <stdlib.h> #include "qapplication_p.h" +#include "qevent_p.h" #include "qwidget_p.h" #include "qapplication.h" +#include <private/qgesturemanager_p.h> + #ifdef Q_WS_WINCE #include "qdatetime.h" #include "qguifunctions_wince.h" @@ -97,6 +100,8 @@ extern bool qt_wince_is_mobile(); //qguifunctions_wince.cpp extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp #endif +#include "qdatetime.h" + //#define ALIEN_DEBUG static void initResources() @@ -132,6 +137,14 @@ int QApplicationPrivate::autoMaximizeThreshold = -1; bool QApplicationPrivate::autoSipEnabled = false; #endif +QGestureManager* QGestureManager::instance() +{ + QApplicationPrivate *d = qApp->d_func(); + if (!d->gestureManager) + d->gestureManager = new QGestureManager(qApp); + return d->gestureManager; +} + QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::Type type) : QCoreApplicationPrivate(argc, argv) { @@ -155,6 +168,8 @@ QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::T directPainters = 0; #endif + gestureManager = 0; + if (!self) self = this; } @@ -2859,7 +2874,8 @@ QWidget *QApplicationPrivate::pickMouseReceiver(QWidget *candidate, const QPoint */ bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event, QWidget *alienWidget, QWidget *nativeWidget, - QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver) + QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver, + bool spontaneous) { Q_ASSERT(receiver); Q_ASSERT(event); @@ -2912,7 +2928,11 @@ bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event, // We need this quard in case someone opens a modal dialog / popup. If that's the case // leaveAfterRelease is set to null, but we shall not update lastMouseReceiver. const bool wasLeaveAfterRelease = leaveAfterRelease != 0; - bool result = QApplication::sendSpontaneousEvent(receiver, event); + bool result; + if (spontaneous) + result = QApplication::sendSpontaneousEvent(receiver, event); + else + result = QApplication::sendEvent(receiver, event); if (!graphicsWidget && leaveAfterRelease && event->type() == QEvent::MouseButtonRelease && !event->buttons() && QWidget::mouseGrabber() != leaveAfterRelease) { @@ -3571,6 +3591,18 @@ bool QApplication::notify(QObject *receiver, QEvent *e) #endif // !QT_NO_WHEELEVENT || !QT_NO_TABLETEVENT } + if (!d->grabbedGestures.isEmpty() && e->spontaneous() && receiver->isWidgetType()) { + const QEvent::Type t = e->type(); + if (t == QEvent::MouseButtonPress || t == QEvent::MouseButtonRelease || t == QEvent::MouseMove + || t == QEvent::MouseButtonDblClick || t == QEvent::Wheel + || t == QEvent::KeyPress || t == QEvent::KeyRelease + || t == QEvent::TabletPress || t == QEvent::TabletRelease || t == QEvent::TabletMove + || t >= QEvent::User) { + if (QGestureManager::instance()->filterEvent(static_cast<QWidget*>(receiver), e)) + return true; + } + } + // User input and window activation makes tooltips sleep switch (e->type()) { case QEvent::Wheel: @@ -3698,19 +3730,10 @@ bool QApplication::notify(QObject *receiver, QEvent *e) QPoint relpos = mouse->pos(); if (e->spontaneous()) { - if (e->type() == QEvent::MouseButtonPress) { - QWidget *fw = w; - while (fw) { - if (fw->isEnabled() - && QApplicationPrivate::shouldSetFocus(fw, Qt::ClickFocus)) { - fw->setFocus(Qt::MouseFocusReason); - break; - } - if (fw->isWindow()) - break; - fw = fw->parentWidget(); - } + QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, + Qt::ClickFocus, + Qt::MouseFocusReason); } if (e->type() == QEvent::MouseMove && mouse->buttons() == 0) { @@ -3792,17 +3815,9 @@ bool QApplication::notify(QObject *receiver, QEvent *e) bool eventAccepted = wheel->isAccepted(); if (e->spontaneous()) { - QWidget *fw = w; - while (fw) { - if (fw->isEnabled() - && QApplicationPrivate::shouldSetFocus(fw, Qt::WheelFocus)) { - fw->setFocus(Qt::MouseFocusReason); - break; - } - if (fw->isWindow()) - break; - fw = fw->parentWidget(); - } + QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, + Qt::WheelFocus, + Qt::MouseFocusReason); } while (w) { @@ -4007,7 +4022,48 @@ bool QApplication::notify(QObject *receiver, QEvent *e) } break; #endif + case QEvent::TouchBegin: + // Note: TouchUpdate and TouchEnd events are sent to d->currentMultitouchWidget and never propagated + { + QWidget *widget = static_cast<QWidget *>(receiver); + QWidget *origin = widget; + QTouchEvent *touchEvent = static_cast<QTouchEvent *>(e); + bool eventAccepted = touchEvent->isAccepted(); + if (widget->testAttribute(Qt::WA_AcceptTouchEvents) && e->spontaneous()) { + // give the widget focus if the focus policy allows it + QApplicationPrivate::giveFocusAccordingToFocusPolicy(widget, + Qt::ClickFocus, + Qt::MouseFocusReason); + } + while (widget) { + // first, try to deliver the touch event + touchEvent->ignore(); + res = widget->testAttribute(Qt::WA_AcceptTouchEvents) + && d->notify_helper(widget, touchEvent); + eventAccepted = touchEvent->isAccepted(); + widget->setAttribute(Qt::WA_AcceptedTouchBeginEvent, res && eventAccepted); + touchEvent->spont = false; + if (res && eventAccepted) { + // the first widget to accept the TouchBegin gets an implicit grab. + for (int i = 0; i < touchEvent->_touchPoints.count(); ++i) { + QTouchEvent::TouchPoint *touchPoint = touchEvent->_touchPoints.at(i); + d->widgetForTouchPointId[touchPoint->d->id] = widget; + } + if (origin != widget) + d->widgetCurrentTouchPoints.remove(origin); + d->widgetCurrentTouchPoints[widget] = touchEvent->_touchPoints; + break; + } else if (widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) { + break; + } + widget = widget->parentWidget(); + d->updateTouchPointsForWidget(widget, touchEvent); + } + + touchEvent->setAccepted(eventAccepted); + break; + } default: res = d->notify_helper(receiver, e); break; @@ -4974,6 +5030,23 @@ Qt::LayoutDirection QApplication::keyboardInputDirection() return qt_keymapper_private()->keyboardInputDirection; } +void QApplicationPrivate::giveFocusAccordingToFocusPolicy(QWidget *widget, + Qt::FocusPolicy focusPolicy, + Qt::FocusReason focusReason) +{ + QWidget *focusWidget = widget; + while (focusWidget) { + if (focusWidget->isEnabled() + && QApplicationPrivate::shouldSetFocus(focusWidget, focusPolicy)) { + focusWidget->setFocus(focusReason); + break; + } + if (focusWidget->isWindow()) + break; + focusWidget = focusWidget->parentWidget(); + } +} + bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy) { QWidget *f = w; @@ -4987,6 +5060,57 @@ bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy) return true; } +/*! + \since 4.6 + + Adds custom gesture \a recognizer object. + + Qt takes ownership of the provided \a recognizer. + + \sa Qt::AA_EnableGestures, QGestureEvent +*/ +void QApplication::addGestureRecognizer(QGestureRecognizer *recognizer) +{ + QGestureManager::instance()->addRecognizer(recognizer); +} + +/*! + \since 4.6 + + Removes custom gesture \a recognizer object. + + \sa Qt::AA_EnableGestures, QGestureEvent +*/ +void QApplication::removeGestureRecognizer(QGestureRecognizer *recognizer) +{ + Q_D(QApplication); + if (!d->gestureManager) + return; + d->gestureManager->removeRecognizer(recognizer); +} + +/*! + \property QApplication::eventDeliveryDelayForGestures + \since 4.6 + + Specifies the \a delay before input events are delivered to the + gesture enabled widgets. + + The delay allows to postpone widget's input event handling until + gestures framework can successfully recognize a gesture. + + \sa QWidget::grabGesture +*/ +void QApplication::setEventDeliveryDelayForGestures(int delay) +{ + QGestureManager::instance()->setEventDeliveryDelay(delay); +} + +int QApplication::eventDeliveryDelayForGestures() +{ + return QGestureManager::instance()->eventDeliveryDelay(); +} + /*! \fn QDecoration &QApplication::qwsDecoration() Return the QWSDecoration used for decorating windows. @@ -5118,6 +5242,19 @@ bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy) This normally takes some time. Does nothing on other platforms. */ +void QApplicationPrivate::updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent) +{ + for (int i = 0; i < touchEvent->_touchPoints.count(); ++i) { + QTouchEvent::TouchPoint *touchPoint = touchEvent->_touchPoints.at(i); + + // preserve the sub-pixel resolution + const QPointF delta = touchPoint->d->screenPos - touchPoint->d->screenPos.toPoint(); + touchPoint->d->pos = widget->mapFromGlobal(touchPoint->d->screenPos.toPoint()) + delta; + touchPoint->d->startPos = widget->mapFromGlobal(touchPoint->d->startScreenPos.toPoint()) + delta; + touchPoint->d->lastPos = widget->mapFromGlobal(touchPoint->d->lastScreenPos.toPoint()) + delta; + } +} + QT_END_NAMESPACE #include "moc_qapplication.cpp" |