diff options
author | Liang Qi <liang.qi@qt.io> | 2016-05-19 11:04:19 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2016-05-19 12:55:27 +0200 |
commit | 818014b449ef996099b4795a82f09651cf1c0129 (patch) | |
tree | 02f991007097fa368491a81eebbabe4cc162a0e0 /src/plugins/platforms/xcb | |
parent | e6cc1d788dddda2998a9f941664ede928ce1e212 (diff) | |
parent | 640441882d20f86db05ab5fd1141abe39a0bd409 (diff) |
Merge remote-tracking branch 'origin/5.6' into 5.7
Conflicts:
configure
src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
src/network/access/qnetworkaccessmanager.cpp
src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp
src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h
src/widgets/widgets/qlineedit_p.cpp
src/widgets/widgets/qlineedit_p.h
src/winmain/winmain.pro
tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp
tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h
tests/auto/testlib/selftests/expected_cmptest.teamcity
tests/auto/testlib/selftests/expected_cmptest.txt
tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
tools/configure/configureapp.cpp
Change-Id: Ib9997b0d0f91946e4081d36c0c6b696c5c983b2a
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbdrag.cpp | 16 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbdrag.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbmime.cpp | 61 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 9 |
4 files changed, 65 insertions, 23 deletions
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index b55fbd8f03..fb006ec0f1 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -56,6 +56,7 @@ #include <qpa/qwindowsysteminterface.h> +#include <private/qguiapplication_p.h> #include <private/qshapedpixmapdndwindow_p.h> #include <private/qsimpledrag_p.h> #include <private/qhighdpiscaling_p.h> @@ -176,6 +177,17 @@ QMimeData *QXcbDrag::platformDropData() return dropData; } +bool QXcbDrag::eventFilter(QObject *o, QEvent *e) +{ + /* We are setting a mouse grab on the QShapedPixmapWindow in order not to + * lose the grab when the virtual desktop changes, but + * QBasicDrag::eventFilter() expects the events to be coming from the + * window where the drag was started. */ + if (initiatorWindow && o == shapedPixmapWindow()) + o = initiatorWindow.data(); + return QBasicDrag::eventFilter(o, e); +} + void QXcbDrag::startDrag() { // #fixme enableEventFilter(); @@ -200,6 +212,7 @@ void QXcbDrag::startDrag() setUseCompositing(current_virtual_desktop->compositingActive()); setScreen(current_virtual_desktop->screens().constFirst()->screen()); + initiatorWindow = QGuiApplicationPrivate::currentMouseWindow; QBasicDrag::startDrag(); if (connection()->mouseGrabber() == Q_NULLPTR) shapedPixmapWindow()->setMouseGrabEnabled(true); @@ -208,6 +221,7 @@ void QXcbDrag::startDrag() void QXcbDrag::endDrag() { QBasicDrag::endDrag(); + initiatorWindow.clear(); } static xcb_translate_coordinates_reply_t * @@ -821,7 +835,7 @@ void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event) DEBUG("xdndHandleStatus"); waiting_for_status = false; // ignore late status messages - if (event->data.data32[0] && event->data.data32[0] != current_proxy_target) + if (event->data.data32[0] && event->data.data32[0] != current_target) return; const bool dropPossible = event->data.data32[1]; diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h index 7eac6cbbe0..f65dbda05d 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.h +++ b/src/plugins/platforms/xcb/qxcbdrag.h @@ -75,6 +75,7 @@ public: ~QXcbDrag(); virtual QMimeData *platformDropData() Q_DECL_OVERRIDE; + bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE; void startDrag() Q_DECL_OVERRIDE; void cancel() Q_DECL_OVERRIDE; @@ -112,6 +113,7 @@ private: Qt::DropAction toDropAction(xcb_atom_t atom) const; xcb_atom_t toXdndAction(Qt::DropAction a) const; + QPointer<QWindow> initiatorWindow; QPointer<QWindow> currentWindow; QPoint currentPosition; diff --git a/src/plugins/platforms/xcb/qxcbmime.cpp b/src/plugins/platforms/xcb/qxcbmime.cpp index a4a99ece64..825a8acd1f 100644 --- a/src/plugins/platforms/xcb/qxcbmime.cpp +++ b/src/plugins/platforms/xcb/qxcbmime.cpp @@ -117,17 +117,18 @@ bool QXcbMime::mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeDa QString atomName = mimeAtomToString(connection, a); if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) { *data = QInternalMimeData::renderDataHelper(atomName, mimeData); - if (atomName == QLatin1String("application/x-color")) + // mimeAtomToString() converts "text/x-moz-url" to "text/uri-list", + // so QXcbConnection::atomName() has to be used. + if (atomName == QLatin1String("text/uri-list") + && connection->atomName(a) == "text/x-moz-url") { + const QByteArray uri = data->split('\n').first(); + QString mozUri = QString::fromLatin1(uri, uri.size()); + mozUri += QLatin1Char('\n'); + *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), + mozUri.length() * 2); + } else if (atomName == QLatin1String("application/x-color")) *dataFormat = 16; ret = true; - } else if (atomName == QLatin1String("text/x-moz-url") && - QInternalMimeData::hasFormatHelper(QLatin1String("text/uri-list"), mimeData)) { - QByteArray uri = QInternalMimeData::renderDataHelper( - QLatin1String("text/uri-list"), mimeData).split('\n').first(); - QString mozUri = QString::fromLatin1(uri, uri.size()); - mozUri += QLatin1Char('\n'); - *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), mozUri.length() * 2); - ret = true; } else if ((a == XCB_ATOM_PIXMAP || a == XCB_ATOM_BITMAP) && mimeData->hasImage()) { ret = true; } @@ -188,17 +189,37 @@ QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, a == connection->atom(QXcbAtom::TEXT)) return QString::fromLatin1(data); } - - // special case for uri types - if (format == QLatin1String("text/uri-list")) { - if (atomName == QLatin1String("text/x-moz-url")) { - // we expect this as utf16 <url><space><title> - // the first part is a url that should only contain ascci char - // so it should be safe to check that the second char is 0 - // to verify that it is utf16 - if (data.size() > 1 && data.at(1) == 0) - return QString::fromRawData((const QChar *)data.constData(), - data.size() / 2).split(QLatin1Char('\n')).first().toLatin1(); + // If data contains UTF16 text, convert it to a string. + // Firefox uses UTF16 without BOM for text/x-moz-url, "text/html", + // Google Chrome uses UTF16 without BOM for "text/x-moz-url", + // UTF16 with BOM for "text/html". + if ((format == QLatin1String("text/html") || format == QLatin1String("text/uri-list")) + && data.size() > 1) { + const quint8 byte0 = data.at(0); + const quint8 byte1 = data.at(1); + if ((byte0 == 0xff && byte1 == 0xfe) || (byte0 == 0xfe && byte1 == 0xff) + || (byte0 != 0 && byte1 == 0) || (byte0 == 0 && byte1 != 0)) { + const QString str = QString::fromUtf16( + reinterpret_cast<const ushort *>(data.constData()), data.size() / 2); + if (!str.isNull()) { + if (format == QLatin1String("text/uri-list")) { + const QStringList urls = str.split(QLatin1Char('\n')); + QList<QVariant> list; + foreach (const QString &s, urls) { + const QUrl url(s.trimmed()); + if (url.isValid()) + list.append(url); + } + // We expect "text/x-moz-url" as <url><space><title>. + // The atomName variable is not used because mimeAtomToString() + // converts "text/x-moz-url" to "text/uri-list". + if (!list.isEmpty() && connection->atomName(a) == "text/x-moz-url") + return list.first(); + return list; + } else { + return str; + } + } } } diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 2c0f1f26b0..82ef8cc4df 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2336,9 +2336,14 @@ void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, i QPoint local(event_x, event_y); QPoint global(root_x, root_y); - // "mousePressWindow" can be NULL i.e. if a window will be grabbed or umnapped, so set it again here - if (connection()->buttons() != Qt::NoButton && connection()->mousePressWindow() == Q_NULLPTR) + // "mousePressWindow" can be NULL i.e. if a window will be grabbed or unmapped, so set it again here. + // Unset "mousePressWindow" when mouse button isn't pressed - in some cases the release event won't arrive. + const bool isMouseButtonPressed = (connection()->buttons() != Qt::NoButton); + const bool hasMousePressWindow = (connection()->mousePressWindow() != Q_NULLPTR); + if (isMouseButtonPressed && !hasMousePressWindow) connection()->setMousePressWindow(this); + else if (hasMousePressWindow && !isMouseButtonPressed) + connection()->setMousePressWindow(Q_NULLPTR); handleMouseEvent(timestamp, local, global, modifiers, source); } |