diff -Nru qtbase-opensource-src-5.5.1+dfsg/debian/changelog qtbase-opensource-src-5.5.1+dfsg/debian/changelog --- qtbase-opensource-src-5.5.1+dfsg/debian/changelog 2016-04-12 16:18:20.000000000 +0000 +++ qtbase-opensource-src-5.5.1+dfsg/debian/changelog 2017-05-03 19:22:47.000000000 +0000 @@ -1,3 +1,46 @@ +qtbase-opensource-src (5.5.1+dfsg-16ubuntu7.5) xenial; urgency=medium + + * Backport upstream change to fix behavior of QMenuBar::isNativeMenuBar() + method (fix_isNativeMenuBar.diff). This should finally fix LP: #1380702. + + -- Dmitry Shachnev Wed, 03 May 2017 22:22:47 +0300 + +qtbase-opensource-src (5.5.1+dfsg-16ubuntu7.4) xenial; urgency=medium + + [ Elvis Stansvik ] + * debian/patches/xcb-compress-mouse-motion-and-touch-update-events.patch: + - Backport event compression fix from Qt 5.6 branch (LP: #1598173) + + -- Dmitry Shachnev Thu, 23 Mar 2017 23:17:09 +0300 + +qtbase-opensource-src (5.5.1+dfsg-16ubuntu7.3) xenial; urgency=medium + + * Backport upstream change to make shortcuts working with global menu + on Unity (global_menu_shortcuts.diff, LP: #1380702). + + -- Dmitry Shachnev Mon, 13 Mar 2017 18:40:39 +0300 + +qtbase-opensource-src (5.5.1+dfsg-16ubuntu7.2) xenial; urgency=medium + + * debian/patches/Fix-parsing-of-tzfile-5-POSIX-rule-zone-names-with-b.patch: + - Backport a timezone conversion fix from Qt 5.6.2 (LP: #1622089) + + -- Timo Jyrinki Mon, 12 Sep 2016 05:49:32 +0000 + +qtbase-opensource-src (5.5.1+dfsg-16ubuntu7.1) xenial; urgency=medium + + * debian/patches/Blacklist-Mali-T760-Mali-T720-from-supporting-BGRA.patch + - Backport from upstream 5.6 (LP: #1557915) (LP: #1559906) + * Add two patches from stable Qt 5.6 branch to fix another case of + QXcbWindow crashes (LP: #1571158). + - debian/patches/Fix-crash-because-of-NULL-screen-in-QXcbWindow.patch + - debian/patches/QtGui-Don-t-set-a-screen-to-a-child-window.patch + * Fix drag and drop issues with patches from upstream. (LP: #1577313) + - debian/patches/xcb-Fix-drag-and-drop-to-Emacs.patch + - debian/patches/xcb-Fix-drag-and-drop-to-applications-like-Emacs-and.patch + + -- Timo Jyrinki Mon, 02 May 2016 12:24:35 +0000 + qtbase-opensource-src (5.5.1+dfsg-16ubuntu7) xenial; urgency=medium [ Dmitry Shachnev ] diff -Nru qtbase-opensource-src-5.5.1+dfsg/debian/patches/Blacklist-Mali-T760-Mali-T720-from-supporting-BGRA.patch qtbase-opensource-src-5.5.1+dfsg/debian/patches/Blacklist-Mali-T760-Mali-T720-from-supporting-BGRA.patch --- qtbase-opensource-src-5.5.1+dfsg/debian/patches/Blacklist-Mali-T760-Mali-T720-from-supporting-BGRA.patch 1970-01-01 00:00:00.000000000 +0000 +++ qtbase-opensource-src-5.5.1+dfsg/debian/patches/Blacklist-Mali-T760-Mali-T720-from-supporting-BGRA.patch 2016-05-02 12:37:39.000000000 +0000 @@ -0,0 +1,41 @@ +From 87715cc4917e0edcc1090658ea09be508f47f3b7 Mon Sep 17 00:00:00 2001 +From: Timo Jyrinki +Date: Wed, 23 Mar 2016 09:41:50 +0000 +Subject: [PATCH] Blacklist Mali-T760/Mali-T720 from supporting BGRA. + +Extend the blacklist with Mali-T760 and Mali-T720 as found on Meizu +Pro 5 and Bq Aquaris M10 Ubuntu Editions. Reading from FBO like +taking screenshots does not produce correct result otherwise. + +Initially reported at: https://launchpad.net/bugs/1557915 and +https://launchpad.net/bugs/1559906 + +Change-Id: Ic875bd083277bf933863a3a50f8e874dd6e04365 +Reviewed-by: Laszlo Agocs +--- + src/gui/opengl/qopenglframebufferobject.cpp | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp +index 5184283..0e1074f 100644 +--- a/src/gui/opengl/qopenglframebufferobject.cpp ++++ b/src/gui/opengl/qopenglframebufferobject.cpp +@@ -1281,9 +1281,13 @@ static inline QImage qt_gl_read_framebuffer_rgba8(const QSize &size, bool includ + const char *renderer = reinterpret_cast(funcs->glGetString(GL_RENDERER)); + const char *ver = reinterpret_cast(funcs->glGetString(GL_VERSION)); + +- // Blacklist PowerVR Rogue G6200 as it has problems with its BGRA support. ++ // Blacklist GPU chipsets that have problems with their BGRA support. + const bool blackListed = (qstrcmp(renderer, "PowerVR Rogue G6200") == 0 +- && ::strstr(ver, "1.3") != 0); ++ && ::strstr(ver, "1.3") != 0) || ++ (qstrcmp(renderer, "Mali-T760") == 0 ++ && ::strstr(ver, "3.1") != 0) || ++ (qstrcmp(renderer, "Mali-T720") == 0 ++ && ::strstr(ver, "3.1") != 0); + + const bool supports_bgra = has_bgra_ext && !blackListed; + +-- +2.7.4 + diff -Nru qtbase-opensource-src-5.5.1+dfsg/debian/patches/Fix-crash-because-of-NULL-screen-in-QXcbWindow.patch qtbase-opensource-src-5.5.1+dfsg/debian/patches/Fix-crash-because-of-NULL-screen-in-QXcbWindow.patch --- qtbase-opensource-src-5.5.1+dfsg/debian/patches/Fix-crash-because-of-NULL-screen-in-QXcbWindow.patch 1970-01-01 00:00:00.000000000 +0000 +++ qtbase-opensource-src-5.5.1+dfsg/debian/patches/Fix-crash-because-of-NULL-screen-in-QXcbWindow.patch 2016-05-02 12:37:39.000000000 +0000 @@ -0,0 +1,44 @@ +From eaa3a9d0108cdf692f1686cafefb7b834f0e5af6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= +Date: Fri, 1 Jan 2016 20:02:42 +0100 +Subject: [PATCH] Fix crash because of NULL screen in QXcbWindow + +Change-Id: If7bbe3ad1656dadcb098bcd3ece2e7b064eeb44d +Task-number: QTBUG-50081 +Reviewed-by: Shawn Rutledge +--- + src/gui/kernel/qwindow.cpp | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp +index e728d32..83e8777 100644 +--- a/src/gui/kernel/qwindow.cpp ++++ b/src/gui/kernel/qwindow.cpp +@@ -609,18 +609,16 @@ void QWindow::setParent(QWindow *parent) + } + + QObject::setParent(parent); +- if (parent) ++ ++ QPlatformWindow *parentPlatformWindow = parent ? parent->d_func()->platformWindow : Q_NULLPTR; ++ ++ if (parentPlatformWindow) + d->disconnectFromScreen(); + else + d->connectToScreen(newScreen); + +- if (d->platformWindow) { +- if (parent && parent->d_func()->platformWindow) { +- d->platformWindow->setParent(parent->d_func()->platformWindow); +- } else { +- d->platformWindow->setParent(0); +- } +- } ++ if (d->platformWindow) ++ d->platformWindow->setParent(parentPlatformWindow); + + d->parentWindow = parent; + +-- +2.7.4 + diff -Nru qtbase-opensource-src-5.5.1+dfsg/debian/patches/fix_isNativeMenuBar.diff qtbase-opensource-src-5.5.1+dfsg/debian/patches/fix_isNativeMenuBar.diff --- qtbase-opensource-src-5.5.1+dfsg/debian/patches/fix_isNativeMenuBar.diff 1970-01-01 00:00:00.000000000 +0000 +++ qtbase-opensource-src-5.5.1+dfsg/debian/patches/fix_isNativeMenuBar.diff 2017-05-03 19:22:36.000000000 +0000 @@ -0,0 +1,65 @@ +Description: make QMenuBar::isNativeMenuBar() more reliable + Now it will not return true if the QPA plugin provides no platform menu bar, + and will not return false when Ubuntu global menu is in use. + . + Instead of trying to keep that variable in sync with platformMenuBar + state, just check whether platformMenuBar exists instead. +Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=835d7cf54328bdd9 +Last-Update: 2017-05-03 + +--- a/src/widgets/widgets/qmenubar.cpp ++++ b/src/widgets/widgets/qmenubar.cpp +@@ -1810,10 +1810,8 @@ + void QMenuBar::setNativeMenuBar(bool nativeMenuBar) + { + Q_D(QMenuBar); +- if (d->nativeMenuBar == -1 || (nativeMenuBar != bool(d->nativeMenuBar))) { +- d->nativeMenuBar = nativeMenuBar; +- +- if (!d->nativeMenuBar) { ++ if (nativeMenuBar != bool(d->platformMenuBar)) { ++ if (!nativeMenuBar) { + delete d->platformMenuBar; + d->platformMenuBar = 0; + } else { +@@ -1822,7 +1820,7 @@ + } + + updateGeometry(); +- if (!d->nativeMenuBar && parentWidget()) ++ if (!nativeMenuBar && parentWidget()) + setVisible(true); + } + } +@@ -1830,10 +1828,7 @@ + bool QMenuBar::isNativeMenuBar() const + { + Q_D(const QMenuBar); +- if (d->nativeMenuBar == -1) { +- return !QApplication::instance()->testAttribute(Qt::AA_DontUseNativeMenuBar); +- } +- return d->nativeMenuBar; ++ return bool(d->platformMenuBar); + } + + /*! +--- a/src/widgets/widgets/qmenubar_p.h ++++ b/src/widgets/widgets/qmenubar_p.h +@@ -59,7 +59,7 @@ + public: + QMenuBarPrivate() : itemsDirty(0), currentAction(0), mouseDown(0), + closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0), +- nativeMenuBar(-1), doChildEffects(false), platformMenuBar(0) ++ doChildEffects(false), platformMenuBar(0) + + #ifdef Q_OS_WINCE + , wce_menubar(0), wceClassicMenu(false) +@@ -102,8 +102,6 @@ + uint keyboardState : 1, altPressed : 1; + QPointer keyboardFocusWidget; + +- +- int nativeMenuBar : 3; // Only has values -1, 0, and 1 + //firing of events + void activateAction(QAction *, QAction::ActionEvent); + diff -Nru qtbase-opensource-src-5.5.1+dfsg/debian/patches/Fix-parsing-of-tzfile-5-POSIX-rule-zone-names-with-b.patch qtbase-opensource-src-5.5.1+dfsg/debian/patches/Fix-parsing-of-tzfile-5-POSIX-rule-zone-names-with-b.patch --- qtbase-opensource-src-5.5.1+dfsg/debian/patches/Fix-parsing-of-tzfile-5-POSIX-rule-zone-names-with-b.patch 1970-01-01 00:00:00.000000000 +0000 +++ qtbase-opensource-src-5.5.1+dfsg/debian/patches/Fix-parsing-of-tzfile-5-POSIX-rule-zone-names-with-b.patch 2016-09-12 05:07:58.000000000 +0000 @@ -0,0 +1,275 @@ +From e9041c7fc1052167f1ec2df0ea9623059e55d00f Mon Sep 17 00:00:00 2001 +From: Thiago Macieira +Date: Thu, 28 Apr 2016 22:09:01 -0700 +Subject: [PATCH] Fix parsing of tzfile(5) POSIX rule zone names with bracket + quotes + +POSIX.1-2001 allows quoting a zone name so that it can contain other +characters besides letters, by enclosing it in angle brackets ('<' and +'>'). This hadn't been used until recently (tzdata2016b), when the +Asia/Barnaul rule started using a zone name "+07" (the name variable +contained the value "<+07>-7"). + +Thanks to Paul Eggert for reporting and investigating the root cause. + +Task-number: QTBUG-53071 +Change-Id: Id5480807d25e49e78b79ffff1449bc410776cb66 +Reviewed-by: Edward Welbourne +Reviewed-by: Lars Knoll +--- + src/corelib/tools/qtimezoneprivate_tz.cpp | 176 ++++++++++++++------- + .../auto/corelib/tools/qtimezone/tst_qtimezone.cpp | 10 ++ + 2 files changed, 130 insertions(+), 56 deletions(-) + +diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp +index 85ed345..cb9581a 100644 +--- a/src/corelib/tools/qtimezoneprivate_tz.cpp ++++ b/src/corelib/tools/qtimezoneprivate_tz.cpp +@@ -41,6 +41,8 @@ + + #include + ++#include "qlocale_tools_p.h" ++ + #include + + QT_BEGIN_NAMESPACE +@@ -384,25 +386,100 @@ static QTime parsePosixTime(const QByteArray &timeRule) + return QTime(2, 0, 0); + } + +-static int parsePosixOffset(const QByteArray &timeRule) ++static int parsePosixOffset(const char *begin, const char *end) + { + // Format "[+|-]hh[:mm[:ss]]" +- QList parts = timeRule.split(':'); +- int count = parts.count(); +- if (count == 3) { +- int hour = parts.at(0).toInt(); +- int sign = hour >= 0 ? -1 : 1; +- return sign * ((qAbs(hour) * 60 * 60) + (parts.at(1).toInt() * 60) + parts.at(2).toInt()); +- } else if (count == 2) { +- int hour = parts.at(0).toInt(); +- int sign = hour >= 0 ? -1 : 1; +- return sign * ((qAbs(hour) * 60 * 60) + (parts.at(1).toInt() * 60)); +- } else if (count == 1) { +- int hour = parts.at(0).toInt(); +- int sign = hour >= 0 ? -1 : 1; +- return sign * (qAbs(hour) * 60 * 60); +- } +- return 0; ++ int hour, min = 0, sec = 0; ++ ++ // note that the sign is inverted because POSIX counts in hours West of GMT ++ bool negate = true; ++ if (*begin == '+') { ++ ++begin; ++ } else if (*begin == '-') { ++ negate = false; ++ ++begin; ++ } ++ ++ bool ok = false; ++ hour = qstrtoll(begin, &begin, 10, &ok); ++ if (!ok) ++ return INT_MIN; ++ if (begin < end && *begin == ':') { ++ // minutes ++ ++begin; ++ min = qstrtoll(begin, &begin, 10, &ok); ++ if (!ok || min < 0) ++ return INT_MIN; ++ ++ if (begin < end && *begin == ':') { ++ // seconds ++ ++begin; ++ sec = qstrtoll(begin, &begin, 10, &ok); ++ if (!ok || sec < 0) ++ return INT_MIN; ++ } ++ } ++ ++ // we must have consumed everything ++ if (begin != end) ++ return INT_MIN; ++ ++ int value = (hour * 60 + min) * 60 + sec; ++ return negate ? -value : value; ++} ++ ++static inline bool asciiIsLetter(char ch) ++{ ++ ch |= 0x20; // lowercases if it is a letter, otherwise just corrupts ch ++ return ch >= 'a' && ch <= 'z'; ++} ++ ++// Returns the zone name, the offset (in seconds) and advances \a begin to ++// where the parsing ended. Returns a zone of INT_MIN in case an offset ++// couldn't be read. ++static QPair parsePosixZoneNameAndOffset(const char *&pos, const char *end) ++{ ++ static const char offsetChars[] = "0123456789:"; ++ QPair result = qMakePair(QString(), INT_MIN); ++ ++ const char *nameBegin = pos; ++ const char *nameEnd; ++ Q_ASSERT(pos < end); ++ ++ if (*pos == '<') { ++ nameBegin = pos + 1; // skip the '<' ++ nameEnd = nameBegin; ++ while (nameEnd < end && *nameEnd != '>') { ++ // POSIX says only alphanumeric, but we allow anything ++ ++nameEnd; ++ } ++ pos = nameEnd + 1; // skip the '>' ++ } else { ++ nameBegin = pos; ++ nameEnd = nameBegin; ++ while (nameEnd < end && asciiIsLetter(*nameEnd)) ++ ++nameEnd; ++ pos = nameEnd; ++ } ++ if (nameEnd - nameBegin < 3) ++ return result; // name must be at least 3 characters long ++ ++ // zone offset, form [+-]hh:mm:ss ++ const char *zoneBegin = pos; ++ const char *zoneEnd = pos; ++ if (zoneEnd < end && (zoneEnd[0] == '+' || zoneEnd[0] == '-')) ++ ++zoneEnd; ++ while (zoneEnd < end) { ++ if (strchr(offsetChars, char(*zoneEnd)) == NULL) ++ break; ++ ++zoneEnd; ++ } ++ ++ result.first = QString::fromUtf8(nameBegin, nameEnd - nameBegin); ++ if (zoneEnd > zoneBegin) ++ result.second = parsePosixOffset(zoneBegin, zoneEnd); ++ pos = zoneEnd; ++ return result; + } + + static QVector calculatePosixTransitions(const QByteArray &posixRule, +@@ -419,51 +496,38 @@ static QVector calculatePosixTransitions(const QByteArra + + // POSIX Format is like "TZ=CST6CDT,M3.2.0/2:00:00,M11.1.0/2:00:00" + // i.e. "std offset dst [offset],start[/time],end[/time]" +- // See http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html ++ // See the section about TZ at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html + QList parts = posixRule.split(','); + +- QString name = QString::fromUtf8(parts.at(0)); +- QString stdName; +- QString stdOffsetString; +- QString dstName; +- QString dstOffsetString; +- bool parsedStdName = false; +- bool parsedStdOffset = false; +- for (int i = 0; i < name.size(); ++i) { +- if (name.at(i).isLetter()) { +- if (parsedStdName) { +- parsedStdOffset = true; +- dstName.append(name.at(i)); +- } else { +- stdName.append(name.at(i)); ++ QPair stdZone, dstZone; ++ { ++ const QByteArray &zoneinfo = parts.at(0); ++ const char *begin = zoneinfo.constBegin(); ++ ++ stdZone = parsePosixZoneNameAndOffset(begin, zoneinfo.constEnd()); ++ if (stdZone.second == INT_MIN) { ++ stdZone.second = 0; // reset to UTC if we failed to parse ++ } else if (begin < zoneinfo.constEnd()) { ++ dstZone = parsePosixZoneNameAndOffset(begin, zoneinfo.constEnd()); ++ if (dstZone.second == INT_MIN) { ++ // if the dst offset isn't provided, it is 1 hour ahead of the standard offset ++ dstZone.second = stdZone.second + (60 * 60); + } +- } else { +- parsedStdName = true; +- if (parsedStdOffset) +- dstOffsetString.append(name.at(i)); +- else +- stdOffsetString.append(name.at(i)); + } + } + +- int utcOffset = parsePosixOffset(stdOffsetString.toUtf8()); +- + // If only the name part then no transitions + if (parts.count() == 1) { + QTimeZonePrivate::Data data; + data.atMSecsSinceEpoch = lastTranMSecs; +- data.offsetFromUtc = utcOffset; +- data.standardTimeOffset = utcOffset; ++ data.offsetFromUtc = stdZone.second; ++ data.standardTimeOffset = stdZone.second; + data.daylightTimeOffset = 0; +- data.abbreviation = stdName; ++ data.abbreviation = stdZone.first; + result << data; + return result; + } + +- // If not populated the total dst offset is 1 hour +- int dstOffset = utcOffset + (60 * 60); +- if (!dstOffsetString.isEmpty()) +- dstOffset = parsePosixOffset(dstOffsetString.toUtf8()); + + // Get the std to dst transtion details + QList dstParts = parts.at(1).split('/'); +@@ -486,18 +550,18 @@ static QVector calculatePosixTransitions(const QByteArra + for (int year = startYear; year <= endYear; ++year) { + QTimeZonePrivate::Data dstData; + QDateTime dst(calculatePosixDate(dstDateRule, year), dstTime, Qt::UTC); +- dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - (utcOffset * 1000); +- dstData.offsetFromUtc = dstOffset; +- dstData.standardTimeOffset = utcOffset; +- dstData.daylightTimeOffset = dstOffset - utcOffset; +- dstData.abbreviation = dstName; ++ dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - (stdZone.second * 1000); ++ dstData.offsetFromUtc = dstZone.second; ++ dstData.standardTimeOffset = stdZone.second; ++ dstData.daylightTimeOffset = dstZone.second - stdZone.second; ++ dstData.abbreviation = dstZone.first; + QTimeZonePrivate::Data stdData; + QDateTime std(calculatePosixDate(stdDateRule, year), stdTime, Qt::UTC); +- stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - (dstOffset * 1000); +- stdData.offsetFromUtc = utcOffset; +- stdData.standardTimeOffset = utcOffset; ++ stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - (dstZone.second * 1000); ++ stdData.offsetFromUtc = stdZone.second; ++ stdData.standardTimeOffset = stdZone.second; + stdData.daylightTimeOffset = 0; +- stdData.abbreviation = stdName; ++ stdData.abbreviation = stdZone.first; + // Part of the high year will overflow + if (year == 292278994 && (dstData.atMSecsSinceEpoch < 0 || stdData.atMSecsSinceEpoch < 0)) { + if (dstData.atMSecsSinceEpoch > 0) { +diff --git a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp +index ea83510..ce72e7c 100644 +--- a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp ++++ b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp +@@ -847,6 +847,16 @@ void tst_QTimeZone::tzTest() + QTzTimeZonePrivate::Data datatz2 = tztz2.data(std); + QTzTimeZonePrivate::Data datautc2 = tzutc2.data(std); + QCOMPARE(datatz2.offsetFromUtc, datautc2.offsetFromUtc); ++ ++ // Test a timezone with a name that isn't all letters ++ QTzTimeZonePrivate tzBarnaul("Asia/Barnaul"); ++ if (tzBarnaul.isValid()) { ++ QCOMPARE(tzBarnaul.data(std).abbreviation, QString("+07")); ++ ++ // first full day of the new rule (tzdata2016b) ++ QDateTime dt(QDate(2016, 3, 28), QTime(0, 0, 0), Qt::UTC); ++ QCOMPARE(tzBarnaul.data(dt.toMSecsSinceEpoch()).abbreviation, QString("+07")); ++ } + #endif // Q_OS_UNIX + } + +-- +2.9.3 + diff -Nru qtbase-opensource-src-5.5.1+dfsg/debian/patches/global_menu_shortcuts.diff qtbase-opensource-src-5.5.1+dfsg/debian/patches/global_menu_shortcuts.diff --- qtbase-opensource-src-5.5.1+dfsg/debian/patches/global_menu_shortcuts.diff 1970-01-01 00:00:00.000000000 +0000 +++ qtbase-opensource-src-5.5.1+dfsg/debian/patches/global_menu_shortcuts.diff 2017-03-13 15:39:23.000000000 +0000 @@ -0,0 +1,55 @@ +Description: make shortcuts work for platform menu bars + When a platform menu bar is used, the QMenuBar is hidden, so shortcuts + for QActions attached only to it do not work. +Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=287f548d4c7cc594 +Bug: https://bugs.launchpad.net/bugs/1380702 +Last-Update: 2017-02-13 + +--- a/src/widgets/kernel/qshortcut.cpp ++++ b/src/widgets/kernel/qshortcut.cpp +@@ -135,9 +135,11 @@ + static bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidget *active_window) + { + bool visible = w->isVisible(); +-#ifdef Q_OS_MAC +- if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast(w)) +- visible = true; ++#ifndef QT_NO_MENUBAR ++ if (QMenuBar *menuBar = qobject_cast(w)) { ++ if (menuBar->isNativeMenuBar()) ++ visible = true; ++ } + #endif + + if (!visible || !w->isEnabled()) +--- a/src/widgets/widgets/qmenubar.cpp ++++ b/src/widgets/widgets/qmenubar.cpp +@@ -1281,10 +1281,12 @@ + } else if(e->type() == QEvent::ActionRemoved) { + e->action()->disconnect(this); + } +- if (isVisible()) { ++ // updateGeometries() is also needed for native menu bars because ++ // it updates shortcutIndexMap ++ if (isVisible() || isNativeMenuBar()) + d->updateGeometries(); ++ if (isVisible()) + update(); +- } + } + + /*! +@@ -1704,6 +1706,13 @@ + { + Q_Q(QMenuBar); + QAction *act = actions.at(id); ++ if (act && act->menu()) { ++ if (QPlatformMenu *platformMenu = act->menu()->platformMenu()) { ++ platformMenu->showPopup(q->windowHandle(), actionRects.at(id), Q_NULLPTR); ++ return; ++ } ++ } ++ + setCurrentAction(act, true, true); + if (act && !act->menu()) { + activateAction(act, QAction::Trigger); diff -Nru qtbase-opensource-src-5.5.1+dfsg/debian/patches/QtGui-Don-t-set-a-screen-to-a-child-window.patch qtbase-opensource-src-5.5.1+dfsg/debian/patches/QtGui-Don-t-set-a-screen-to-a-child-window.patch --- qtbase-opensource-src-5.5.1+dfsg/debian/patches/QtGui-Don-t-set-a-screen-to-a-child-window.patch 1970-01-01 00:00:00.000000000 +0000 +++ qtbase-opensource-src-5.5.1+dfsg/debian/patches/QtGui-Don-t-set-a-screen-to-a-child-window.patch 2016-05-02 12:37:39.000000000 +0000 @@ -0,0 +1,49 @@ +From f3114120f2d6f81f424ee542635c2711f66b516b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= +Date: Tue, 5 Jan 2016 00:58:50 +0100 +Subject: [PATCH] QtGui: Don't set a screen to a child window + +This is a partial revert of eaa3a9d0108cdf692f1686cafefb7b834f0e5af6 + +Task-number: QTBUG-50081 +Change-Id: Ic3dc4daa90d7a968a4ebf45d3029c99a12985686 +Reviewed-by: Shawn Rutledge +--- + src/gui/kernel/qwindow.cpp | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp +index 83e8777..21734f1 100644 +--- a/src/gui/kernel/qwindow.cpp ++++ b/src/gui/kernel/qwindow.cpp +@@ -609,18 +609,20 @@ void QWindow::setParent(QWindow *parent) + } + + QObject::setParent(parent); ++ d->parentWindow = parent; + +- QPlatformWindow *parentPlatformWindow = parent ? parent->d_func()->platformWindow : Q_NULLPTR; +- +- if (parentPlatformWindow) ++ if (parent) + d->disconnectFromScreen(); + else + d->connectToScreen(newScreen); + +- if (d->platformWindow) +- d->platformWindow->setParent(parentPlatformWindow); +- +- d->parentWindow = parent; ++ if (d->platformWindow) { ++ if (parent && parent->d_func()->platformWindow) { ++ d->platformWindow->setParent(parent->d_func()->platformWindow); ++ } else { ++ d->platformWindow->setParent(0); ++ } ++ } + + QGuiApplicationPrivate::updateBlockedStatus(this); + } +-- +2.7.4 + diff -Nru qtbase-opensource-src-5.5.1+dfsg/debian/patches/series qtbase-opensource-src-5.5.1+dfsg/debian/patches/series --- qtbase-opensource-src-5.5.1+dfsg/debian/patches/series 2016-04-12 16:18:20.000000000 +0000 +++ qtbase-opensource-src-5.5.1+dfsg/debian/patches/series 2017-05-03 19:18:27.000000000 +0000 @@ -31,6 +31,15 @@ dbustray_fixes.diff qdoc-Wrap-QML-read-only-and-default-qualifiers-in-br.patch detect-indicator-application.diff +Blacklist-Mali-T760-Mali-T720-from-supporting-BGRA.patch +Fix-crash-because-of-NULL-screen-in-QXcbWindow.patch +QtGui-Don-t-set-a-screen-to-a-child-window.patch +xcb-Fix-drag-and-drop-to-applications-like-Emacs-and.patch +xcb-Fix-drag-and-drop-to-Emacs.patch +Fix-parsing-of-tzfile-5-POSIX-rule-zone-names-with-b.patch +fix_isNativeMenuBar.diff +global_menu_shortcuts.diff +xcb-compress-mouse-motion-and-touch-update-events.patch # Debian specific. gnukfreebsd.diff diff -Nru qtbase-opensource-src-5.5.1+dfsg/debian/patches/xcb-compress-mouse-motion-and-touch-update-events.patch qtbase-opensource-src-5.5.1+dfsg/debian/patches/xcb-compress-mouse-motion-and-touch-update-events.patch --- qtbase-opensource-src-5.5.1+dfsg/debian/patches/xcb-compress-mouse-motion-and-touch-update-events.patch 1970-01-01 00:00:00.000000000 +0000 +++ qtbase-opensource-src-5.5.1+dfsg/debian/patches/xcb-compress-mouse-motion-and-touch-update-events.patch 2017-03-23 20:16:50.000000000 +0000 @@ -0,0 +1,449 @@ +Description: xcb: Compress mouse motion and touch update events + The current version of the mouse motion event compression algorithm + does not work with certain configurations — situations where we get + one XCB_GE_GENERIC event between every XCB_MOTION_NOTIFY event. + . + The new implementation tries to be less fragile. The previous approach + checked “is *the next* event the same type as the current event”, the + new check asks “have we buffered more events of the same type as the + current event”. We buffer events of the same type only when the main + thread is unresponsive. + . + This patch adds event compression for XI_TouchUpdate in addition to + the fix for motion even compression. +Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=7edd10e6cc215c41 +Bug: https://bugs.launchpad.net/bugs/1598173 +Last-Update: 2017-03-23 + +--- a/src/plugins/platforms/xcb/qxcbconnection.cpp ++++ b/src/plugins/platforms/xcb/qxcbconnection.cpp +@@ -107,6 +107,24 @@ + #define XCB_GE_GENERIC 35 + #endif + ++// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed: ++// - "pad0" became "extension" ++// - "pad1" and "pad" became "pad0" ++// New and old version of this struct share the following fields: ++typedef struct qt_xcb_ge_event_t { ++ uint8_t response_type; ++ uint8_t extension; ++ uint16_t sequence; ++ uint32_t length; ++ uint16_t event_type; ++} qt_xcb_ge_event_t; ++ ++static inline bool isXIEvent(xcb_generic_event_t *event, int opCode) ++{ ++ qt_xcb_ge_event_t *e = (qt_xcb_ge_event_t *)event; ++ return e->extension == opCode; ++} ++ + #ifdef XCB_USE_XLIB + static const char * const xcbConnectionErrors[] = { + "No error", /* Error 0 */ +@@ -1139,7 +1157,7 @@ + #if defined(XCB_USE_XINPUT2) + case XCB_GE_GENERIC: + // Here the windowEventListener is invoked from xi2HandleEvent() +- if (m_xi2Enabled) ++ if (m_xi2Enabled && isXIEvent(event, m_xiOpCode)) + xi2HandleEvent(reinterpret_cast(event)); + break; + #endif +@@ -1467,6 +1485,105 @@ + + #endif + ++#if defined(XCB_USE_XINPUT2) ++// it is safe to cast XI_* events here as long as we are only touching the first 32 bytes, ++// after that position event needs memmove, see xi2PrepareXIGenericDeviceEvent ++static inline bool isXIType(xcb_generic_event_t *event, int opCode, uint16_t type) ++{ ++ if (!isXIEvent(event, opCode)) ++ return false; ++ ++ xXIGenericDeviceEvent *xiEvent = reinterpret_cast(event); ++ return xiEvent->evtype == type; ++} ++#endif ++static inline bool isValid(xcb_generic_event_t *event) ++{ ++ return event && (event->response_type & ~0x80); ++} ++ ++/*! \internal ++ ++ Compresses events of the same type to avoid swamping the event queue. ++ If event compression is not desired there are several options what developers can do: ++ ++ 1) Write responsive applications. We drop events that have been buffered in the event ++ queue while waiting on unresponsive GUI thread. ++ 2) Use QAbstractNativeEventFilter to get all events from X connection. This is not optimal ++ because it requires working with native event types. ++ 3) Or add public API to Qt for disabling event compression QTBUG-44964 ++ ++*/ ++bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const ++{ ++ uint responseType = event->response_type & ~0x80; ++ int nextIndex = currentIndex + 1; ++ ++ if (responseType == XCB_MOTION_NOTIFY) { ++ // compress XCB_MOTION_NOTIFY notify events ++ for (int j = nextIndex; j < eventqueue->size(); ++j) { ++ xcb_generic_event_t *next = eventqueue->at(j); ++ if (!isValid(next)) ++ continue; ++ if (next->response_type == XCB_MOTION_NOTIFY) ++ return true; ++ } ++ return false; ++ } ++#if defined(XCB_USE_XINPUT2) ++ // compress XI_* events ++ if (responseType == XCB_GE_GENERIC) { ++ if (!m_xi2Enabled) ++ return false; ++ ++ // compress XI_Motion ++ if (isXIType(event, m_xiOpCode, XI_Motion)) { ++ for (int j = nextIndex; j < eventqueue->size(); ++j) { ++ xcb_generic_event_t *next = eventqueue->at(j); ++ if (!isValid(next)) ++ continue; ++ if (isXIType(next, m_xiOpCode, XI_Motion)) ++ return true; ++ } ++ return false; ++ } ++#ifdef XCB_USE_XINPUT22 ++ // compress XI_TouchUpdate for the same touch point id ++ if (isXIType(event, m_xiOpCode, XI_TouchUpdate)) { ++ xXIDeviceEvent *xiDeviceEvent = reinterpret_cast(event); ++ uint32_t id = xiDeviceEvent->detail % INT_MAX; ++ for (int j = nextIndex; j < eventqueue->size(); ++j) { ++ xcb_generic_event_t *next = eventqueue->at(j); ++ if (!isValid(next)) ++ continue; ++ if (isXIType(next, m_xiOpCode, XI_TouchUpdate)) { ++ xXIDeviceEvent *xiDeviceNextEvent = reinterpret_cast(next); ++ if (id == xiDeviceNextEvent->detail % INT_MAX) ++ return true; ++ } ++ } ++ return false; ++ } ++#endif ++ return false; ++ } ++#endif ++ if (responseType == XCB_CONFIGURE_NOTIFY) { ++ // compress multiple configure notify events for the same window ++ for (int j = nextIndex; j < eventqueue->size(); ++j) { ++ xcb_generic_event_t *next = eventqueue->at(j); ++ if (isValid(next) && next->response_type == XCB_CONFIGURE_NOTIFY ++ && ((xcb_configure_notify_event_t *)next)->event == ((xcb_configure_notify_event_t*)event)->event) ++ { ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ return false; ++} ++ + void QXcbConnection::processXcbEvents() + { + int connection_error = xcb_connection_has_error(xcb_connection()); +@@ -1477,61 +1594,39 @@ + + QXcbEventArray *eventqueue = m_reader->lock(); + +- for(int i = 0; i < eventqueue->size(); ++i) { ++ for (int i = 0; i < eventqueue->size(); ++i) { + xcb_generic_event_t *event = eventqueue->at(i); + if (!event) + continue; + QScopedPointer eventGuard(event); + (*eventqueue)[i] = 0; + +- uint response_type = event->response_type & ~0x80; +- +- if (!response_type) { ++ if (!(event->response_type & ~0x80)) { + handleXcbError((xcb_generic_error_t *)event); +- } else { +- if (response_type == XCB_MOTION_NOTIFY) { +- // compress multiple motion notify events in a row +- // to avoid swamping the event queue +- xcb_generic_event_t *next = eventqueue->value(i+1, 0); +- if (next && (next->response_type & ~0x80) == XCB_MOTION_NOTIFY) +- continue; +- } ++ continue; ++ } + +- if (response_type == XCB_CONFIGURE_NOTIFY) { +- // compress multiple configure notify events for the same window +- bool found = false; +- for (int j = i; j < eventqueue->size(); ++j) { +- xcb_generic_event_t *other = eventqueue->at(j); +- if (other && (other->response_type & ~0x80) == XCB_CONFIGURE_NOTIFY +- && ((xcb_configure_notify_event_t *)other)->event == ((xcb_configure_notify_event_t *)event)->event) +- { +- found = true; +- break; +- } +- } +- if (found) +- continue; +- } ++ if (compressEvent(event, i, eventqueue)) ++ continue; + +- bool accepted = false; +- if (clipboard()->processIncr()) +- clipboard()->incrTransactionPeeker(event, accepted); +- if (accepted) +- continue; ++ bool accepted = false; ++ if (clipboard()->processIncr()) ++ clipboard()->incrTransactionPeeker(event, accepted); ++ if (accepted) ++ continue; + +- QVector::iterator it = m_peekFuncs.begin(); +- while (it != m_peekFuncs.end()) { +- // These callbacks return true if the event is what they were +- // waiting for, remove them from the list in that case. +- if ((*it)(this, event)) +- it = m_peekFuncs.erase(it); +- else +- ++it; +- } +- m_reader->unlock(); +- handleXcbEvent(event); +- m_reader->lock(); ++ QVector::iterator it = m_peekFuncs.begin(); ++ while (it != m_peekFuncs.end()) { ++ // These callbacks return true if the event is what they were ++ // waiting for, remove them from the list in that case. ++ if ((*it)(this, event)) ++ it = m_peekFuncs.erase(it); ++ else ++ ++it; + } ++ m_reader->unlock(); ++ handleXcbEvent(event); ++ m_reader->lock(); + } + + eventqueue->clear(); +@@ -2073,34 +2168,13 @@ + return true; + } + +-// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed: +-// - "pad0" became "extension" +-// - "pad1" and "pad" became "pad0" +-// New and old version of this struct share the following fields: +-// NOTE: API might change again in the next release of xcb in which case this comment will +-// need to be updated to reflect the reality. +-typedef struct qt_xcb_ge_event_t { +- uint8_t response_type; +- uint8_t extension; +- uint16_t sequence; +- uint32_t length; +- uint16_t event_type; +-} qt_xcb_ge_event_t; +- +-bool QXcbConnection::xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *ev, int opCode) ++void QXcbConnection::xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event) + { +- qt_xcb_ge_event_t *event = (qt_xcb_ge_event_t *)ev; +- // xGenericEvent has "extension" on the second byte, the same is true for xcb_ge_event_t starting from +- // the xcb version 1.9.3, prior to that it was called "pad0". +- if (event->extension == opCode) { +- // xcb event structs contain stuff that wasn't on the wire, the full_sequence field +- // adds an extra 4 bytes and generic events cookie data is on the wire right after the standard 32 bytes. +- // Move this data back to have the same layout in memory as it was on the wire +- // and allow casting, overwriting the full_sequence field. +- memmove((char*) event + 32, (char*) event + 36, event->length * 4); +- return true; +- } +- return false; ++ // xcb event structs contain stuff that wasn't on the wire, the full_sequence field ++ // adds an extra 4 bytes and generic events cookie data is on the wire right after the standard 32 bytes. ++ // Move this data back to have the same layout in memory as it was on the wire ++ // and allow casting, overwriting the full_sequence field. ++ memmove((char*) event + 32, (char*) event + 36, event->length * 4); + } + #endif // defined(XCB_USE_XINPUT2) + +--- a/src/plugins/platforms/xcb/qxcbconnection.h ++++ b/src/plugins/platforms/xcb/qxcbconnection.h +@@ -517,6 +517,7 @@ + QXcbScreen* findScreenForOutput(xcb_window_t rootWindow, xcb_randr_output_t output); + QXcbVirtualDesktop* virtualDesktopForRootWindow(xcb_window_t rootWindow); + void updateScreens(const xcb_randr_notify_event_t *event); ++ bool compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const; + bool checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output); + void updateScreen(QXcbScreen *screen, const xcb_randr_output_change_t &outputChange); + QXcbScreen *createScreen(QXcbVirtualDesktop *virtualDesktop, +@@ -576,7 +577,7 @@ + QHash m_scrollingDevices; + + static bool xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value); +- static bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int opCode); ++ static void xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event); + #endif + + xcb_connection_t *m_connection; +--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp ++++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +@@ -459,82 +459,81 @@ + + void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) + { +- if (xi2PrepareXIGenericDeviceEvent(event, m_xiOpCode)) { +- xXIGenericDeviceEvent *xiEvent = reinterpret_cast(event); +- int sourceDeviceId = xiEvent->deviceid; // may be the master id +- xXIDeviceEvent *xiDeviceEvent = 0; +- QXcbWindowEventListener *eventListener = 0; +- +- switch (xiEvent->evtype) { +- case XI_ButtonPress: +- case XI_ButtonRelease: +- case XI_Motion: ++ xi2PrepareXIGenericDeviceEvent(event); ++ xXIGenericDeviceEvent *xiEvent = reinterpret_cast(event); ++ int sourceDeviceId = xiEvent->deviceid; // may be the master id ++ xXIDeviceEvent *xiDeviceEvent = 0; ++ QXcbWindowEventListener *eventListener = 0; ++ ++ switch (xiEvent->evtype) { ++ case XI_ButtonPress: ++ case XI_ButtonRelease: ++ case XI_Motion: + #ifdef XCB_USE_XINPUT22 +- case XI_TouchBegin: +- case XI_TouchUpdate: +- case XI_TouchEnd: ++ case XI_TouchBegin: ++ case XI_TouchUpdate: ++ case XI_TouchEnd: + #endif +- { +- xiDeviceEvent = reinterpret_cast(event); +- eventListener = windowEventListenerFromId(xiDeviceEvent->event); +- if (eventListener) { +- long result = 0; +- if (eventListener->handleGenericEvent(reinterpret_cast(event), &result)) +- return; +- } +- sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master +- break; +- } +- case XI_HierarchyChanged: +- xi2HandleHierachyEvent(xiEvent); +- return; +- case XI_DeviceChanged: +- xi2HandleDeviceChangedEvent(xiEvent); +- return; +- default: +- break; ++ { ++ xiDeviceEvent = reinterpret_cast(event); ++ eventListener = windowEventListenerFromId(xiDeviceEvent->event); ++ if (eventListener) { ++ long result = 0; ++ if (eventListener->handleGenericEvent(reinterpret_cast(event), &result)) ++ return; + } ++ sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master ++ break; ++ } ++ case XI_HierarchyChanged: ++ xi2HandleHierachyEvent(xiEvent); ++ return; ++ case XI_DeviceChanged: ++ xi2HandleDeviceChangedEvent(xiEvent); ++ return; ++ default: ++ break; ++ } + + #ifndef QT_NO_TABLETEVENT +- for (int i = 0; i < m_tabletData.count(); ++i) { +- if (m_tabletData.at(i).deviceId == sourceDeviceId) { +- if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener)) +- return; +- } ++ for (int i = 0; i < m_tabletData.count(); ++i) { ++ if (m_tabletData.at(i).deviceId == sourceDeviceId) { ++ if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener)) ++ return; + } ++ } + #endif // QT_NO_TABLETEVENT + + #ifdef XCB_USE_XINPUT21 +- QHash::iterator device = m_scrollingDevices.find(sourceDeviceId); +- if (device != m_scrollingDevices.end()) +- xi2HandleScrollEvent(xiEvent, device.value()); ++ QHash::iterator device = m_scrollingDevices.find(sourceDeviceId); ++ if (device != m_scrollingDevices.end()) ++ xi2HandleScrollEvent(xiEvent, device.value()); + #endif // XCB_USE_XINPUT21 + + #ifdef XCB_USE_XINPUT22 +- if (xiDeviceEvent) { +- switch (xiDeviceEvent->evtype) { +- case XI_ButtonPress: +- case XI_ButtonRelease: +- case XI_Motion: +- if (xi2MouseEvents() && eventListener && !(xiDeviceEvent->flags & XIPointerEmulated)) +- eventListener->handleXIMouseEvent(event); +- break; +- +- case XI_TouchBegin: +- case XI_TouchUpdate: +- case XI_TouchEnd: +- if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) +- qCDebug(lcQpaXInput, "XI2 touch event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f on window %x", +- event->event_type, xiDeviceEvent->sequenceNumber, xiDeviceEvent->detail, +- fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y), +- fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y),xiDeviceEvent->event); +- if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) +- xi2ProcessTouch(xiDeviceEvent, platformWindow); +- break; +- } ++ if (xiDeviceEvent) { ++ switch (xiDeviceEvent->evtype) { ++ case XI_ButtonPress: ++ case XI_ButtonRelease: ++ case XI_Motion: ++ if (xi2MouseEvents() && eventListener && !(xiDeviceEvent->flags & XIPointerEmulated)) ++ eventListener->handleXIMouseEvent(event); ++ break; ++ ++ case XI_TouchBegin: ++ case XI_TouchUpdate: ++ case XI_TouchEnd: ++ if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) ++ qCDebug(lcQpaXInput, "XI2 touch event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f on window %x", ++ event->event_type, xiDeviceEvent->sequenceNumber, xiDeviceEvent->detail, ++ fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y), ++ fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y),xiDeviceEvent->event); ++ if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) ++ xi2ProcessTouch(xiDeviceEvent, platformWindow); ++ break; + } +-#endif // XCB_USE_XINPUT22 + } ++#endif // XCB_USE_XINPUT22 + } + + #ifdef XCB_USE_XINPUT22 diff -Nru qtbase-opensource-src-5.5.1+dfsg/debian/patches/xcb-Fix-drag-and-drop-to-applications-like-Emacs-and.patch qtbase-opensource-src-5.5.1+dfsg/debian/patches/xcb-Fix-drag-and-drop-to-applications-like-Emacs-and.patch --- qtbase-opensource-src-5.5.1+dfsg/debian/patches/xcb-Fix-drag-and-drop-to-applications-like-Emacs-and.patch 1970-01-01 00:00:00.000000000 +0000 +++ qtbase-opensource-src-5.5.1+dfsg/debian/patches/xcb-Fix-drag-and-drop-to-applications-like-Emacs-and.patch 2016-05-02 12:37:39.000000000 +0000 @@ -0,0 +1,98 @@ +From 269fdbdd2bedda5f5eacb751224d3a3fc3eed5bc Mon Sep 17 00:00:00 2001 +From: Urs Fleisch +Date: Fri, 26 Feb 2016 17:46:09 +0100 +Subject: [PATCH] xcb: Fix drag and drop to applications like Emacs and + Chromium. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Drops without matching time stamp do not work. I have fixed the issue by +reanimating the findXdndAwareParent() function (adapted to XCB) and +using it to find a matching transaction if all else fails. + +Task-number: QTBUG-45812 +Change-Id: Ibca15bbab02ccf2f25280418e9edf36972ebf9a0 +Reviewed-by: Błażej Szczygieł +Reviewed-by: Dmitry Shachnev +Reviewed-by: Shawn Rutledge +--- + src/plugins/platforms/xcb/qxcbdrag.cpp | 55 +++++++++++++++++++++++++++------- + 1 file changed, 44 insertions(+), 11 deletions(-) + +diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp +index f5cc873..f1428d0 100644 +--- a/src/plugins/platforms/xcb/qxcbdrag.cpp ++++ b/src/plugins/platforms/xcb/qxcbdrag.cpp +@@ -1072,6 +1072,40 @@ void QXcbDrag::cancel() + send_leave(); + } + ++// find an ancestor with XdndAware on it ++static xcb_window_t findXdndAwareParent(QXcbConnection *c, xcb_window_t window) ++{ ++ xcb_window_t target = 0; ++ forever { ++ // check if window has XdndAware ++ xcb_get_property_cookie_t gpCookie = Q_XCB_CALL( ++ xcb_get_property(c->xcb_connection(), false, window, ++ c->atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0)); ++ xcb_get_property_reply_t *gpReply = xcb_get_property_reply( ++ c->xcb_connection(), gpCookie, 0); ++ bool aware = gpReply && gpReply->type != XCB_NONE; ++ free(gpReply); ++ if (aware) { ++ target = window; ++ break; ++ } ++ ++ // try window's parent ++ xcb_query_tree_cookie_t qtCookie = Q_XCB_CALL( ++ xcb_query_tree_unchecked(c->xcb_connection(), window)); ++ xcb_query_tree_reply_t *qtReply = xcb_query_tree_reply( ++ c->xcb_connection(), qtCookie, NULL); ++ if (!qtReply) ++ break; ++ xcb_window_t root = qtReply->root; ++ xcb_window_t parent = qtReply->parent; ++ free(qtReply); ++ if (window == root) ++ break; ++ window = parent; ++ } ++ return target; ++} + + void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event) + { +@@ -1099,17 +1133,16 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event + // xcb_convert_selection() that we sent the XdndDrop event to. + at = findTransactionByWindow(event->requestor); + } +-// if (at == -1 && event->time == XCB_CURRENT_TIME) { +-// // previous Qt versions always requested the data on a child of the target window +-// // using CurrentTime... but it could be asking for either drop data or the current drag's data +-// Window target = findXdndAwareParent(event->requestor); +-// if (target) { +-// if (current_target && current_target == target) +-// at = -2; +-// else +-// at = findXdndDropTransactionByWindow(target); +-// } +-// } ++ ++ if (at == -1 && event->time == XCB_CURRENT_TIME) { ++ xcb_window_t target = findXdndAwareParent(connection(), event->requestor); ++ if (target) { ++ if (current_target == target) ++ at = -2; ++ else ++ at = findTransactionByWindow(target); ++ } ++ } + } + + QDrag *transactionDrag = 0; +-- +2.7.4 + diff -Nru qtbase-opensource-src-5.5.1+dfsg/debian/patches/xcb-Fix-drag-and-drop-to-Emacs.patch qtbase-opensource-src-5.5.1+dfsg/debian/patches/xcb-Fix-drag-and-drop-to-Emacs.patch --- qtbase-opensource-src-5.5.1+dfsg/debian/patches/xcb-Fix-drag-and-drop-to-Emacs.patch 1970-01-01 00:00:00.000000000 +0000 +++ qtbase-opensource-src-5.5.1+dfsg/debian/patches/xcb-Fix-drag-and-drop-to-Emacs.patch 2016-05-02 12:37:39.000000000 +0000 @@ -0,0 +1,35 @@ +From 427a0fc9bc3481626da250efe5229186ab8847d4 Mon Sep 17 00:00:00 2001 +From: Urs Fleisch +Date: Sun, 1 May 2016 14:31:48 +0200 +Subject: [PATCH] xcb: Fix drag and drop to Emacs. + +Unfortunately, the improved patch for QTBUG-45812 fixed things for +Chromium, but did no longer work for Emacs. This fixes commit [269fdb] +to make it work for both Emacs and Chromium. + +Task-number: QTBUG-45812 +Change-Id: I2fca708503f27679681bc6959de1ad94943a063e +--- + src/plugins/platforms/xcb/qxcbdrag.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp +index f1428d0..529f91e 100644 +--- a/src/plugins/platforms/xcb/qxcbdrag.cpp ++++ b/src/plugins/platforms/xcb/qxcbdrag.cpp +@@ -1134,10 +1134,10 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event + at = findTransactionByWindow(event->requestor); + } + +- if (at == -1 && event->time == XCB_CURRENT_TIME) { ++ if (at == -1) { + xcb_window_t target = findXdndAwareParent(connection(), event->requestor); + if (target) { +- if (current_target == target) ++ if (event->time == XCB_CURRENT_TIME && current_target == target) + at = -2; + else + at = findTransactionByWindow(target); +-- +2.7.4 +