diff options
author | Paul Olav Tvete <paul.tvete@theqtcompany.com> | 2015-06-02 15:32:02 +0200 |
---|---|---|
committer | Paul Olav Tvete <paul.tvete@theqtcompany.com> | 2015-06-03 07:51:47 +0000 |
commit | 39413100cdc8cd7d3ef55ff3c79d94b7cf89cc5e (patch) | |
tree | f95d0ebd3a7bb69bab3b3bdef675667a9b978b07 /src/gui/kernel/qsimpledrag.cpp | |
parent | d0a017e9b03dd3cf19b640fad4dd56ef0494ce5f (diff) |
Fix drag and drop for Xcb
Make the xcb plugin work in native coordinates, using platform windows as
much as possible. As part of this, replace QMouseEvent in QBasicDrag with
just a QPoint. This is private API, so we can change this without warning.
In addition to xcb, QBasicDrag is used in QSimpleDrag and for Wayland.
QSimpleDrag does not yet have a fix for highDpi, but it should continue
working in the non-scaled case. Wayland (and any other module which uses
QBasicDrag) will need a compile fix.
Also fix bug in QWindowSystemInterface: handleDrag()/handleDrop()
take positions in window local coordinates, not global.
Change-Id: I86543e4f52a7b3ba1efeac815cf89bbd97c0a0a2
Reviewed-by: Morten Johan Sørvig <morten.sorvig@theqtcompany.com>
Diffstat (limited to 'src/gui/kernel/qsimpledrag.cpp')
-rw-r--r-- | src/gui/kernel/qsimpledrag.cpp | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp index 090e88c118..517f3024aa 100644 --- a/src/gui/kernel/qsimpledrag.cpp +++ b/src/gui/kernel/qsimpledrag.cpp @@ -55,6 +55,7 @@ #include <private/qdnd_p.h> #include <private/qshapedpixmapdndwindow_p.h> +#include <private/qhighdpiscaling_p.h> QT_BEGIN_NAMESPACE @@ -106,6 +107,12 @@ void QBasicDrag::disableEventFilter() qApp->removeEventFilter(this); } + +static inline QPoint getNativeMousePos(QEvent *e, QObject *o) +{ + return QHighDpi::toNativePixels(static_cast<QMouseEvent *>(e)->globalPos(), qobject_cast<QWindow*>(o)); +} + bool QBasicDrag::eventFilter(QObject *o, QEvent *e) { Q_UNUSED(o); @@ -139,19 +146,21 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e) } case QEvent::MouseMove: - move(static_cast<QMouseEvent *>(e)); + { + QPoint nativePosition = getNativeMousePos(e, o); + move(nativePosition); return true; // Eat all mouse events - + } case QEvent::MouseButtonRelease: disableEventFilter(); if (canDrop()) { - drop(static_cast<QMouseEvent *>(e)); + QPoint nativePosition = getNativeMousePos(e, o); + drop(nativePosition); } else { cancel(); } exitDndEventLoop(); return true; // Eat all mouse events - case QEvent::MouseButtonPress: case QEvent::MouseButtonDblClick: case QEvent::Wheel: @@ -218,13 +227,13 @@ void QBasicDrag::cancel() m_drag_icon_window->setVisible(false); } -void QBasicDrag::move(const QMouseEvent *) +void QBasicDrag::move(const QPoint &) { if (m_drag) m_drag_icon_window->updateGeometry(); } -void QBasicDrag::drop(const QMouseEvent *) +void QBasicDrag::drop(const QPoint &) { disableEventFilter(); restoreCursor(); @@ -321,14 +330,15 @@ void QSimpleDrag::cancel() } } -void QSimpleDrag::move(const QMouseEvent *me) +void QSimpleDrag::move(const QPoint &globalPos) { - QBasicDrag::move(me); - QWindow *window = topLevelAt(me->globalPos()); + //### not high-DPI aware + QBasicDrag::move(globalPos); + QWindow *window = topLevelAt(globalPos); if (!window) return; - const QPoint pos = me->globalPos() - window->geometry().topLeft(); + const QPoint pos = globalPos - window->geometry().topLeft(); const QPlatformDragQtResponse qt_response = QWindowSystemInterface::handleDrag(window, drag()->mimeData(), pos, drag()->supportedActions()); @@ -336,14 +346,16 @@ void QSimpleDrag::move(const QMouseEvent *me) setCanDrop(qt_response.isAccepted()); } -void QSimpleDrag::drop(const QMouseEvent *me) +void QSimpleDrag::drop(const QPoint &globalPos) { - QBasicDrag::drop(me); - QWindow *window = topLevelAt(me->globalPos()); + //### not high-DPI aware + + QBasicDrag::drop(globalPos); + QWindow *window = topLevelAt(globalPos); if (!window) return; - const QPoint pos = me->globalPos() - window->geometry().topLeft(); + const QPoint pos = globalPos - window->geometry().topLeft(); const QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(window, drag()->mimeData(),pos, drag()->supportedActions()); if (response.isAccepted()) { |