diff options
author | Rick Stockton <rickstockton@reno-computerhelp.com> | 2014-01-19 10:44:31 -0800 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-27 23:55:12 +0100 |
commit | 9063edef796ad10eb9ac2229627f36d60168f0e2 (patch) | |
tree | b52ad219afc1770c890ea5474ce5afdeb7b6016d /src | |
parent | b7de9e7353a0caccceb309c03343e80dbe117dbb (diff) |
If DblClick, do not deliver 'duplicated' MouseButtonPress
QWidgetWIndow: In Qt4, when Qt created a MouseButtonDblClick
event, Qt would consume the causing MouseButtonPress.
It would send only the derived dblclick event to widget
windows and their children.
This change makes Qt5.3 and higher emulate Qt4 delivery
of double click-related events to widget windows and
their children. QML objects (e.g. mousearea) continue to
receive the second MouseButtonPress.
[ChangeLog][QtGui][QWidget] MouseButtonDblClick: Do not send
the 2nd MouseButtonPress event to Widgets. Restore Qt4
behavior in sequence of mouse events delivered to
widget windows and their children.
Task-number: QTBUG-25831
Change-Id: Iff0f9c592bceacb2ca844d30f8180081e136a889
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/global/qnamespace.h | 8 | ||||
-rw-r--r-- | src/corelib/global/qnamespace.qdoc | 13 | ||||
-rw-r--r-- | src/gui/kernel/qevent.cpp | 14 | ||||
-rw-r--r-- | src/gui/kernel/qevent.h | 1 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 21 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication_p.h | 3 | ||||
-rw-r--r-- | src/widgets/kernel/qapplication.cpp | 9 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 19 |
8 files changed, 81 insertions, 7 deletions
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 06a1aa1c91..e6caf798d8 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1609,6 +1609,13 @@ public: MouseEventSynthesizedBySystem, MouseEventSynthesizedByQt }; + + enum MouseEventFlag { + MouseEventCreatedDoubleClick = 0x01, + MouseEventFlagMask = 0xFF + }; + Q_DECLARE_FLAGS(MouseEventFlags, MouseEventFlag) + } #ifdef Q_MOC_RUN ; @@ -1632,6 +1639,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TextInteractionFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::InputMethodQueries) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::InputMethodHints) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TouchPointStates) +Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MouseEventFlags) #ifndef QT_NO_GESTURES Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::GestureFlags) #endif diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 851b6609ea..f05cd0fd7e 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2917,3 +2917,16 @@ \sa Qt::AA_SynthesizeMouseForUnhandledTouchEvents */ + +/*! + \enum Qt::MouseEventFlag + \since 5.3 + + This enum provides additional information concerning a QMouseEvent. + + \value MouseEventCreatedDoubleClick Indicates that Qt has created a + MouseButtonDblClick event from this event. The flag is set in the causing + MouseButtonPress, and not in the resulting MouseButtonDblCLick. + + \omitvalue MouseEventFlagMask +*/ diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index a474d70190..7759e812cb 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -294,6 +294,20 @@ Qt::MouseEventSource QMouseEvent::source() const } /*! + \since 5.3 + + Returns the mouse event flags. + + The mouse event flags provide additional information about a mouse event. + + \sa Qt::MouseEventFlag + */ +Qt::MouseEventFlags QMouseEvent::flags() const +{ + return QGuiApplicationPrivate::mouseEventFlags(this); +} + +/*! \fn QPointF QMouseEvent::localPos() const \since 5.0 diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index b6b1e0c76b..0a826284c9 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -136,6 +136,7 @@ public: #endif Qt::MouseEventSource source() const; + Qt::MouseEventFlags flags() const; protected: QPointF l, w, s; diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index a753e6018c..3ad98fd137 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1600,6 +1600,11 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo return; } + if (doubleClick && (ev.type() == QEvent::MouseButtonPress)) { + // QtBUG-25831, used to suppress delivery in qwidgetwindow.cpp + setMouseEventFlags(&ev, ev.flags() | Qt::MouseEventCreatedDoubleClick); + } + QGuiApplication::sendSpontaneousEvent(window, &ev); if (!e->synthetic && !ev.isAccepted() && !frameStrut @@ -3169,6 +3174,8 @@ enum { MouseSourceMaskDst = 0xFF00, MouseSourceMaskSrc = MouseCapsMask, MouseSourceShift = 8, + MouseFlagsCapsMask = 0xFF0000, + MouseFlagsShift = 16 }; int QGuiApplicationPrivate::mouseEventCaps(QMouseEvent *event) @@ -3204,6 +3211,20 @@ void QGuiApplicationPrivate::setMouseEventSource(QMouseEvent *event, Qt::MouseEv event->caps |= (value & MouseSourceMaskSrc) << MouseSourceShift; } +Qt::MouseEventFlags QGuiApplicationPrivate::mouseEventFlags(const QMouseEvent *event) +{ + return Qt::MouseEventFlags((event->caps & MouseFlagsCapsMask) >> MouseFlagsShift); +} + +void QGuiApplicationPrivate::setMouseEventFlags(QMouseEvent *event, Qt::MouseEventFlags flags) +{ + // use the 0x00FF0000 byte from caps (containing up to 7 mouse event flags) + unsigned int value = flags; + Q_ASSERT(value <= Qt::MouseEventFlagMask); + event->caps &= ~MouseFlagsCapsMask; + event->caps |= (value & Qt::MouseEventFlagMask) << MouseFlagsShift; +} + #include "moc_qguiapplication.cpp" QT_END_NAMESPACE diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 95ee8eb295..57c55e1e0f 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -272,6 +272,9 @@ public: static Qt::MouseEventSource mouseEventSource(const QMouseEvent *event); static void setMouseEventSource(QMouseEvent *event, Qt::MouseEventSource source); + static Qt::MouseEventFlags mouseEventFlags(const QMouseEvent *event); + static void setMouseEventFlags(QMouseEvent *event, Qt::MouseEventFlags flags); + const QDrawHelperGammaTables *gammaTables(); // hook reimplemented in QApplication to apply the QStyle function on the QIcon diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index be349bfced..1f84a4b5c4 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -2767,6 +2767,13 @@ bool QApplication::notify(QObject *receiver, QEvent *e) QApplicationPrivate::mouse_buttons |= me->button(); break; } + case QEvent::MouseButtonDblClick: + { + QMouseEvent *me = static_cast<QMouseEvent*>(e); + QApplicationPrivate::modifier_buttons = me->modifiers(); + QApplicationPrivate::mouse_buttons |= me->button(); + break; + } case QEvent::MouseButtonRelease: { QMouseEvent *me = static_cast<QMouseEvent*>(e); @@ -2995,6 +3002,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) mouse->modifiers()); me.spont = mouse->spontaneous(); me.setTimestamp(mouse->timestamp()); + QGuiApplicationPrivate::setMouseEventFlags(&me, mouse->flags()); // throw away any mouse-tracking-only mouse events if (!w->hasMouseTracking() && mouse->type() == QEvent::MouseMove && mouse->buttons() == 0) { @@ -3748,6 +3756,7 @@ void QApplicationPrivate::giveFocusAccordingToFocusPolicy(QWidget *widget, QEven switch (event->type()) { case QEvent::MouseButtonPress: + case QEvent::MouseButtonDblClick: case QEvent::TouchBegin: if (setFocusOnRelease) return; diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 167102c633..1cf13c880b 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -473,7 +473,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) if (!widget) widget = m_widget; - if (event->type() == QEvent::MouseButtonPress) + if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) qt_button_down = widget; QWidget *receiver = QApplicationPrivate::pickMouseReceiver(m_widget, event->windowPos().toPoint(), &mapped, event->type(), event->buttons(), @@ -484,12 +484,17 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) QApplicationPrivate::mouse_buttons &= ~event->button(); return; } - - QMouseEvent translated(event->type(), mapped, event->windowPos(), event->screenPos(), event->button(), event->buttons(), event->modifiers()); - translated.setTimestamp(event->timestamp()); - QApplicationPrivate::sendMouseEvent(receiver, &translated, widget, m_widget, &qt_button_down, - qt_last_mouse_receiver); - + if ((event->type() != QEvent::MouseButtonPress) + || !(event->flags().testFlag(Qt::MouseEventCreatedDoubleClick))) { + + // The preceding statement excludes MouseButtonPress events which caused + // creation of a MouseButtonDblClick event. QTBUG-25831 + QMouseEvent translated(event->type(), mapped, event->windowPos(), event->screenPos(), + event->button(), event->buttons(), event->modifiers()); + translated.setTimestamp(event->timestamp()); + QApplicationPrivate::sendMouseEvent(receiver, &translated, widget, m_widget, + &qt_button_down, qt_last_mouse_receiver); + } #ifndef QT_NO_CONTEXTMENU if (event->type() == contextMenuTrigger && event->button() == Qt::RightButton) { QContextMenuEvent e(QContextMenuEvent::Mouse, mapped, event->globalPos(), event->modifiers()); |