summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qapplication.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel/qapplication.cpp')
-rw-r--r--src/gui/kernel/qapplication.cpp187
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"