diff --git a/.gitignore b/.gitignore index 73b7e05..c1946d7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /qtbase-opensource-src-5.4.0.tar.xz /qtbase-opensource-src-5.4.1.tar.xz +/qtbase-opensource-src-5.4.2.tar.xz diff --git a/0004-Fix-QPrinter-setPaperSize-regression-when-using-QPri.patch b/0004-Fix-QPrinter-setPaperSize-regression-when-using-QPri.patch deleted file mode 100644 index 3b505c0..0000000 --- a/0004-Fix-QPrinter-setPaperSize-regression-when-using-QPri.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 7fc8c560e21e7175b1fe33c988f3f30e4b326efe Mon Sep 17 00:00:00 2001 -From: David Faure -Date: Mon, 29 Dec 2014 16:37:55 +0100 -Subject: [PATCH 004/248] Fix QPrinter::setPaperSize regression when using - QPrinter::DevicePixel - -The QPageSize-based refactoring led to casting DevicePixel to a QPageSize::Unit -value of 6 (out of bounds). And then the switch in qt_nameForCustomSize -would leave the string empty, leading to "QString::arg: Argument missing: , 672" -warnings. - -Change-Id: I85e97174cc8ead9beccaaa3ded6edfad80f8e360 -Reviewed-by: Friedemann Kleint -Reviewed-by: Andy Shaw ---- - src/printsupport/kernel/qprinter.cpp | 5 ++++- - tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp | 12 +++++++++++- - 2 files changed, 15 insertions(+), 2 deletions(-) - -diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp -index 437a68e..8ed2732 100644 ---- a/src/printsupport/kernel/qprinter.cpp -+++ b/src/printsupport/kernel/qprinter.cpp -@@ -1224,7 +1224,10 @@ void QPrinter::setPageSize(PageSize newPageSize) - - void QPrinter::setPaperSize(const QSizeF &paperSize, QPrinter::Unit unit) - { -- setPageSize(QPageSize(paperSize, QPageSize::Unit(unit))); -+ if (unit == QPrinter::DevicePixel) -+ setPageSize(QPageSize(paperSize * qt_pixelMultiplier(resolution()), QPageSize::Point)); -+ else -+ setPageSize(QPageSize(paperSize, QPageSize::Unit(unit))); - } - - /*! -diff --git a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp -index 78aa0af..62bd982 100644 ---- a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp -+++ b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp -@@ -526,7 +526,7 @@ void tst_QPrinter::testCustomPageSizes() - { - QPrinter p; - -- QSizeF customSize(8.5, 11.0); -+ QSizeF customSize(7.0, 11.0); - p.setPaperSize(customSize, QPrinter::Inch); - - QSizeF paperSize = p.paperSize(QPrinter::Inch); -@@ -538,6 +538,16 @@ void tst_QPrinter::testCustomPageSizes() - paperSize = p.paperSize(QPrinter::Inch); - QCOMPARE(paperSize.width(), customSize.width()); - QCOMPARE(paperSize.height(), customSize.height()); -+ -+ const QSizeF sizeInPixels = p.paperSize(QPrinter::DevicePixel); -+ QPrinter p3; -+ p3.setPaperSize(sizeInPixels, QPrinter::DevicePixel); -+ paperSize = p3.paperSize(QPrinter::Inch); -+ QCOMPARE(paperSize.width(), customSize.width()); -+ QCOMPARE(paperSize.height(), customSize.height()); -+ QPageSize pageSize = p3.pageLayout().pageSize(); -+ QCOMPARE(pageSize.key(), QString("Custom.504x792")); -+ QCOMPARE(pageSize.name(), QString("Custom (504pt x 792pt)")); - } - - void tst_QPrinter::customPaperSizeAndMargins_data() --- -2.3.7 - diff --git a/0012-Fix-a-crash-in-QPlainTextEdit-documentChanged.patch b/0012-Fix-a-crash-in-QPlainTextEdit-documentChanged.patch deleted file mode 100644 index bd6c3a8..0000000 --- a/0012-Fix-a-crash-in-QPlainTextEdit-documentChanged.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 890ae41d0601d20505df2f955a99d0238bf4f59e Mon Sep 17 00:00:00 2001 -From: Pierre Rossi -Date: Wed, 7 Jan 2015 16:16:23 +0100 -Subject: [PATCH 012/223] Fix a crash in QPlainTextEdit::documentChanged - -The layout for an invalid block is very likely to be null, it -shouldn't be accessed without checking the block's validity first. -We can make the check a bit more conservative and simply check that -the block isn't empty. - -Change-Id: Ic1459a6168b1b8ce36e9c6d019dc28653676efbe -Task-number: QTBUG-43562 -Reviewed-by: Simon Hausmann ---- - src/widgets/widgets/qplaintextedit.cpp | 3 +- - .../widgets/qplaintextedit/tst_qplaintextedit.cpp | 33 ++++++++++++++++++++++ - 2 files changed, 34 insertions(+), 2 deletions(-) - -diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp -index 72a556d..e56fd11 100644 ---- a/src/widgets/widgets/qplaintextedit.cpp -+++ b/src/widgets/widgets/qplaintextedit.cpp -@@ -288,8 +288,7 @@ void QPlainTextDocumentLayout::documentChanged(int from, int charsRemoved, int c - - if (changeStartBlock == changeEndBlock && newBlockCount == d->blockCount) { - QTextBlock block = changeStartBlock; -- int blockLineCount = block.layout()->lineCount(); -- if (block.isValid() && blockLineCount) { -+ if (block.isValid() && block.length()) { - QRectF oldBr = blockBoundingRect(block); - layoutBlock(block); - QRectF newBr = blockBoundingRect(block); -diff --git a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp -index d8e7fb7..cf495e2 100644 ---- a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp -+++ b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp -@@ -148,6 +148,7 @@ private slots: - #endif - void layoutAfterMultiLineRemove(); - void undoCommandRemovesAndReinsertsBlock(); -+ void taskQTBUG_43562_lineCountCrash(); - - private: - void createSelection(); -@@ -1629,5 +1630,37 @@ void tst_QPlainTextEdit::undoCommandRemovesAndReinsertsBlock() - - } - -+class ContentsChangedFunctor { -+public: -+ ContentsChangedFunctor(QPlainTextEdit *t) : textEdit(t) {} -+ void operator()(int, int, int) -+ { -+ QTextCursor c(textEdit->textCursor()); -+ c.beginEditBlock(); -+ c.movePosition(QTextCursor::Start); -+ c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); -+ c.setCharFormat(QTextCharFormat()); -+ c.endEditBlock(); -+ } -+ -+private: -+ QPlainTextEdit *textEdit; -+}; -+ -+void tst_QPlainTextEdit::taskQTBUG_43562_lineCountCrash() -+{ -+ connect(ed->document(), &QTextDocument::contentsChange, ContentsChangedFunctor(ed)); -+ // Don't crash -+ QTest::keyClicks(ed, "Some text"); -+ QTest::keyClick(ed, Qt::Key_Left); -+ QTest::keyClick(ed, Qt::Key_Right); -+ QTest::keyClick(ed, Qt::Key_A); -+ QTest::keyClick(ed, Qt::Key_Left); -+ QTest::keyClick(ed, Qt::Key_Right); -+ QTest::keyClick(ed, Qt::Key_Space); -+ QTest::keyClicks(ed, "nd some more"); -+ disconnect(ed->document(), SIGNAL(contentsChange(int, int, int)), 0, 0); -+} -+ - QTEST_MAIN(tst_QPlainTextEdit) - #include "tst_qplaintextedit.moc" --- -1.9.3 - diff --git a/0072-CMake-Fix-QObject-connect-failing-on-ARM.patch b/0072-CMake-Fix-QObject-connect-failing-on-ARM.patch deleted file mode 100644 index 4bec1e6..0000000 --- a/0072-CMake-Fix-QObject-connect-failing-on-ARM.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 9718cb330cb479ec6e91f1f10c5ee9097fa2f4fb Mon Sep 17 00:00:00 2001 -From: Albert Astals Cid -Date: Thu, 29 Jan 2015 12:13:53 +0100 -Subject: [PATCH 072/163] CMake: Fix QObject::connect failing on ARM - -We need PIE, doesn't matter if reduce_relocations is used or not - -Change-Id: I9a359b9d4443a6059980cd4c48058132ec4267fe -Reviewed-by: Simon Hausmann -Reviewed-by: Olivier Goffart (Woboq GmbH) ---- - mkspecs/features/create_cmake.prf | 2 -- - src/corelib/Qt5CoreConfigExtras.cmake.in | 2 -- - 2 files changed, 4 deletions(-) - -diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf -index 3b0e037..9f7ba46 100644 ---- a/mkspecs/features/create_cmake.prf -+++ b/mkspecs/features/create_cmake.prf -@@ -171,8 +171,6 @@ contains(CONFIG, plugin) { - return() - } - --unix:contains(QT_CONFIG, reduce_relocations):CMAKE_ADD_FPIE_FLAGS = "true" -- - CMAKE_MKSPEC = $$[QMAKE_XSPEC] - - CMAKE_MODULE_DEPS = $$cmakeModuleList($$sort_depends(QT.$${MODULE}.depends, QT.)) -diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in -index 9bda70e..4387bed 100644 ---- a/src/corelib/Qt5CoreConfigExtras.cmake.in -+++ b/src/corelib/Qt5CoreConfigExtras.cmake.in -@@ -66,14 +66,12 @@ list(APPEND Qt5Core_INCLUDE_DIRS ${_qt5_corelib_extra_includes}) - set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${_qt5_corelib_extra_includes}) - set(_qt5_corelib_extra_includes) - --!!IF !isEmpty(CMAKE_ADD_FPIE_FLAGS) - # Targets using Qt need to use the POSITION_INDEPENDENT_CODE property. The - # Qt5_POSITION_INDEPENDENT_CODE variable is used in the # qt5_use_module - # macro to add it. - set(Qt5_POSITION_INDEPENDENT_CODE True) - set_property(TARGET Qt5::Core PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") - set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIE\") --!!ENDIF - - !!IF !isEmpty(QT_NAMESPACE) - list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) --- -1.9.3 - diff --git a/0094-Fix-Meta-.-shortcuts-on-XCB.patch b/0094-Fix-Meta-.-shortcuts-on-XCB.patch deleted file mode 100644 index 2d43868..0000000 --- a/0094-Fix-Meta-.-shortcuts-on-XCB.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0d990b9ca117514fe83f53b39f25d6272304f2fb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?K=C3=A5re=20S=C3=A4rs?= -Date: Thu, 22 Jan 2015 22:40:37 +0200 -Subject: [PATCH 094/163] Fix Meta+... shortcuts on XCB - -If the window contains a widget that accepts text input, a Meta+... -shortcut will be interpreted as if no modifier was pressed. This fix -enables the usage of Meta+... shortcuts for the XCB platform plugin. - -Change-Id: I80034b7e6bbbf18471c86fc77320d5038f5740be -Task-number: QTBUG-43572 -Reviewed-by: Aleix Pol Gonzalez -Reviewed-by: Milian Wolff -Reviewed-by: David Edmundson -Reviewed-by: Lars Knoll ---- - src/plugins/platforms/xcb/qxcbkeyboard.cpp | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp -index 5fb7457..85fef39 100644 ---- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp -+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp -@@ -933,7 +933,7 @@ xkb_keysym_t QXcbKeyboard::lookupLatinKeysym(xkb_keycode_t keycode) const - QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const - { - // turn off the modifier bits which doesn't participate in shortcuts -- Qt::KeyboardModifiers notNeeded = Qt::MetaModifier | Qt::KeypadModifier | Qt::GroupSwitchModifier; -+ Qt::KeyboardModifiers notNeeded = Qt::KeypadModifier | Qt::GroupSwitchModifier; - Qt::KeyboardModifiers modifiers = event->modifiers() &= ~notNeeded; - // create a fresh kb state and test against the relevant modifier combinations - struct xkb_state *kb_state = xkb_state_new(xkb_keymap); -@@ -963,10 +963,12 @@ QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const - xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(xkb_keymap, "Shift"); - xkb_mod_index_t altMod = xkb_keymap_mod_get_index(xkb_keymap, "Alt"); - xkb_mod_index_t controlMod = xkb_keymap_mod_get_index(xkb_keymap, "Control"); -+ xkb_mod_index_t metaMod = xkb_keymap_mod_get_index(xkb_keymap, "Meta"); - - Q_ASSERT(shiftMod < 32); - Q_ASSERT(altMod < 32); - Q_ASSERT(controlMod < 32); -+ Q_ASSERT(metaMod < 32); - - xkb_mod_mask_t depressed; - int qtKey = 0; -@@ -987,6 +989,8 @@ QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const - depressed |= (1 << shiftMod); - if (neededMods & Qt::ControlModifier) - depressed |= (1 << controlMod); -+ if (neededMods & Qt::MetaModifier) -+ depressed |= (1 << metaMod); - xkb_state_update_mask(kb_state, depressed, latchedMods, lockedMods, 0, 0, lockedLayout); - sym = xkb_state_key_get_one_sym(kb_state, keycode); - } --- -1.9.3 - diff --git a/0132-Call-ofono-nm-Registered-delayed-in-constructor-othe.patch b/0132-Call-ofono-nm-Registered-delayed-in-constructor-othe.patch deleted file mode 100644 index 53f49f8..0000000 --- a/0132-Call-ofono-nm-Registered-delayed-in-constructor-othe.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 8d6341a721d07e3cc30032bcc89f7e25cb00b9eb Mon Sep 17 00:00:00 2001 -From: Albert Astals Cid -Date: Mon, 16 Feb 2015 22:53:02 +0100 -Subject: [PATCH 132/163] Call [ofono|nm]Registered delayed in constructor - otherwise signals will be lost - -If we call them just in the constructor all the signals they sent -out can't be connected and will be lost, particularly this means -the QNetworkConfigurationManager doesn't see my ethernet connection -and thus thinks i'm not online - -Change-Id: I1480f76338d6ae4fbed676f9fa40ada18ea431ad -Reviewed-by: Alex Blasche ---- - src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp -index f52b9d4..0378ac7 100644 ---- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp -+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp -@@ -80,10 +80,10 @@ QNetworkManagerEngine::QNetworkManagerEngine(QObject *parent) - this, SLOT(ofonoUnRegistered(QString))); - - if (QDBusConnection::systemBus().interface()->isServiceRegistered("org.ofono")) -- ofonoRegistered(); -+ QMetaObject::invokeMethod(this, "ofonoRegistered", Qt::QueuedConnection); - - if (QDBusConnection::systemBus().interface()->isServiceRegistered(NM_DBUS_SERVICE)) -- nmRegistered(); -+ QMetaObject::invokeMethod(this, "nmRegistered", Qt::QueuedConnection); - } - - QNetworkManagerEngine::~QNetworkManagerEngine() --- -1.9.3 - diff --git a/0136-Make-sure-there-s-a-scene-before-using-it.patch b/0136-Make-sure-there-s-a-scene-before-using-it.patch deleted file mode 100644 index 7829c5e..0000000 --- a/0136-Make-sure-there-s-a-scene-before-using-it.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 8fccfef424e7d2b7a2019b1f828234145d4011df Mon Sep 17 00:00:00 2001 -From: Albert Astals Cid -Date: Tue, 17 Feb 2015 09:53:27 +0100 -Subject: [PATCH 136/163] Make sure there's a scene before using it -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Fixes crash hovering links in quassel - -Task-number: QTBUG-44509 -Change-Id: I77d8d9118ad185ed70a46e91445e2960200e562b -Reviewed-by: Michael BrĂ¼ning -Reviewed-by: Frederik Gladhorn -Reviewed-by: Marc Mutz ---- - src/widgets/kernel/qwidget.cpp | 4 ++-- - .../qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp | 11 +++++++++++ - 2 files changed, 13 insertions(+), 2 deletions(-) - -diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp -index 6871541..cb2e9e0 100644 ---- a/src/widgets/kernel/qwidget.cpp -+++ b/src/widgets/kernel/qwidget.cpp -@@ -12272,7 +12272,7 @@ QPoint QWidget::mapToGlobal(const QPoint &pos) const - { - #ifndef QT_NO_GRAPHICSVIEW - Q_D(const QWidget); -- if (d->extra && d->extra->proxyWidget) { -+ if (d->extra && d->extra->proxyWidget && d->extra->proxyWidget->scene()) { - const QList views = d->extra->proxyWidget->scene()->views(); - if (!views.isEmpty()) { - const QPointF scenePos = d->extra->proxyWidget->mapToScene(pos); -@@ -12307,7 +12307,7 @@ QPoint QWidget::mapFromGlobal(const QPoint &pos) const - { - #ifndef QT_NO_GRAPHICSVIEW - Q_D(const QWidget); -- if (d->extra && d->extra->proxyWidget) { -+ if (d->extra && d->extra->proxyWidget && d->extra->proxyWidget->scene()) { - const QList views = d->extra->proxyWidget->scene()->views(); - if (!views.isEmpty()) { - const QPoint viewPortPos = views.first()->viewport()->mapFromGlobal(pos); --- -1.9.3 - diff --git a/0240-QLockFile-fix-deadlock-when-the-lock-file-is-corrupt.patch b/0240-QLockFile-fix-deadlock-when-the-lock-file-is-corrupt.patch deleted file mode 100644 index cf84945..0000000 --- a/0240-QLockFile-fix-deadlock-when-the-lock-file-is-corrupt.patch +++ /dev/null @@ -1,113 +0,0 @@ -From f58e882b7594c59b6050d3c87562fcf836d10f60 Mon Sep 17 00:00:00 2001 -From: Olivier Goffart -Date: Tue, 14 Apr 2015 10:58:26 +0200 -Subject: [PATCH 240/248] QLockFile: fix deadlock when the lock file is - corrupted - -[ChangeLog][QtCore][QLockFile] Fixed a deadlock when the lock file -is corrupted. - -Task-number: QTBUG-44771 -Change-Id: Ic490b09d70ff1cc1733b64949889a73720b2d0f3 -Reviewed-by: David Faure ---- - src/corelib/io/qlockfile_unix.cpp | 10 +++++----- - src/corelib/io/qlockfile_win.cpp | 22 +++++++++++----------- - tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp | 17 +++++++++++++++++ - 3 files changed, 33 insertions(+), 16 deletions(-) - -diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp -index bf1015a..dc9f8f7 100644 ---- a/src/corelib/io/qlockfile_unix.cpp -+++ b/src/corelib/io/qlockfile_unix.cpp -@@ -181,11 +181,11 @@ bool QLockFilePrivate::isApparentlyStale() const - { - qint64 pid; - QString hostname, appname; -- if (!getLockInfo(&pid, &hostname, &appname)) -- return false; -- if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) { -- if (::kill(pid, 0) == -1 && errno == ESRCH) -- return true; // PID doesn't exist anymore -+ if (getLockInfo(&pid, &hostname, &appname)) { -+ if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) { -+ if (::kill(pid, 0) == -1 && errno == ESRCH) -+ return true; // PID doesn't exist anymore -+ } - } - const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime()); - return staleLockTime > 0 && age > staleLockTime; -diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp -index f9f2909..3587c7b 100644 ---- a/src/corelib/io/qlockfile_win.cpp -+++ b/src/corelib/io/qlockfile_win.cpp -@@ -115,21 +115,21 @@ bool QLockFilePrivate::isApparentlyStale() const - { - qint64 pid; - QString hostname, appname; -- if (!getLockInfo(&pid, &hostname, &appname)) -- return false; - - // On WinRT there seems to be no way of obtaining information about other - // processes due to sandboxing - #ifndef Q_OS_WINRT -- if (hostname == QString::fromLocal8Bit(localHostName())) { -- HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); -- if (!procHandle) -- return true; -- // We got a handle but check if process is still alive -- DWORD dwR = ::WaitForSingleObject(procHandle, 0); -- ::CloseHandle(procHandle); -- if (dwR == WAIT_TIMEOUT) -- return true; -+ if (getLockInfo(&pid, &hostname, &appname)) { -+ if (hostname == QString::fromLocal8Bit(localHostName())) { -+ HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); -+ if (!procHandle) -+ return true; -+ // We got a handle but check if process is still alive -+ DWORD dwR = ::WaitForSingleObject(procHandle, 0); -+ ::CloseHandle(procHandle); -+ if (dwR == WAIT_TIMEOUT) -+ return true; -+ } - } - #endif // !Q_OS_WINRT - const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime()); -diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp -index 77bef94..12bea67 100644 ---- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp -+++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp -@@ -58,6 +58,7 @@ private slots: - void staleLongLockFromBusyProcess(); - void staleLockRace(); - void noPermissions(); -+ void corruptedLockFile(); - - public: - QString m_helperApp; -@@ -415,5 +416,21 @@ void tst_QLockFile::noPermissions() - QCOMPARE(int(lockFile.error()), int(QLockFile::PermissionError)); - } - -+void tst_QLockFile::corruptedLockFile() -+{ -+ const QString fileName = dir.path() + "/corruptedLockFile"; -+ -+ { -+ // Create a empty file. Typically the result of a computer crash or hard disk full. -+ QFile file(fileName); -+ QVERIFY(file.open(QFile::WriteOnly)); -+ } -+ -+ QLockFile secondLock(fileName); -+ secondLock.setStaleLockTime(100); -+ QVERIFY(secondLock.tryLock(10000)); -+ QCOMPARE(int(secondLock.error()), int(QLockFile::NoError)); -+} -+ - QTEST_MAIN(tst_QLockFile) - #include "tst_qlockfile.moc" --- -2.3.7 - diff --git a/0248-QNAM-Fix-upload-corruptions-when-server-closes-conne.patch b/0248-QNAM-Fix-upload-corruptions-when-server-closes-conne.patch deleted file mode 100644 index 3ef7cd7..0000000 --- a/0248-QNAM-Fix-upload-corruptions-when-server-closes-conne.patch +++ /dev/null @@ -1,692 +0,0 @@ -From cff39fba10ffc10ee4dcfdc66ff6528eb26462d3 Mon Sep 17 00:00:00 2001 -From: Markus Goetz -Date: Fri, 10 Apr 2015 14:09:53 +0200 -Subject: [PATCH 248/257] QNAM: Fix upload corruptions when server closes - connection - -This patch fixes several upload corruptions if the server closes the connection -while/before we send data into it. They happen inside multiple places in the HTTP -layer and are explained in the comments. -Corruptions are: -* The upload byte device has an in-flight signal with pending upload data, if -it gets reset (because server closes the connection) then the re-send of the -request was sometimes taking this stale in-flight pending upload data. -* Because some signals were DirectConnection and some were QueuedConnection, there -was a chance that a direct signal overtakes a queued signal. The state machine -then sent data down the socket which was buffered there (and sent later) although -it did not match the current state of the state machine when it was actually sent. -* A socket was seen as being able to have requests sent even though it was not -encrypted yet. This relates to the previous corruption where data is stored inside -the socket's buffer and then sent later. - -The included auto test produces all fixed corruptions, I detected no regressions -via the other tests. -This code also adds a bit of sanity checking to protect from possible further -problems. - -[ChangeLog][QtNetwork] Fix HTTP(s) upload corruption when server closes connection - -Change-Id: I54c883925ec897050941498f139c4b523030432e -Reviewed-by: Peter Hartmann ---- - src/corelib/io/qnoncontiguousbytedevice.cpp | 18 +++ - src/corelib/io/qnoncontiguousbytedevice_p.h | 4 + - .../access/qhttpnetworkconnectionchannel.cpp | 35 ++++- - .../access/qhttpnetworkconnectionchannel_p.h | 2 + - src/network/access/qhttpprotocolhandler.cpp | 7 + - src/network/access/qhttpthreaddelegate_p.h | 36 ++++- - src/network/access/qnetworkreplyhttpimpl.cpp | 25 ++- - src/network/access/qnetworkreplyhttpimpl_p.h | 7 +- - .../access/qnetworkreply/tst_qnetworkreply.cpp | 175 ++++++++++++++++++++- - 9 files changed, 279 insertions(+), 30 deletions(-) - -diff --git a/src/corelib/io/qnoncontiguousbytedevice.cpp b/src/corelib/io/qnoncontiguousbytedevice.cpp -index 11510a8..760ca3d 100644 ---- a/src/corelib/io/qnoncontiguousbytedevice.cpp -+++ b/src/corelib/io/qnoncontiguousbytedevice.cpp -@@ -236,6 +236,11 @@ qint64 QNonContiguousByteDeviceByteArrayImpl::size() - return byteArray->size(); - } - -+qint64 QNonContiguousByteDeviceByteArrayImpl::pos() -+{ -+ return currentPosition; -+} -+ - QNonContiguousByteDeviceRingBufferImpl::QNonContiguousByteDeviceRingBufferImpl(QSharedPointer rb) - : QNonContiguousByteDevice(), currentPosition(0) - { -@@ -273,6 +278,11 @@ bool QNonContiguousByteDeviceRingBufferImpl::atEnd() - return currentPosition >= size(); - } - -+qint64 QNonContiguousByteDeviceRingBufferImpl::pos() -+{ -+ return currentPosition; -+} -+ - bool QNonContiguousByteDeviceRingBufferImpl::reset() - { - if (resetDisabled) -@@ -406,6 +416,14 @@ qint64 QNonContiguousByteDeviceIoDeviceImpl::size() - return device->size() - initialPosition; - } - -+qint64 QNonContiguousByteDeviceIoDeviceImpl::pos() -+{ -+ if (device->isSequential()) -+ return -1; -+ -+ return device->pos(); -+} -+ - QByteDeviceWrappingIoDevice::QByteDeviceWrappingIoDevice(QNonContiguousByteDevice *bd) : QIODevice((QObject*)0) - { - byteDevice = bd; -diff --git a/src/corelib/io/qnoncontiguousbytedevice_p.h b/src/corelib/io/qnoncontiguousbytedevice_p.h -index c05ae11..4d7b7b0 100644 ---- a/src/corelib/io/qnoncontiguousbytedevice_p.h -+++ b/src/corelib/io/qnoncontiguousbytedevice_p.h -@@ -61,6 +61,7 @@ public: - virtual const char* readPointer(qint64 maximumLength, qint64 &len) = 0; - virtual bool advanceReadPointer(qint64 amount) = 0; - virtual bool atEnd() = 0; -+ virtual qint64 pos() { return -1; } - virtual bool reset() = 0; - void disableReset(); - bool isResetDisabled() { return resetDisabled; } -@@ -106,6 +107,7 @@ public: - bool atEnd(); - bool reset(); - qint64 size(); -+ qint64 pos() Q_DECL_OVERRIDE; - protected: - QByteArray* byteArray; - qint64 currentPosition; -@@ -121,6 +123,7 @@ public: - bool atEnd(); - bool reset(); - qint64 size(); -+ qint64 pos() Q_DECL_OVERRIDE; - protected: - QSharedPointer ringBuffer; - qint64 currentPosition; -@@ -138,6 +141,7 @@ public: - bool atEnd(); - bool reset(); - qint64 size(); -+ qint64 pos() Q_DECL_OVERRIDE; - protected: - QIODevice* device; - QByteArray* currentReadBuffer; -diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp -index 9f63280..49c6793 100644 ---- a/src/network/access/qhttpnetworkconnectionchannel.cpp -+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp -@@ -106,15 +106,19 @@ void QHttpNetworkConnectionChannel::init() - socket->setProxy(QNetworkProxy::NoProxy); - #endif - -+ // We want all signals (except the interactive ones) be connected as QueuedConnection -+ // because else we're falling into cases where we recurse back into the socket code -+ // and mess up the state. Always going to the event loop (and expecting that when reading/writing) -+ // is safer. - QObject::connect(socket, SIGNAL(bytesWritten(qint64)), - this, SLOT(_q_bytesWritten(qint64)), -- Qt::DirectConnection); -+ Qt::QueuedConnection); - QObject::connect(socket, SIGNAL(connected()), - this, SLOT(_q_connected()), -- Qt::DirectConnection); -+ Qt::QueuedConnection); - QObject::connect(socket, SIGNAL(readyRead()), - this, SLOT(_q_readyRead()), -- Qt::DirectConnection); -+ Qt::QueuedConnection); - - // The disconnected() and error() signals may already come - // while calling connectToHost(). -@@ -143,13 +147,13 @@ void QHttpNetworkConnectionChannel::init() - // won't be a sslSocket if encrypt is false - QObject::connect(sslSocket, SIGNAL(encrypted()), - this, SLOT(_q_encrypted()), -- Qt::DirectConnection); -+ Qt::QueuedConnection); - QObject::connect(sslSocket, SIGNAL(sslErrors(QList)), - this, SLOT(_q_sslErrors(QList)), - Qt::DirectConnection); - QObject::connect(sslSocket, SIGNAL(encryptedBytesWritten(qint64)), - this, SLOT(_q_encryptedBytesWritten(qint64)), -- Qt::DirectConnection); -+ Qt::QueuedConnection); - - if (ignoreAllSslErrors) - sslSocket->ignoreSslErrors(); -@@ -186,8 +190,11 @@ void QHttpNetworkConnectionChannel::close() - // pendingEncrypt must only be true in between connected and encrypted states - pendingEncrypt = false; - -- if (socket) -+ if (socket) { -+ // socket can be 0 since the host lookup is done from qhttpnetworkconnection.cpp while -+ // there is no socket yet. - socket->close(); -+ } - } - - -@@ -353,6 +360,14 @@ bool QHttpNetworkConnectionChannel::ensureConnection() - } - return false; - } -+ -+ // This code path for ConnectedState -+ if (pendingEncrypt) { -+ // Let's only be really connected when we have received the encrypted() signal. Else the state machine seems to mess up -+ // and corrupt the things sent to the server. -+ return false; -+ } -+ - return true; - } - -@@ -659,6 +674,12 @@ bool QHttpNetworkConnectionChannel::isSocketReading() const - void QHttpNetworkConnectionChannel::_q_bytesWritten(qint64 bytes) - { - Q_UNUSED(bytes); -+ if (ssl) { -+ // In the SSL case we want to send data from encryptedBytesWritten signal since that one -+ // is the one going down to the actual network, not only into some SSL buffer. -+ return; -+ } -+ - // bytes have been written to the socket. write even more of them :) - if (isSocketWriting()) - sendRequest(); -@@ -734,7 +755,7 @@ void QHttpNetworkConnectionChannel::_q_connected() - - // ### FIXME: if the server closes the connection unexpectedly, we shouldn't send the same broken request again! - //channels[i].reconnectAttempts = 2; -- if (pendingEncrypt) { -+ if (ssl || pendingEncrypt) { // FIXME: Didn't work properly with pendingEncrypt only, we should refactor this into an EncrypingState - #ifndef QT_NO_SSL - if (connection->sslContext().isNull()) { - // this socket is making the 1st handshake for this connection, -diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h -index 692c0e6..231fe11 100644 ---- a/src/network/access/qhttpnetworkconnectionchannel_p.h -+++ b/src/network/access/qhttpnetworkconnectionchannel_p.h -@@ -83,6 +83,8 @@ typedef QPair HttpMessagePair; - class QHttpNetworkConnectionChannel : public QObject { - Q_OBJECT - public: -+ // TODO: Refactor this to add an EncryptingState (and remove pendingEncrypt). -+ // Also add an Unconnected state so IdleState does not have double meaning. - enum ChannelState { - IdleState = 0, // ready to send request - ConnectingState = 1, // connecting to host -diff --git a/src/network/access/qhttpprotocolhandler.cpp b/src/network/access/qhttpprotocolhandler.cpp -index 28e10f7..3357948 100644 ---- a/src/network/access/qhttpprotocolhandler.cpp -+++ b/src/network/access/qhttpprotocolhandler.cpp -@@ -368,6 +368,13 @@ bool QHttpProtocolHandler::sendRequest() - // nothing to read currently, break the loop - break; - } else { -+ if (m_channel->written != uploadByteDevice->pos()) { -+ // Sanity check. This was useful in tracking down an upload corruption. -+ qWarning() << "QHttpProtocolHandler: Internal error in sendRequest. Expected to write at position" << m_channel->written << "but read device is at" << uploadByteDevice->pos(); -+ Q_ASSERT(m_channel->written == uploadByteDevice->pos()); -+ m_connection->d_func()->emitReplyError(m_socket, m_reply, QNetworkReply::ProtocolFailure); -+ return false; -+ } - qint64 currentWriteSize = m_socket->write(readPointer, currentReadSize); - if (currentWriteSize == -1 || currentWriteSize != currentReadSize) { - // socket broke down -diff --git a/src/network/access/qhttpthreaddelegate_p.h b/src/network/access/qhttpthreaddelegate_p.h -index 1661082..b553409 100644 ---- a/src/network/access/qhttpthreaddelegate_p.h -+++ b/src/network/access/qhttpthreaddelegate_p.h -@@ -187,6 +187,7 @@ protected: - QByteArray m_dataArray; - bool m_atEnd; - qint64 m_size; -+ qint64 m_pos; // to match calls of haveDataSlot with the expected position - public: - QNonContiguousByteDeviceThreadForwardImpl(bool aE, qint64 s) - : QNonContiguousByteDevice(), -@@ -194,7 +195,8 @@ public: - m_amount(0), - m_data(0), - m_atEnd(aE), -- m_size(s) -+ m_size(s), -+ m_pos(0) - { - } - -@@ -202,6 +204,11 @@ public: - { - } - -+ qint64 pos() Q_DECL_OVERRIDE -+ { -+ return m_pos; -+ } -+ - const char* readPointer(qint64 maximumLength, qint64 &len) - { - if (m_amount > 0) { -@@ -229,11 +236,10 @@ public: - - m_amount -= a; - m_data += a; -+ m_pos += a; - -- // To main thread to inform about our state -- emit processedData(a); -- -- // FIXME possible optimization, already ask user thread for some data -+ // To main thread to inform about our state. The m_pos will be sent as a sanity check. -+ emit processedData(m_pos, a); - - return true; - } -@@ -250,10 +256,21 @@ public: - { - m_amount = 0; - m_data = 0; -+ m_dataArray.clear(); -+ -+ if (wantDataPending) { -+ // had requested the user thread to send some data (only 1 in-flight at any moment) -+ wantDataPending = false; -+ } - - // Communicate as BlockingQueuedConnection - bool b = false; - emit resetData(&b); -+ if (b) { -+ // the reset succeeded, we're at pos 0 again -+ m_pos = 0; -+ // the HTTP code will anyway abort the request if !b. -+ } - return b; - } - -@@ -264,8 +281,13 @@ public: - - public slots: - // From user thread: -- void haveDataSlot(QByteArray dataArray, bool dataAtEnd, qint64 dataSize) -+ void haveDataSlot(qint64 pos, QByteArray dataArray, bool dataAtEnd, qint64 dataSize) - { -+ if (pos != m_pos) { -+ // Sometimes when re-sending a request in the qhttpnetwork* layer there is a pending haveData from the -+ // user thread on the way to us. We need to ignore it since it is the data for the wrong(later) chunk. -+ return; -+ } - wantDataPending = false; - - m_dataArray = dataArray; -@@ -285,7 +307,7 @@ signals: - - // to main thread: - void wantData(qint64); -- void processedData(qint64); -+ void processedData(qint64 pos, qint64 amount); - void resetData(bool *b); - }; - -diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp -index 4ce7303..974a101 100644 ---- a/src/network/access/qnetworkreplyhttpimpl.cpp -+++ b/src/network/access/qnetworkreplyhttpimpl.cpp -@@ -424,6 +424,7 @@ QNetworkReplyHttpImplPrivate::QNetworkReplyHttpImplPrivate() - , synchronous(false) - , state(Idle) - , statusCode(0) -+ , uploadByteDevicePosition(false) - , uploadDeviceChoking(false) - , outgoingData(0) - , bytesUploaded(-1) -@@ -863,9 +864,9 @@ void QNetworkReplyHttpImplPrivate::postRequest() - q, SLOT(uploadByteDeviceReadyReadSlot()), - Qt::QueuedConnection); - -- // From main thread to user thread: -- QObject::connect(q, SIGNAL(haveUploadData(QByteArray,bool,qint64)), -- forwardUploadDevice, SLOT(haveDataSlot(QByteArray,bool,qint64)), Qt::QueuedConnection); -+ // From user thread to http thread: -+ QObject::connect(q, SIGNAL(haveUploadData(qint64,QByteArray,bool,qint64)), -+ forwardUploadDevice, SLOT(haveDataSlot(qint64,QByteArray,bool,qint64)), Qt::QueuedConnection); - QObject::connect(uploadByteDevice.data(), SIGNAL(readyRead()), - forwardUploadDevice, SIGNAL(readyRead()), - Qt::QueuedConnection); -@@ -873,8 +874,8 @@ void QNetworkReplyHttpImplPrivate::postRequest() - // From http thread to user thread: - QObject::connect(forwardUploadDevice, SIGNAL(wantData(qint64)), - q, SLOT(wantUploadDataSlot(qint64))); -- QObject::connect(forwardUploadDevice, SIGNAL(processedData(qint64)), -- q, SLOT(sentUploadDataSlot(qint64))); -+ QObject::connect(forwardUploadDevice,SIGNAL(processedData(qint64, qint64)), -+ q, SLOT(sentUploadDataSlot(qint64,qint64))); - QObject::connect(forwardUploadDevice, SIGNAL(resetData(bool*)), - q, SLOT(resetUploadDataSlot(bool*)), - Qt::BlockingQueuedConnection); // this is the only one with BlockingQueued! -@@ -1268,12 +1269,22 @@ void QNetworkReplyHttpImplPrivate::replySslConfigurationChanged(const QSslConfig - void QNetworkReplyHttpImplPrivate::resetUploadDataSlot(bool *r) - { - *r = uploadByteDevice->reset(); -+ if (*r) { -+ // reset our own position which is used for the inter-thread communication -+ uploadByteDevicePosition = 0; -+ } - } - - // Coming from QNonContiguousByteDeviceThreadForwardImpl in HTTP thread --void QNetworkReplyHttpImplPrivate::sentUploadDataSlot(qint64 amount) -+void QNetworkReplyHttpImplPrivate::sentUploadDataSlot(qint64 pos, qint64 amount) - { -+ if (uploadByteDevicePosition + amount != pos) { -+ // Sanity check, should not happen. -+ error(QNetworkReply::UnknownNetworkError, ""); -+ return; -+ } - uploadByteDevice->advanceReadPointer(amount); -+ uploadByteDevicePosition += amount; - } - - // Coming from QNonContiguousByteDeviceThreadForwardImpl in HTTP thread -@@ -1298,7 +1309,7 @@ void QNetworkReplyHttpImplPrivate::wantUploadDataSlot(qint64 maxSize) - QByteArray dataArray(data, currentUploadDataLength); - - // Communicate back to HTTP thread -- emit q->haveUploadData(dataArray, uploadByteDevice->atEnd(), uploadByteDevice->size()); -+ emit q->haveUploadData(uploadByteDevicePosition, dataArray, uploadByteDevice->atEnd(), uploadByteDevice->size()); - } - - void QNetworkReplyHttpImplPrivate::uploadByteDeviceReadyReadSlot() -diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h -index 77d9c5a..1940922 100644 ---- a/src/network/access/qnetworkreplyhttpimpl_p.h -+++ b/src/network/access/qnetworkreplyhttpimpl_p.h -@@ -120,7 +120,7 @@ public: - - Q_PRIVATE_SLOT(d_func(), void resetUploadDataSlot(bool *r)) - Q_PRIVATE_SLOT(d_func(), void wantUploadDataSlot(qint64)) -- Q_PRIVATE_SLOT(d_func(), void sentUploadDataSlot(qint64)) -+ Q_PRIVATE_SLOT(d_func(), void sentUploadDataSlot(qint64,qint64)) - Q_PRIVATE_SLOT(d_func(), void uploadByteDeviceReadyReadSlot()) - Q_PRIVATE_SLOT(d_func(), void emitReplyUploadProgress(qint64, qint64)) - Q_PRIVATE_SLOT(d_func(), void _q_cacheSaveDeviceAboutToClose()) -@@ -144,7 +144,7 @@ signals: - - void startHttpRequestSynchronously(); - -- void haveUploadData(QByteArray dataArray, bool dataAtEnd, qint64 dataSize); -+ void haveUploadData(const qint64 pos, QByteArray dataArray, bool dataAtEnd, qint64 dataSize); - }; - - class QNetworkReplyHttpImplPrivate: public QNetworkReplyPrivate -@@ -195,6 +195,7 @@ public: - // upload - QNonContiguousByteDevice* createUploadByteDevice(); - QSharedPointer uploadByteDevice; -+ qint64 uploadByteDevicePosition; - bool uploadDeviceChoking; // if we couldn't readPointer() any data at the moment - QIODevice *outgoingData; - QSharedPointer outgoingDataBuffer; -@@ -283,7 +284,7 @@ public: - // From QNonContiguousByteDeviceThreadForwardImpl in HTTP thread: - void resetUploadDataSlot(bool *r); - void wantUploadDataSlot(qint64); -- void sentUploadDataSlot(qint64); -+ void sentUploadDataSlot(qint64, qint64); - - // From user's QNonContiguousByteDevice - void uploadByteDeviceReadyReadSlot(); -diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp -index 3ccedf6..d2edf67 100644 ---- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp -+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp -@@ -457,6 +457,10 @@ private Q_SLOTS: - - void putWithRateLimiting(); - -+#ifndef QT_NO_SSL -+ void putWithServerClosingConnectionImmediately(); -+#endif -+ - // NOTE: This test must be last! - void parentingRepliesToTheApp(); - private: -@@ -4718,18 +4722,22 @@ void tst_QNetworkReply::ioPostToHttpNoBufferFlag() - class SslServer : public QTcpServer { - Q_OBJECT - public: -- SslServer() : socket(0) {}; -+ SslServer() : socket(0), m_ssl(true) {} - void incomingConnection(qintptr socketDescriptor) { - QSslSocket *serverSocket = new QSslSocket; - serverSocket->setParent(this); - - if (serverSocket->setSocketDescriptor(socketDescriptor)) { -+ connect(serverSocket, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); -+ if (!m_ssl) { -+ emit newPlainConnection(serverSocket); -+ return; -+ } - QString testDataDir = QFileInfo(QFINDTESTDATA("rfc3252.txt")).absolutePath(); - if (testDataDir.isEmpty()) - testDataDir = QCoreApplication::applicationDirPath(); - - connect(serverSocket, SIGNAL(encrypted()), this, SLOT(encryptedSlot())); -- connect(serverSocket, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); - serverSocket->setProtocol(QSsl::AnyProtocol); - connect(serverSocket, SIGNAL(sslErrors(QList)), serverSocket, SLOT(ignoreSslErrors())); - serverSocket->setLocalCertificate(testDataDir + "/certs/server.pem"); -@@ -4740,11 +4748,12 @@ public: - } - } - signals: -- void newEncryptedConnection(); -+ void newEncryptedConnection(QSslSocket *s); -+ void newPlainConnection(QSslSocket *s); - public slots: - void encryptedSlot() { - socket = (QSslSocket*) sender(); -- emit newEncryptedConnection(); -+ emit newEncryptedConnection(socket); - } - void readyReadSlot() { - // for the incoming sockets, not the server socket -@@ -4753,6 +4762,7 @@ public slots: - - public: - QSslSocket *socket; -+ bool m_ssl; - }; - - // very similar to ioPostToHttpUploadProgress but for SSL -@@ -4780,7 +4790,7 @@ void tst_QNetworkReply::ioPostToHttpsUploadProgress() - QNetworkReplyPtr reply(manager.post(request, sourceFile)); - - QSignalSpy spy(reply.data(), SIGNAL(uploadProgress(qint64,qint64))); -- connect(&server, SIGNAL(newEncryptedConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); -+ connect(&server, SIGNAL(newEncryptedConnection(QSslSocket*)), &QTestEventLoop::instance(), SLOT(exitLoop())); - connect(reply, SIGNAL(sslErrors(QList)), reply.data(), SLOT(ignoreSslErrors())); - - // get the request started and the incoming socket connected -@@ -4788,7 +4798,7 @@ void tst_QNetworkReply::ioPostToHttpsUploadProgress() - QVERIFY(!QTestEventLoop::instance().timeout()); - QTcpSocket *incomingSocket = server.socket; - QVERIFY(incomingSocket); -- disconnect(&server, SIGNAL(newEncryptedConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); -+ disconnect(&server, SIGNAL(newEncryptedConnection(QSslSocket*)), &QTestEventLoop::instance(), SLOT(exitLoop())); - - - incomingSocket->setReadBufferSize(1*1024); -@@ -7905,6 +7915,159 @@ void tst_QNetworkReply::putWithRateLimiting() - } - - -+#ifndef QT_NO_SSL -+ -+class PutWithServerClosingConnectionImmediatelyHandler: public QObject -+{ -+ Q_OBJECT -+public: -+ bool m_parsedHeaders; -+ QByteArray m_receivedData; -+ QByteArray m_expectedData; -+ QSslSocket *m_socket; -+ PutWithServerClosingConnectionImmediatelyHandler(QSslSocket *s, QByteArray expected) :m_parsedHeaders(false), m_expectedData(expected), m_socket(s) -+ { -+ m_socket->setParent(this); -+ connect(m_socket, SIGNAL(readyRead()), SLOT(readyReadSlot())); -+ connect(m_socket, SIGNAL(disconnected()), SLOT(disconnectedSlot())); -+ } -+signals: -+ void correctFileUploadReceived(); -+ void corruptFileUploadReceived(); -+ -+public slots: -+ void closeDelayed() { -+ m_socket->close(); -+ } -+ -+ void readyReadSlot() -+ { -+ QByteArray data = m_socket->readAll(); -+ m_receivedData += data; -+ if (!m_parsedHeaders && m_receivedData.contains("\r\n\r\n")) { -+ m_parsedHeaders = true; -+ QTimer::singleShot(qrand()%10, this, SLOT(closeDelayed())); // simulate random network latency -+ // This server simulates a web server connection closing, e.g. because of Apaches MaxKeepAliveRequests or KeepAliveTimeout -+ // In this case QNAM needs to re-send the upload data but it had a bug which then corrupts the upload -+ // This test catches that. -+ } -+ -+ } -+ void disconnectedSlot() -+ { -+ if (m_parsedHeaders) { -+ //qDebug() << m_receivedData.left(m_receivedData.indexOf("\r\n\r\n")); -+ m_receivedData = m_receivedData.mid(m_receivedData.indexOf("\r\n\r\n")+4); // check only actual data -+ } -+ if (m_receivedData.length() > 0 && !m_expectedData.startsWith(m_receivedData)) { -+ // We had received some data but it is corrupt! -+ qDebug() << "CORRUPT" << m_receivedData.count(); -+ -+ // Use this to track down the pattern of the corruption and conclude the source -+// QFile a("/tmp/corrupt"); -+// a.open(QIODevice::WriteOnly); -+// a.write(m_receivedData); -+// a.close(); -+ -+// QFile b("/tmp/correct"); -+// b.open(QIODevice::WriteOnly); -+// b.write(m_expectedData); -+// b.close(); -+ //exit(1); -+ emit corruptFileUploadReceived(); -+ } else { -+ emit correctFileUploadReceived(); -+ } -+ } -+}; -+ -+class PutWithServerClosingConnectionImmediatelyServer: public SslServer -+{ -+ Q_OBJECT -+public: -+ int m_correctUploads; -+ int m_corruptUploads; -+ int m_repliesFinished; -+ int m_expectedReplies; -+ QByteArray m_expectedData; -+ PutWithServerClosingConnectionImmediatelyServer() : SslServer(), m_correctUploads(0), m_corruptUploads(0), m_repliesFinished(0), m_expectedReplies(0) -+ { -+ QObject::connect(this, SIGNAL(newEncryptedConnection(QSslSocket*)), this, SLOT(createHandlerForConnection(QSslSocket*))); -+ QObject::connect(this, SIGNAL(newPlainConnection(QSslSocket*)), this, SLOT(createHandlerForConnection(QSslSocket*))); -+ } -+ -+public slots: -+ void createHandlerForConnection(QSslSocket* s) { -+ PutWithServerClosingConnectionImmediatelyHandler *handler = new PutWithServerClosingConnectionImmediatelyHandler(s, m_expectedData); -+ handler->setParent(this); -+ QObject::connect(handler, SIGNAL(correctFileUploadReceived()), this, SLOT(increaseCorrect())); -+ QObject::connect(handler, SIGNAL(corruptFileUploadReceived()), this, SLOT(increaseCorrupt())); -+ } -+ void increaseCorrect() { -+ m_correctUploads++; -+ } -+ void increaseCorrupt() { -+ m_corruptUploads++; -+ } -+ void replyFinished() { -+ m_repliesFinished++; -+ if (m_repliesFinished == m_expectedReplies) { -+ QTestEventLoop::instance().exitLoop(); -+ } -+ } -+}; -+ -+ -+ -+void tst_QNetworkReply::putWithServerClosingConnectionImmediately() -+{ -+ const int numUploads = 40; -+ qint64 wantedSize = 512*1024; // 512 kB -+ QByteArray sourceFile; -+ for (int i = 0; i < wantedSize; ++i) { -+ sourceFile += (char)'a' +(i%26); -+ } -+ bool withSsl = false; -+ -+ for (int s = 0; s <= 1; s++) { -+ withSsl = (s == 1); -+ // Test also needs to run several times because of 9c2ecf89 -+ for (int j = 0; j < 20; j++) { -+ // emulate a minimal https server -+ PutWithServerClosingConnectionImmediatelyServer server; -+ server.m_ssl = withSsl; -+ server.m_expectedData = sourceFile; -+ server.m_expectedReplies = numUploads; -+ server.listen(QHostAddress(QHostAddress::LocalHost), 0); -+ -+ for (int i = 0; i < numUploads; i++) { -+ // create the request -+ QUrl url = QUrl(QString("http%1://127.0.0.1:%2/file=%3").arg(withSsl ? "s" : "").arg(server.serverPort()).arg(i)); -+ QNetworkRequest request(url); -+ QNetworkReply *reply = manager.put(request, sourceFile); -+ connect(reply, SIGNAL(sslErrors(QList)), reply, SLOT(ignoreSslErrors())); -+ connect(reply, SIGNAL(finished()), &server, SLOT(replyFinished())); -+ reply->setParent(&server); -+ } -+ -+ // get the request started and the incoming socket connected -+ QTestEventLoop::instance().enterLoop(10); -+ -+ //qDebug() << "correct=" << server.m_correctUploads << "corrupt=" << server.m_corruptUploads << "expected=" < 5); -+ // Because actually important is that we don't get any corruption: -+ QCOMPARE(server.m_corruptUploads, 0); -+ -+ server.close(); -+ } -+ } -+ -+ -+} -+ -+#endif - - // NOTE: This test must be last testcase in tst_qnetworkreply! - void tst_QNetworkReply::parentingRepliesToTheApp() --- -2.4.0 - diff --git a/0260-Make-qglobal.h-complain-if-you-use-fPIE.patch b/0260-Make-qglobal.h-complain-if-you-use-fPIE.patch deleted file mode 100644 index 4208948..0000000 --- a/0260-Make-qglobal.h-complain-if-you-use-fPIE.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 3eca75de67b3fd2c890715b30c7899cebc096fe9 Mon Sep 17 00:00:00 2001 -From: Thiago Macieira -Date: Mon, 11 May 2015 18:30:00 +0900 -Subject: [PATCH 260/262] Make qglobal.h complain if you use -fPIE - -Prior to Qt 5.4.2 (commit 36d6eb721e7d5997ade75e289d4088dc48678d0d), we -allowed it, but now we need to enforce that it is not used. Note that --fPIE does define __PIC__, so we need this to catch the use of -fPIE. - -[ChangeLog][Important Behavior Changes] On x86 and x86-64 systems with -ELF binaries (especially Linux), due to a new optimization in GCC 5.x in -combination with a recent version of GNU binutils, compiling Qt -applications with -fPIE is no longer enough. Applications now need to be -compiled with the -fPIC option if Qt's option "reduce relocations" is -active. Note that Clang is known to generate incompatible code even with --fPIC if the -flto option is active. - -Task-number: QTBUG-45755 -Change-Id: I66a35ce5f88941f29aa6ffff13dd210e0aa2728f -Reviewed-by: Dmitry Shachnev -Reviewed-by: Simon Hausmann ---- - dist/changes-5.4.2 | 7 +++++++ - src/corelib/global/qglobal.h | 4 ++-- - 2 files changed, 9 insertions(+), 2 deletions(-) - -diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h -index ef84662..4547877 100644 ---- a/src/corelib/global/qglobal.h -+++ b/src/corelib/global/qglobal.h -@@ -1047,9 +1047,9 @@ Q_CORE_EXPORT int qrand(); - # define QT_NO_SHAREDMEMORY - #endif - --#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && !defined(__PIC__) -+#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && (!defined(__PIC__) || defined(__PIE__)) - # error "You must build your code with position independent code if Qt was built with -reduce-relocations. "\ -- "Compile your code with -fPIC." -+ "Compile your code with -fPIC (-fPIE is not enough)." - #endif - - namespace QtPrivate { --- -2.4.1 - diff --git a/0260-Require-fPIC-instead-of-just-fPIE-for-reduce-relocat.patch b/0260-Require-fPIC-instead-of-just-fPIE-for-reduce-relocat.patch deleted file mode 100644 index 9f488c2..0000000 --- a/0260-Require-fPIC-instead-of-just-fPIE-for-reduce-relocat.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 36d6eb721e7d5997ade75e289d4088dc48678d0d Mon Sep 17 00:00:00 2001 -From: Thiago Macieira -Date: Tue, 5 May 2015 08:43:42 -0700 -Subject: [PATCH 260/266] Require -fPIC instead of just -fPIE for - -reduce-relocations - -GCC 5 combined with a recent binutils have a new optimization that -allows them to generate copy relocations even in -fPIE code. Clang has -the same functionality when compiling an executable with -flto. We need -to let the compilers know that they cannot use copy relocations, so they -need to use really position-independent code. - -Position independent code throughout is not really required. We just -need the compilers to use position-independent access to symbols coming -from the Qt libraries, but there's currently no other way of doing that. - -Task-number: QTBUG-45755 -Change-Id: I0d4913955e3745b69672ffff13db5df7377398c5 -Reviewed-by: Simon Hausmann -Reviewed-by: Oswald Buddenhagen ---- - mkspecs/common/gcc-base.conf | 2 +- - mkspecs/common/qcc-base.conf | 2 +- - mkspecs/linux-icc/qmake.conf | 2 +- - src/corelib/Qt5CoreConfigExtras.cmake.in | 2 +- - src/corelib/global/qglobal.h | 4 ++-- - tests/auto/tools/moc/tst_moc.cpp | 6 +++--- - 6 files changed, 9 insertions(+), 9 deletions(-) - -diff --git a/mkspecs/common/gcc-base.conf b/mkspecs/common/gcc-base.conf -index a149f4d..e4ccbd7 100644 ---- a/mkspecs/common/gcc-base.conf -+++ b/mkspecs/common/gcc-base.conf -@@ -42,7 +42,7 @@ QMAKE_CFLAGS_RELEASE += $$QMAKE_CFLAGS_OPTIMIZE - QMAKE_CFLAGS_DEBUG += -g - QMAKE_CFLAGS_SHLIB += -fPIC - QMAKE_CFLAGS_STATIC_LIB += -fPIC --QMAKE_CFLAGS_APP += -fPIE -+QMAKE_CFLAGS_APP += -fPIC - QMAKE_CFLAGS_ISYSTEM = -isystem - QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses - QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden -diff --git a/mkspecs/common/qcc-base.conf b/mkspecs/common/qcc-base.conf -index f529d7f..8276316 100644 ---- a/mkspecs/common/qcc-base.conf -+++ b/mkspecs/common/qcc-base.conf -@@ -23,7 +23,7 @@ QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_OPTIMIZE -g - QMAKE_CFLAGS_DEBUG += -g - QMAKE_CFLAGS_SHLIB += -fPIC -shared - QMAKE_CFLAGS_STATIC_LIB += -fPIC --QMAKE_CFLAGS_APP += -fPIE -+QMAKE_CFLAGS_APP += -fPIC - QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses - QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden - QMAKE_CFLAGS_SSE2 += -msse2 -diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf -index 8119c8a..9190aa9 100644 ---- a/mkspecs/linux-icc/qmake.conf -+++ b/mkspecs/linux-icc/qmake.conf -@@ -12,7 +12,7 @@ QMAKE_LEXFLAGS = - QMAKE_YACC = yacc - QMAKE_YACCFLAGS = -d - QMAKE_CFLAGS = --QMAKE_CFLAGS_APP = -fPIE -+QMAKE_CFLAGS_APP = -fPIC - QMAKE_CFLAGS_DEPS = -M - QMAKE_CFLAGS_WARN_ON = -w1 -Wall -Wcheck -wd1572,873,2259,2261 - QMAKE_CFLAGS_WARN_OFF = -w -diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in -index 7213a84..48d5f21 100644 ---- a/src/corelib/Qt5CoreConfigExtras.cmake.in -+++ b/src/corelib/Qt5CoreConfigExtras.cmake.in -@@ -71,7 +71,7 @@ set(_qt5_corelib_extra_includes) - # macro to add it. - set(Qt5_POSITION_INDEPENDENT_CODE True) - set_property(TARGET Qt5::Core PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") --set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIE\") -+set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIC\") - - !!IF !isEmpty(QT_NAMESPACE) - list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) -diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h -index 455582e..ef84662 100644 ---- a/src/corelib/global/qglobal.h -+++ b/src/corelib/global/qglobal.h -@@ -1047,9 +1047,9 @@ Q_CORE_EXPORT int qrand(); - # define QT_NO_SHAREDMEMORY - #endif - --#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && !defined(__PIC__) && !defined(__PIE__) -+#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && !defined(__PIC__) - # error "You must build your code with position independent code if Qt was built with -reduce-relocations. "\ -- "Compile your code with -fPIC or -fPIE." -+ "Compile your code with -fPIC." - #endif - - namespace QtPrivate { -diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp -index edb6488..748cb82 100644 ---- a/tests/auto/tools/moc/tst_moc.cpp -+++ b/tests/auto/tools/moc/tst_moc.cpp -@@ -662,7 +662,7 @@ void tst_Moc::oldStyleCasts() - - QStringList args; - args << "-c" << "-x" << "c++" << "-Wold-style-cast" << "-I" << "." -- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIE" << "-"; -+ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-"; - proc.start("gcc", args); - QVERIFY(proc.waitForStarted()); - proc.write(mocOut); -@@ -732,7 +732,7 @@ void tst_Moc::inputFileNameWithDotsButNoExtension() - - QStringList args; - args << "-c" << "-x" << "c++" << "-I" << ".." -- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIE" << "-"; -+ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-"; - proc.start("gcc", args); - QVERIFY(proc.waitForStarted()); - proc.write(mocOut); -@@ -1011,7 +1011,7 @@ void tst_Moc::ignoreOptionClashes() - // If -pthread wasn't ignored, it was parsed as a prefix of "thread/", which breaks compilation. - QStringList gccArgs; - gccArgs << "-c" << "-x" << "c++" << "-I" << ".." -- << "-I" << qtIncludePath << "-I" << includeDir << "-o" << "/dev/null" << "-fPIE" << "-"; -+ << "-I" << qtIncludePath << "-I" << includeDir << "-o" << "/dev/null" << "-fPIC" << "-"; - proc.start("gcc", gccArgs); - QVERIFY(proc.waitForStarted()); - proc.write(mocOut); --- -2.4.0 - diff --git a/0262-Try-to-ensure-that-fPIC-is-used-in-CMake-builds.patch b/0262-Try-to-ensure-that-fPIC-is-used-in-CMake-builds.patch deleted file mode 100644 index cdfb455..0000000 --- a/0262-Try-to-ensure-that-fPIC-is-used-in-CMake-builds.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 083c9269ed73e8771e1dbe10812696b45b7389f3 Mon Sep 17 00:00:00 2001 -From: Evangelos Foutras -Date: Mon, 11 May 2015 12:20:57 +0300 -Subject: [PATCH 262/262] Try to ensure that -fPIC is used in CMake builds - -In commit 36d6eb721e7d5997ade75e289d4088dc48678d0d the -fPIE switch was -replaced with -fPIC in an effort to avoid generating copy relocations -which are incompatible with Qt5 when built with -reduce-relocations. - -Task-number: QTBUG-45755 -Change-Id: I59a55ea15052f498104848c5fd867e563ddc2290 -Reviewed-by: Thiago Macieira ---- - src/corelib/Qt5CoreConfigExtras.cmake.in | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in -index 48d5f21..d4abc5f 100644 ---- a/src/corelib/Qt5CoreConfigExtras.cmake.in -+++ b/src/corelib/Qt5CoreConfigExtras.cmake.in -@@ -70,8 +70,9 @@ set(_qt5_corelib_extra_includes) - # Qt5_POSITION_INDEPENDENT_CODE variable is used in the # qt5_use_module - # macro to add it. - set(Qt5_POSITION_INDEPENDENT_CODE True) --set_property(TARGET Qt5::Core PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") - set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIC\") -+set_property(TARGET Qt5::Core PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") -+set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}) - - !!IF !isEmpty(QT_NAMESPACE) - list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) --- -2.4.1 - diff --git a/qt5-qtbase.spec b/qt5-qtbase.spec index 497736a..8204f6b 100644 --- a/qt5-qtbase.spec +++ b/qt5-qtbase.spec @@ -41,8 +41,8 @@ Summary: Qt5 - QtBase components Name: qt5-qtbase -Version: 5.4.1 -Release: 20%{?dist} +Version: 5.4.2 +Release: 1%{?dist} # See LGPL_EXCEPTIONS.txt, for exception details License: LGPLv2 with exceptions or GPLv3 with exceptions @@ -117,19 +117,6 @@ Patch100: qtbase-opensource-src-5.4.0-QTBUG-43057.patch # Qt 5.5 patches Patch208: qt5-qtbase-5.5-Get_display_number_when_screen_number_is_omitted.patch -Patch204: 0004-Fix-QPrinter-setPaperSize-regression-when-using-QPri.patch -Patch212: 0012-Fix-a-crash-in-QPlainTextEdit-documentChanged.patch -Patch272: 0072-CMake-Fix-QObject-connect-failing-on-ARM.patch -Patch294: 0094-Fix-Meta-.-shortcuts-on-XCB.patch -Patch332: 0132-Call-ofono-nm-Registered-delayed-in-constructor-othe.patch -Patch336: 0136-Make-sure-there-s-a-scene-before-using-it.patch -Patch440: 0240-QLockFile-fix-deadlock-when-the-lock-file-is-corrupt.patch -Patch448: 0248-QNAM-Fix-upload-corruptions-when-server-closes-conne.patch -Patch460: 0260-Require-fPIC-instead-of-just-fPIE-for-reduce-relocat.patch -# from 5.4.2 branch -Patch461: 0260-Make-qglobal.h-complain-if-you-use-fPIE.patch -Patch462: 0262-Try-to-ensure-that-fPIC-is-used-in-CMake-builds.patch - # http://lists.qt-project.org/pipermail/announce/2015-February/000059.html # CVE-2015-0295 Patch349: 0149-Fix-a-division-by-zero-when-processing-malformed-BMP.patch @@ -401,21 +388,6 @@ rm -fv mkspecs/linux-g++*/qmake.conf.multilib-optflags %patch208 -p1 -b .ibus_get_display_number -%patch204 -p1 -b .0004 -%patch212 -p1 -b .0012 -%patch272 -p1 -b .0072 -%patch294 -p1 -b .0094 -%patch332 -p1 -b .0132 -%patch336 -p1 -b .0136 -%patch349 -p1 -b .0149 -%patch400 -p1 -b .0200 -%patch401 -p1 -b .0201 -%patch440 -p1 -b .0240 -%patch448 -p1 -b .0248 -%patch460 -p1 -b .0260 -%patch461 -p1 -b .0260-2 -%patch462 -p1 -b .0262 - # drop -fexceptions from $RPM_OPT_FLAGS RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS | sed 's|-fexceptions||g'` @@ -939,6 +911,9 @@ fi %changelog +* Tue Jun 02 2015 Jan Grulich 5.4.2-1 +- Update to 5.4.2 + * Tue May 26 2015 Rex Dieter 5.4.1-20 - SM_CLIENT_ID property is not set (QTBUG-46310) diff --git a/qtbase-opensource-src-5.4.0-QTBUG-42985.patch b/qtbase-opensource-src-5.4.0-QTBUG-42985.patch index 60bd6bd..276e976 100644 --- a/qtbase-opensource-src-5.4.0-QTBUG-42985.patch +++ b/qtbase-opensource-src-5.4.0-QTBUG-42985.patch @@ -5,7 +5,7 @@ index 39b031e..7f808da 100644 @@ -429,16 +429,40 @@ QList QPlatformIntegration::possibleKeys(const QKeyEvent *) const This adds the screen to QGuiApplication::screens(), and emits the QGuiApplication::screenAdded() signal. - + + If the added screen is a primary screen (isPrimary = true), it is prepended + to the QGuiApplicationPrivate::screen_list, since + QGuiApplication::primaryScreen always returns the first screen in the list. @@ -25,7 +25,7 @@ index 39b031e..7f808da 100644 + } emit qGuiApp->screenAdded(screen); } - + +/*! + Should be called by the implementation whenever a screen is removed. + @@ -51,13 +51,13 @@ index d510240..5ec7896 100644 +++ b/src/gui/kernel/qplatformintegration.h @@ -169,7 +169,8 @@ public: #endif - + protected: - void screenAdded(QPlatformScreen *screen); + void screenAdded(QPlatformScreen *screen, bool isPrimary = false); + void screenRemoved(QPlatformScreen *screen); }; - + QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp index 71710d1..4fb7114 100644 @@ -71,7 +71,7 @@ index 71710d1..4fb7114 100644 - QGuiApplicationPrivate::screen_list.removeOne(d->screen); delete d->screen; } - + diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp index ed6e8dd..8909eed 100644 --- a/src/gui/kernel/qscreen.cpp @@ -79,7 +79,7 @@ index ed6e8dd..8909eed 100644 @@ -66,16 +66,6 @@ QScreen::QScreen(QPlatformScreen *screen) { } - + - -/*! - Destroys the screen. @@ -99,25 +99,25 @@ index 766b3d8..144730a 100644 +++ b/src/gui/kernel/qscreen.h @@ -81,7 +81,6 @@ class Q_GUI_EXPORT QScreen : public QObject Q_PROPERTY(qreal refreshRate READ refreshRate NOTIFY refreshRateChanged) - + public: - ~QScreen(); QPlatformScreen *handle() const; - + QString name() const; diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp -index f56a29d..0dca2da 100644 +index 4b6caa9..4c2be75 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -276,7 +276,7 @@ QXcbClipboard::QXcbClipboard(QXcbConnection *c) m_timestamp[QClipboard::Clipboard] = XCB_CURRENT_TIME; m_timestamp[QClipboard::Selection] = XCB_CURRENT_TIME; - + - m_screen = connection()->primaryScreen(); + QXcbScreen * screen = connection()->primaryScreen(); - + int x = 0, y = 0, w = 3, h = 3; - + @@ -284,11 +284,11 @@ QXcbClipboard::QXcbClipboard(QXcbConnection *c) Q_XCB_CALL(xcb_create_window(xcb_connection(), XCB_COPY_FROM_PARENT, // depth -- same as root @@ -135,7 +135,7 @@ index f56a29d..0dca2da 100644 @@ -462,8 +462,15 @@ bool QXcbClipboard::ownsMode(QClipboard::Mode mode) const return m_timestamp[mode] != XCB_CURRENT_TIME; } - + +QXcbScreen *QXcbClipboard::screen() const +{ + return connection()->primaryScreen(); @@ -169,23 +169,23 @@ index e76d502..b6cbda4 100644 @@ -59,7 +59,7 @@ public: bool supportsMode(QClipboard::Mode mode) const; bool ownsMode(QClipboard::Mode mode) const; - + - QXcbScreen *screen() const { return m_screen; } + QXcbScreen *screen() const; - + xcb_window_t requestor() const; void setRequestor(xcb_window_t window); @@ -91,8 +91,6 @@ private: xcb_atom_t atomForMode(QClipboard::Mode mode) const; QClipboard::Mode modeForAtom(xcb_atom_t atom) const; - + - QXcbScreen *m_screen; - // Selection and Clipboard QXcbClipboardMime *m_xClipboard[2]; QMimeData *m_clientClipboard[2]; diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp -index 5510c3b..c9600f0 100644 +index 77e4601..a2177d2 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -182,7 +182,6 @@ QXcbScreen* QXcbConnection::findOrCreateScreen(QList& newScreens, @@ -234,7 +234,7 @@ index 5510c3b..c9600f0 100644 @@ -279,28 +277,39 @@ void QXcbConnection::updateScreens() ++xcbScreenNumber; } // for each xcb screen - + - // Now activeScreens is the complete set of screens which are active at this time. - // Delete any existing screens which are not in activeScreens + // Rebuild screen list, ensuring primary screen is always in front, @@ -252,7 +252,7 @@ index 5510c3b..c9600f0 100644 + screensToDelete.append(m_screens.takeAt(i)); } } - + - // Add any new screens, and make sure the primary screen comes first - // since it is used by QGuiApplication::primaryScreen() + // If there is a new primary screen, add that one first @@ -272,7 +272,7 @@ index 5510c3b..c9600f0 100644 + m_screens.append(screen); + ((QXcbIntegration*)QGuiApplicationPrivate::platformIntegration())->screenAdded(screen); } - + - // Now that they are in the right order, emit the added signals for new screens only - foreach (QXcbScreen* screen, m_screens) - if (newScreens.contains(screen)) @@ -283,10 +283,10 @@ index 5510c3b..c9600f0 100644 + delete screen; + } } - + QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp -index 0094278..44d33e1 100644 +index c0076a9..abb945c 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -257,9 +257,7 @@ QXcbWindow::QXcbWindow(QWindow *window) @@ -297,13 +297,13 @@ index 0094278..44d33e1 100644 - - setConnection(m_screen->connection()); + setConnection(xcbscreen()->connection()); - + if (window->type() != Qt::ForeignWindow) create(); @@ -298,11 +296,13 @@ void QXcbWindow::create() - + Qt::WindowType type = window()->type(); - + + QXcbScreen* screen = this->xcbscreen(); + if (type == Qt::Desktop) { @@ -318,16 +318,16 @@ index 0094278..44d33e1 100644 m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask); connection()->addWindowEventListener(m_window, this); return; -@@ -343,7 +343,7 @@ void QXcbWindow::create() +@@ -338,7 +338,7 @@ void QXcbWindow::create() rect.setHeight(defaultWindowHeight); } - + - xcb_window_t xcb_parent_id = m_screen->root(); + xcb_window_t xcb_parent_id = screen->root(); if (parent()) { xcb_parent_id = static_cast(parent())->xcb_window(); m_embedded = parent()->window()->type() == Qt::ForeignWindow; -@@ -358,7 +358,7 @@ void QXcbWindow::create() +@@ -353,7 +353,7 @@ void QXcbWindow::create() #if (defined(XCB_USE_GLX) || defined(XCB_USE_EGL)) && defined(XCB_USE_XLIB) if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) { #if defined(XCB_USE_GLX) @@ -336,18 +336,18 @@ index 0094278..44d33e1 100644 #elif defined(XCB_USE_EGL) EGLDisplay eglDisplay = connection()->egl_display(); EGLConfig eglConfig = q_configFromGLFormat(eglDisplay, m_format, true); -@@ -387,8 +387,8 @@ void QXcbWindow::create() +@@ -382,8 +382,8 @@ void QXcbWindow::create() Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), xcb_parent_id, visualInfo->visual, AllocNone); - + XSetWindowAttributes a; - a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber()); - a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber()); + a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(this), screen->screenNumber()); + a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(this), screen->screenNumber()); a.colormap = cmap; - + m_visualId = visualInfo->visualid; -@@ -407,14 +407,14 @@ void QXcbWindow::create() +@@ -402,14 +402,14 @@ void QXcbWindow::create() #endif //defined(XCB_USE_GLX) || defined(XCB_USE_EGL) { m_window = xcb_generate_id(xcb_connection()); @@ -355,17 +355,17 @@ index 0094278..44d33e1 100644 - m_depth = m_screen->screen()->root_depth; + m_visualId = screen->screen()->root_visual; + m_depth = screen->screen()->root_depth; - + uint32_t mask = 0; uint32_t values[3]; - + if (m_format.alphaBufferSize() == 8) { - xcb_depth_iterator_t depthIter = xcb_screen_allowed_depths_iterator(m_screen->screen()); + xcb_depth_iterator_t depthIter = xcb_screen_allowed_depths_iterator(screen->screen()); while (depthIter.rem) { if (depthIter.data->depth == 32) { xcb_visualtype_iterator_t visualIter = xcb_depth_visuals_iterator(depthIter.data); -@@ -425,8 +425,8 @@ void QXcbWindow::create() +@@ -420,8 +420,8 @@ void QXcbWindow::create() xcb_create_colormap(xcb_connection(), XCB_COLORMAP_ALLOC_NONE, colormap, xcb_parent_id, m_visualId); mask |= XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP; @@ -376,43 +376,43 @@ index 0094278..44d33e1 100644 values[2] = colormap; break; } -@@ -435,7 +435,7 @@ void QXcbWindow::create() +@@ -430,7 +430,7 @@ void QXcbWindow::create() } } - + - const xcb_visualtype_t *visual = m_screen->visualForId(m_visualId); + const xcb_visualtype_t *visual = screen->visualForId(m_visualId); m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask); - + Q_XCB_CALL(xcb_create_window(xcb_connection(), -@@ -465,7 +465,7 @@ void QXcbWindow::create() +@@ -460,7 +460,7 @@ void QXcbWindow::create() properties[propertyCount++] = atom(QXcbAtom::WM_TAKE_FOCUS); properties[propertyCount++] = atom(QXcbAtom::_NET_WM_PING); - + - m_usingSyncProtocol = m_screen->syncRequestSupported(); + m_usingSyncProtocol = screen->syncRequestSupported(); #if !defined(XCB_USE_GLX) // synced resize only implemented on GLX if (window()->supportsOpenGL()) -@@ -524,7 +524,7 @@ void QXcbWindow::create() - +@@ -519,7 +519,7 @@ void QXcbWindow::create() + xcb_set_wm_hints(xcb_connection(), m_window, &hints); - + - xcb_window_t leader = m_screen->clientLeader(); + xcb_window_t leader = screen->clientLeader(); Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, atom(QXcbAtom::WM_CLIENT_LEADER), XCB_ATOM_WINDOW, 32, 1, &leader)); -@@ -550,7 +550,7 @@ void QXcbWindow::create() - +@@ -545,7 +545,7 @@ void QXcbWindow::create() + #ifdef XCB_USE_XLIB // force sync to read outstanding requests - see QTBUG-29106 - XSync(DISPLAY_FROM_XCB(m_screen), false); + XSync(DISPLAY_FROM_XCB(screen), false); #endif - + #ifndef QT_NO_DRAGANDDROP -@@ -744,7 +744,7 @@ void QXcbWindow::show() +@@ -742,7 +742,7 @@ void QXcbWindow::show() // Default to client leader if there is no transient parent, else modal dialogs can // be hidden by their parents. if (!transientXcbParent) @@ -421,16 +421,16 @@ index 0094278..44d33e1 100644 if (transientXcbParent) { // ICCCM 4.1.2.6 Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32, -@@ -772,7 +772,7 @@ void QXcbWindow::show() +@@ -773,7 +773,7 @@ void QXcbWindow::show() if (QGuiApplication::modalWindow() == window()) requestActivateWindow(); - + - m_screen->windowShown(this); + xcbscreen()->windowShown(this); - + connection()->sync(); } -@@ -784,10 +784,10 @@ void QXcbWindow::hide() +@@ -785,10 +785,10 @@ void QXcbWindow::hide() // send synthetic UnmapNotify event according to icccm 4.1.4 xcb_unmap_notify_event_t event; event.response_type = XCB_UNMAP_NOTIFY; @@ -441,27 +441,27 @@ index 0094278..44d33e1 100644 - Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_screen->root(), + Q_XCB_CALL(xcb_send_event(xcb_connection(), false, xcbscreen()->root(), XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event)); - + xcb_flush(xcb_connection()); -@@ -1107,7 +1107,7 @@ void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two) +@@ -1108,7 +1108,7 @@ void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two) event.data.data32[3] = 0; event.data.data32[4] = 0; - + - Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event)); + Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, xcbscreen()->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event)); } - + void QXcbWindow::setWindowState(Qt::WindowState state) -@@ -1148,7 +1148,7 @@ void QXcbWindow::setWindowState(Qt::WindowState state) +@@ -1149,7 +1149,7 @@ void QXcbWindow::setWindowState(Qt::WindowState state) event.data.data32[3] = 0; event.data.data32[4] = 0; - + - Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event)); + Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, xcbscreen()->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event)); } break; case Qt::WindowMaximized: -@@ -1391,7 +1391,7 @@ void QXcbWindow::setParent(const QPlatformWindow *parent) +@@ -1392,7 +1392,7 @@ void QXcbWindow::setParent(const QPlatformWindow *parent) xcb_parent_id = qXcbParent->xcb_window(); m_embedded = qXcbParent->window()->type() == Qt::ForeignWindow; } else { @@ -470,35 +470,35 @@ index 0094278..44d33e1 100644 m_embedded = false; } Q_XCB_CALL(xcb_reparent_window(xcb_connection(), xcb_window(), xcb_parent_id, topLeft.x(), topLeft.y())); -@@ -1559,7 +1559,7 @@ void QXcbWindow::requestActivateWindow() +@@ -1560,7 +1560,7 @@ void QXcbWindow::requestActivateWindow() event.data.data32[3] = 0; event.data.data32[4] = 0; - + - Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event)); + Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, xcbscreen()->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event)); } else { Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, connection()->time())); } -@@ -1796,15 +1796,15 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even +@@ -1797,15 +1797,15 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even relayFocusToModalWindow(); return; } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_PING)) { - if (event->window == m_screen->root()) + if (event->window == xcbscreen()->root()) return; - + xcb_client_message_event_t reply = *event; - + reply.response_type = XCB_CLIENT_MESSAGE; - reply.window = m_screen->root(); + reply.window = xcbscreen()->root(); - + - xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&reply); + xcb_send_event(xcb_connection(), 0, xcbscreen()->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&reply); xcb_flush(xcb_connection()); } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_SYNC_REQUEST)) { connection()->setTime(event->data.data32[1]); -@@ -1871,7 +1871,7 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * +@@ -1872,7 +1872,7 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * if (!parent() && !fromSendEvent) { // Do not trust the position, query it instead. xcb_translate_coordinates_cookie_t cookie = xcb_translate_coordinates(xcb_connection(), xcb_window(), @@ -507,9 +507,9 @@ index 0094278..44d33e1 100644 xcb_translate_coordinates_reply_t *reply = xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL); if (reply) { pos.setX(reply->dst_x); -@@ -1888,8 +1888,7 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * +@@ -1889,8 +1889,7 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * QWindowSystemInterface::handleGeometryChange(window(), rect); - + QPlatformScreen *newScreen = screenForNativeGeometry(nativeRect); - if (newScreen != m_screen) { - m_screen = static_cast(newScreen); @@ -517,7 +517,7 @@ index 0094278..44d33e1 100644 QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); int newDpr = devicePixelRatio(); if (newDpr != dpr) { -@@ -1933,7 +1932,7 @@ QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const +@@ -1934,7 +1933,7 @@ QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const const int dpr = int(devicePixelRatio()); QPoint ret; xcb_translate_coordinates_cookie_t cookie = @@ -526,7 +526,7 @@ index 0094278..44d33e1 100644 pos.x() * dpr, pos.y() * dpr); xcb_translate_coordinates_reply_t *reply = xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL); -@@ -1954,7 +1953,7 @@ QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const +@@ -1955,7 +1954,7 @@ QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const const int dpr = int(devicePixelRatio()); QPoint ret; xcb_translate_coordinates_cookie_t cookie = @@ -535,7 +535,7 @@ index 0094278..44d33e1 100644 pos.x() *dpr, pos.y() * dpr); xcb_translate_coordinates_reply_t *reply = xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL); -@@ -2178,8 +2177,8 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev +@@ -2179,8 +2178,8 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev m_windowState = newState; } return; @@ -545,8 +545,8 @@ index 0094278..44d33e1 100644 + xcbscreen()->updateGeometry(event->time); } } - -@@ -2308,7 +2307,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) + +@@ -2309,7 +2308,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) xev.data.data32[3] = XCB_BUTTON_INDEX_1; xev.data.data32[4] = 0; xcb_ungrab_pointer(connection()->xcb_connection(), XCB_CURRENT_TIME); @@ -555,7 +555,16 @@ index 0094278..44d33e1 100644 XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY, (const char *)&xev); return true; -@@ -2444,13 +2443,18 @@ void QXcbWindow::postSyncWindowRequest() +@@ -2354,7 +2353,7 @@ void QXcbWindow::handleXEmbedMessage(const xcb_client_message_event_t *event) + break; + case XEMBED_EMBEDDED_NOTIFY: + Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window)); +- m_screen->windowShown(this); ++ xcbscreen()->windowShown(this); + break; + case XEMBED_FOCUS_IN: + Qt::FocusReason reason; +@@ -2448,13 +2447,18 @@ void QXcbWindow::postSyncWindowRequest() if (!m_pendingSyncRequest) { QXcbSyncWindowRequest *e = new QXcbSyncWindowRequest(this); m_pendingSyncRequest = e; @@ -563,7 +572,7 @@ index 0094278..44d33e1 100644 + QCoreApplication::postEvent(xcbscreen()->connection(), e); } } - + qreal QXcbWindow::devicePixelRatio() const { - return m_screen ? m_screen->devicePixelRatio() : 1.0; @@ -574,7 +583,7 @@ index 0094278..44d33e1 100644 +{ + return static_cast(screen()); } - + QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 254421e..966a834 100644 @@ -583,18 +592,18 @@ index 254421e..966a834 100644 @@ -152,6 +152,8 @@ public: void postSyncWindowRequest(); void clearSyncWindowRequest() { m_pendingSyncRequest = 0; } - + + QXcbScreen *xcbscreen() const; + qreal devicePixelRatio() const; - + QPlatformScreen *screenForNativeGeometry(const QRect &newGeometry) const; @@ -188,8 +190,6 @@ private: void doFocusIn(); void doFocusOut(); - + - QXcbScreen *m_screen; - xcb_window_t m_window; - + uint m_depth; diff --git a/sources b/sources index 9a43291..7f2ec34 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -9507825e558c980fed602de1f16ec7ae qtbase-opensource-src-5.4.1.tar.xz +67a95eec79ffc4a14f516ad6f3d24c96 qtbase-opensource-src-5.4.2.tar.xz