summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qapplication_x11.cpp2
-rw-r--r--src/gui/kernel/qdnd_x11.cpp6
-rw-r--r--src/gui/kernel/qevent.cpp158
-rw-r--r--src/gui/kernel/qstandardgestures.cpp18
-rw-r--r--src/gui/kernel/qt_mac.cpp19
-rw-r--r--src/gui/kernel/qwidget_mac.mm2
6 files changed, 144 insertions, 61 deletions
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index d942519..0d07a02 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -4572,6 +4572,7 @@ bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet
int deviceType = QTabletEvent::NoDevice;
int pointerType = QTabletEvent::UnknownPointer;
XEvent mouseMotionEvent;
+ XEvent dummy;
const XDeviceMotionEvent *motion = 0;
XDeviceButtonEvent *button = 0;
const XProximityNotifyEvent *proximity = 0;
@@ -4589,7 +4590,6 @@ bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet
// Do event compression. Skip over tablet+mouse move events if there are newer ones.
qt_tablet_motion_data tabletMotionData;
tabletMotionData.tabletMotionType = tablet->xinput_motion;
- XEvent dummy;
while (true) {
// Find first mouse event since we expect them in pairs inside Qt
tabletMotionData.error =false;
diff --git a/src/gui/kernel/qdnd_x11.cpp b/src/gui/kernel/qdnd_x11.cpp
index a4042c1..8f92fea 100644
--- a/src/gui/kernel/qdnd_x11.cpp
+++ b/src/gui/kernel/qdnd_x11.cpp
@@ -1073,12 +1073,14 @@ void qt_xdnd_send_leave()
if (!qt_xdnd_current_target)
return;
+ QDragManager *manager = QDragManager::self();
+
XClientMessageEvent leave;
leave.type = ClientMessage;
leave.window = qt_xdnd_current_target;
leave.format = 32;
leave.message_type = ATOM(XdndLeave);
- leave.data.l[0] = qt_xdnd_dragsource_xid;
+ leave.data.l[0] = manager->dragPrivate()->source->effectiveWinId();
leave.data.l[1] = 0; // flags
leave.data.l[2] = 0; // x, y
leave.data.l[3] = 0; // w, h
@@ -1094,8 +1096,8 @@ void qt_xdnd_send_leave()
else
XSendEvent(X11->display, qt_xdnd_current_proxy_target, False,
NoEventMask, (XEvent*)&leave);
+
// reset the drag manager state
- QDragManager *manager = QDragManager::self();
manager->willDrop = false;
if (global_accepted_action != Qt::IgnoreAction)
manager->emitActionChanged(Qt::IgnoreAction);
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 7365820..3e1d12d 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -3538,38 +3538,108 @@ QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar)
\since 4.6
\ingroup events
- Touch events occur when pressing, releasing, or moving one or more
- touch points on a touch device (such as a touch-screen or
- track-pad). To receive touch events, widgets have to have the
- Qt::WA_AcceptTouchEvents attribute set and graphics items need to have
- the \l{QGraphicsItem::setAcceptTouchEvents()}{acceptTouchEvents}
- attribute set to true.
-
- All touch events are of type QEvent::TouchBegin,
- QEvent::TouchUpdate, or QEvent::TouchEnd. The touchPoints()
- function returns a list of all touch points contained in the event.
- Information about each touch point can be retrieved using the
- QTouchEvent::TouchPoint class. The Qt::TouchPointState enum
- describes the different states that a touch point may have.
-
- Similar to QMouseEvent, Qt automatically grabs each touch point on
- the first press inside a widget; the widget will receive all
- updates for the touch point until it is released. Note that it is
- possible for a widget to receive events for multiple touch points,
- and that multiple widgets may be receiving touch events at the same
- time.
-
- A touch event contains a special accept flag that indicates
- whether the receiver wants the event. By default, the event is
- accepted. You should call ignore() if the touch event is not handled by
- your widget. A QEvent::TouchBegin event is propagated up the parent widget
- chain until a widget accepts it with accept(), or an event filter
- consumes it. If the QEvent::TouchBegin event is neither accepted nor consumed,
- then mouse events are simulated from the state of the first touch
- point.
-
- Reimplement QWidget::event() for widgets and QGraphicsItem::sceneEvent()
- for items in a graphics view to receive touch events.
+ \section1 Enabling Touch Events
+
+ Touch events occur when pressing, releasing, or moving one or more touch points on a touch
+ device (such as a touch-screen or track-pad). To receive touch events, widgets have to have the
+ Qt::WA_AcceptTouchEvents attribute set and graphics items need to have the
+ \l{QGraphicsItem::setAcceptTouchEvents()}{acceptTouchEvents} attribute set to true.
+
+ Note: when using QAbstractScrollArea based widgets, you should enabled the
+ Qt::WA_AcceptTouchEvents attribute on the scroll area's
+ \l{QAbstractScrollArea::viewport()}{viewport}.
+
+ \section1 Event Delivery and Propagation
+
+ All touch events are of type QEvent::TouchBegin, QEvent::TouchUpdate, or QEvent::TouchEnd.
+ Reimplement QWidget::event() or QAbstractScrollArea::viewportEvent() for widgets and
+ QGraphicsItem::sceneEvent() for items in a graphics view to receive touch events. By default,
+ QWidget::event() translates the first non-primary touch point in a QTouchEvent into a
+ QMouseEvent. This makes it possible to enable touch events on existing widgets that do not
+ normally handle QTouchEvent. See below for information on some special considerations needed
+ when doing this.
+
+ QEvent::TouchBegin is the first touch event sent to a widget. The QEvent::TouchBegin event
+ contains a special accept flag that indicates whether the receiver wants the event. By default,
+ the event is accepted. You should call ignore() if the touch event is not handled by your
+ widget. The QEvent::TouchBegin event is propagated up the parent widget chain until a widget
+ accepts it with accept(), or an event filter consumes it. For QGraphicsItems, the
+ QEvent::TouchBegin event is propagated to items under the mouse (similar to mouse event
+ propagation for QGraphicsItems).
+
+ The QEvent::TouchUpdate and QEvent::TouchEnd events are sent to the widget or item that
+ accepted the QEvent::TouchBegin event. If the QEvent::TouchBegin event is not accepted and not
+ filtered by an event filter, then no further touch events are sent until the next
+ QEvent::TouchBegin.
+
+ The touchPoints() function returns a list of all touch points contained in the event.
+ Information about each touch point can be retrieved using the QTouchEvent::TouchPoint class.
+ The Qt::TouchPointState enum describes the different states that a touch point may have.
+
+ Similar to QMouseEvent, Qt automatically grabs each touch point on the first press inside a
+ widget; the widget will receive all updates for the touch point until it is released. Note that
+ it is possible for a widget to receive events for multiple touch points, and that multiple
+ widgets may be receiving touch events at the same time.
+
+ \section1 Touch Point Grouping
+
+ As mentioned above, it is possible that several widgets can be receiving QTouchEvents at the
+ same time. However, Qt makes sure to never send duplicate QEvent::TouchBegin events to the same
+ widget, which could theoretically happen during propagation if, for example, the user touched 2
+ separate widgets in a QGroupBox and both widgets ignored the QEvent::TouchBegin event.
+
+ To avoid this, Qt will group new touch points together using the following rules:
+
+ \list
+
+ \i When the first touch point is detected, the destination widget is determined firstly by the
+ location on screen first and secondly by the propagation rules.
+
+ \i When additional touch points are detected, Qt first looks to see if there are any active
+ touch points on any ancestor or descendent of the widget under the new touch point. If there
+ are, the new touch point is grouped with the first, and the new touch point will be sent in a
+ single QTouchEvent to the widget that handled the first touch point. (The widget under the new
+ touch point will not receive an event).
+
+ \endlist
+
+ This makes it possible for sibling widgets to handle touch events independently while making
+ sure that the sequence of QTouchEvents is always correct.
+
+ \section1 Mouse Events and the Primary Touch Point
+
+ QTouchEvent delivery is independent from that of QMouseEvent. On some windowing systems, mouse
+ events are also sent for the \l{QTouchEvent::TouchPoint::isPrimary()}{primary touch point}.
+ This means it is possible for your widget to receive both QTouchEvent and QMouseEvent for the
+ same user interaction point. You can use the QTouchEvent::TouchPoint::isPrimary() function to
+ identify the primary touch point.
+
+ Note that on some systems, it is possible to receive touch events without a primary touch
+ point. All this means is that there will be no mouse event generated for the touch points in
+ the QTouchEvent.
+
+ \section1 Caveats
+
+ \list
+
+ \i As mentioned above, enabling touch events means multiple widgets can be receiving touch
+ events simultaneously. Combined with the default QWidget::event() handling for QTouchEvents,
+ this gives you great flexibility in designing multi-touch user interfaces. Be aware of the
+ implications. For example, is is possible that the user is moving a QSlider with one finger and
+ pressing a QPushButton with another. The signals are emitted from these widgets will be
+ interleaved.
+
+ \i Recursion into the event loop using one of the exec() methods (e.g. QDialog::exec() or
+ QMenu::exec()) in a QTouchEvent event handler is not supported. Since there are multiple event
+ recipients, unexpected recursion may cause problems, including but not limited to lost events
+ and unexpected infinite recursion.
+
+ \i QTouchEvents are not affected by a \l{QWidget::grabMouse()}{mouse grab} or an
+ \l{QApplication::activePopupWidget()}{active popup widget}. The behavior of QTouchEvents is
+ undefined when opening a popup or grabbing the mouse while there are multiple active touch
+ points.
+
+ \endlist
\sa QTouchEvent::TouchPoint, Qt::TouchPointState, Qt::WA_AcceptTouchEvents,
QGraphicsItem::acceptTouchEvents()
@@ -3648,6 +3718,11 @@ QTouchEvent::~QTouchEvent()
Returns the list of touch points contained in the touch event.
*/
+/*! \fn QTouchEvent::DeviceType QTouchEvent::deviceType() const
+
+ Returns the touch device Type, which is of type \l {QTouchEvent::DeviceType} {DeviceType}.
+*/
+
/*! \fn void QTouchEvent::setWidget(QWidget *widget)
\internal
@@ -3669,6 +3744,14 @@ QTouchEvent::~QTouchEvent()
Sets the list of touch points for this event.
*/
+/*! \fn void QTouchEvent::setDeviceType(DeviceType deviceType)
+
+ \internal
+
+ Sets the device type to \a deviceType, which is of type \l {QTouchEvent::DeviceType}
+ {DeviceType}.
+*/
+
/*! \class QTouchEvent::TouchPoint
\brief The QTouchEvent::TouchPoint class provides information about a touch point in a QTouchEvent.
\since 4.6
@@ -4080,15 +4163,4 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T
return *this;
}
-/*! \fn QTouchEvent::DeviceType QTouchEvent::deviceType() const
- Returns the touch device Type, which is of type
- \l {QTouchEvent::DeviceType} {DeviceType}.
- */
-
-/*! \fn void QTouchEvent::setDeviceType(DeviceType deviceType)
- Sets the device type to \a deviceType, which is of type
- \l {QTouchEvent::DeviceType} {DeviceType}.
- */
-
-
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp
index 47f3146..10689ba 100644
--- a/src/gui/kernel/qstandardgestures.cpp
+++ b/src/gui/kernel/qstandardgestures.cpp
@@ -172,8 +172,6 @@ bool QPanGesture::eventFilter(QObject *receiver, QEvent *event)
bool QPanGesture::filterEvent(QEvent *event)
{
Q_D(QPanGesture);
- if (!event->spontaneous())
- return false;
const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
if (event->type() == QEvent::TouchBegin) {
QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
@@ -329,10 +327,11 @@ bool QPinchGesture::event(QEvent *event)
bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event)
{
-#ifdef Q_WS_WIN
+#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
Q_D(QPinchGesture);
if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) {
QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
+#if defined(Q_WS_WIN)
QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
QApplicationPrivate::WidgetStandardGesturesMap::iterator it;
it = qAppPriv->widgetGestures.find(static_cast<QWidget*>(receiver));
@@ -340,7 +339,9 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event)
return false;
if (this != it.value().pinch)
return false;
+#endif
Qt::GestureState nextState = Qt::NoGesture;
+
switch(ev->gestureType) {
case QNativeGestureEvent::GestureBegin:
// next we might receive the first gesture update event, so we
@@ -349,15 +350,22 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event)
d->scaleFactor = d->lastScaleFactor = 1;
d->rotationAngle = d->lastRotationAngle = 0;
d->startCenterPoint = d->centerPoint = d->lastCenterPoint = QPoint();
+#if defined(Q_WS_WIN)
d->initialDistance = 0;
+#endif
return false;
case QNativeGestureEvent::Rotate:
d->lastRotationAngle = d->rotationAngle;
+#if defined(Q_WS_WIN)
d->rotationAngle = -1 * GID_ROTATE_ANGLE_FROM_ARGUMENT(ev->argument);
+#elif defined(Q_WS_MAC)
+ d->rotationAngle = ev->percentage;
+#endif
nextState = Qt::GestureUpdated;
event->accept();
break;
case QNativeGestureEvent::Zoom:
+#if defined(Q_WS_WIN)
if (d->initialDistance != 0) {
d->lastScaleFactor = d->scaleFactor;
int distance = int(qint64(ev->argument));
@@ -365,6 +373,10 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event)
} else {
d->initialDistance = int(qint64(ev->argument));
}
+#elif defined(Q_WS_MAC)
+ d->lastScaleFactor = d->scaleFactor;
+ d->scaleFactor = ev->percentage;
+#endif
nextState = Qt::GestureUpdated;
event->accept();
break;
diff --git a/src/gui/kernel/qt_mac.cpp b/src/gui/kernel/qt_mac.cpp
index 642aa5c..bef3449 100644
--- a/src/gui/kernel/qt_mac.cpp
+++ b/src/gui/kernel/qt_mac.cpp
@@ -1,11 +1,11 @@
/****************************************************************************
- **
- ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
- **
- ** This file is part of the QtGui module of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:LGPL$
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
@@ -36,11 +36,8 @@
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
** $QT_END_LICENSE$
- **
- ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- **
- ****************************************************************************/
+**
+****************************************************************************/
#include <private/qt_mac_p.h>
#include <private/qpixmap_mac_p.h>
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 999faeb..71571e4 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -1055,7 +1055,7 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event,
handled_event = false;
break;
}
- qNGEvent.gestureType = QNativeGestureEvent::Zoom;
+ qNGEvent.gestureType = QNativeGestureEvent::Rotate;
qNGEvent.percentage = float(amount);
break; }
case kEventGestureSwipe: {