summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-05-19 11:04:19 +0200
committerLiang Qi <liang.qi@qt.io>2016-05-19 12:55:27 +0200
commit818014b449ef996099b4795a82f09651cf1c0129 (patch)
tree02f991007097fa368491a81eebbabe4cc162a0e0 /src/plugins/platforms/xcb
parente6cc1d788dddda2998a9f941664ede928ce1e212 (diff)
parent640441882d20f86db05ab5fd1141abe39a0bd409 (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.cpp16
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbmime.cpp61
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp9
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);
}