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 @@ -293,6 +293,20 @@ Qt::MouseEventSource QMouseEvent::source() const return QGuiApplicationPrivate::mouseEventSource(this); } +/*! + \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 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(e); + QApplicationPrivate::modifier_buttons = me->modifiers(); + QApplicationPrivate::mouse_buttons |= me->button(); + break; + } case QEvent::MouseButtonRelease: { QMouseEvent *me = static_cast(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; } + if ((event->type() != QEvent::MouseButtonPress) + || !(event->flags().testFlag(Qt::MouseEventCreatedDoubleClick))) { - 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); - + // 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());