diff options
Diffstat (limited to 'src/gui/kernel/qguiapplication.cpp')
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 67 |
1 files changed, 58 insertions, 9 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index caa8aaca4b..22f4cdeaa3 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1679,7 +1679,7 @@ Qt::KeyboardModifiers QGuiApplication::queryKeyboardModifiers() /*! Returns the current state of the buttons on the mouse. The current state is - updated syncronously as the event queue is emptied of events that will + updated synchronously as the event queue is emptied of events that will spontaneously change the mouse state (QEvent::MouseButtonPress and QEvent::MouseButtonRelease events). @@ -3036,8 +3036,56 @@ void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::E #ifndef QT_NO_DRAGANDDROP -QPlatformDragQtResponse QGuiApplicationPrivate::processDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions) +/*! \internal + + This function updates an internal state to keep the source compatibility. Documentation of + QGuiApplication::mouseButtons() states - "The current state is updated synchronously as + the event queue is emptied of events that will spontaneously change the mouse state + (QEvent::MouseButtonPress and QEvent::MouseButtonRelease events)". But internally we have + been updating these state variables from various places to keep buttons returned by + mouseButtons() in sync with the systems state. This is not the documented behavior. + + ### Qt6 - Remove QGuiApplication::mouseButtons()/keyboardModifiers() API? And here + are the reasons: + + - It is an easy to misuse API by: + + a) Application developers: The only place where the values of this API can be trusted is + when using within mouse handling callbacks. In these callbacks we work with the state + that was provided directly by the windowing system. Anywhere else it might not reflect what + user wrongly expects. We might not always receive a matching mouse release for a press event + (e.g. When dismissing a popup window on X11. Or when dnd enter Qt application with mouse + button down, we update mouse_buttons and then dnd leaves Qt application and does a drop + somewhere else) and hence mouseButtons() will be out-of-sync from users perspective, see + for example QTBUG-33161. BUT THIS IS NOT HOW THE API IS SUPPOSED TO BE USED. Since the only + safe place to use this API is from mouse event handlers, we might as well deprecate it and + pass down the button state if we are not already doing that everywhere where it matters. + + b) Qt framework developers: + + We see users complaining, we start adding hacks everywhere just to keep buttons in sync ;) + There are corner cases that can not be solved and adding this kind of hacks is never ending + task. + + - Real mouse events, tablet mouse events, etc: all go through QGuiApplication::processMouseEvent, + and all share mouse_buttons. What if we want to support multiple mice in future? The API must + go. + + - Motivation why this API is public is not clear. Could the same be achieved by a user by + installing an event filter? +*/ +static void updateMouseAndModifierButtonState(Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) +{ + QGuiApplicationPrivate::mouse_buttons = buttons; + QGuiApplicationPrivate::modifier_buttons = modifiers; +} + +QPlatformDragQtResponse QGuiApplicationPrivate::processDrag(QWindow *w, const QMimeData *dropData, + const QPoint &p, Qt::DropActions supportedActions, + Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) { + updateMouseAndModifierButtonState(buttons, modifiers); + static QPointer<QWindow> currentDragWindow; static Qt::DropAction lastAcceptedDropAction = Qt::IgnoreAction; QPlatformDrag *platformDrag = platformIntegration()->drag(); @@ -3054,8 +3102,7 @@ QPlatformDragQtResponse QGuiApplicationPrivate::processDrag(QWindow *w, const QM lastAcceptedDropAction = Qt::IgnoreAction; return QPlatformDragQtResponse(false, lastAcceptedDropAction, QRect()); } - QDragMoveEvent me(p, supportedActions, dropData, - QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers()); + QDragMoveEvent me(p, supportedActions, dropData, buttons, modifiers); if (w != currentDragWindow) { lastAcceptedDropAction = Qt::IgnoreAction; @@ -3064,8 +3111,7 @@ QPlatformDragQtResponse QGuiApplicationPrivate::processDrag(QWindow *w, const QM QGuiApplication::sendEvent(currentDragWindow, &e); } currentDragWindow = w; - QDragEnterEvent e(p, supportedActions, dropData, - QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers()); + QDragEnterEvent e(p, supportedActions, dropData, buttons, modifiers); QGuiApplication::sendEvent(w, &e); if (e.isAccepted() && e.dropAction() != Qt::IgnoreAction) lastAcceptedDropAction = e.dropAction(); @@ -3083,10 +3129,13 @@ QPlatformDragQtResponse QGuiApplicationPrivate::processDrag(QWindow *w, const QM return QPlatformDragQtResponse(me.isAccepted(), lastAcceptedDropAction, me.answerRect()); } -QPlatformDropQtResponse QGuiApplicationPrivate::processDrop(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions) +QPlatformDropQtResponse QGuiApplicationPrivate::processDrop(QWindow *w, const QMimeData *dropData, + const QPoint &p, Qt::DropActions supportedActions, + Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) { - QDropEvent de(p, supportedActions, dropData, - QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers()); + updateMouseAndModifierButtonState(buttons, modifiers); + + QDropEvent de(p, supportedActions, dropData, buttons, modifiers); QGuiApplication::sendEvent(w, &de); Qt::DropAction acceptedAction = de.isAccepted() ? de.dropAction() : Qt::IgnoreAction; |