Update to 5.4.2
This commit is contained in:
parent
e3d6eaa8b3
commit
17a4ff4a15
|
@ -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
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
From 7fc8c560e21e7175b1fe33c988f3f30e4b326efe Mon Sep 17 00:00:00 2001
|
||||
From: David Faure <david.faure@kdab.com>
|
||||
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 <Friedemann.Kleint@theqtcompany.com>
|
||||
Reviewed-by: Andy Shaw <andy.shaw@digia.com>
|
||||
---
|
||||
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
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
From 890ae41d0601d20505df2f955a99d0238bf4f59e Mon Sep 17 00:00:00 2001
|
||||
From: Pierre Rossi <pierre.rossi@theqtcompany.com>
|
||||
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 <simon.hausmann@digia.com>
|
||||
---
|
||||
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
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
From 9718cb330cb479ec6e91f1f10c5ee9097fa2f4fb Mon Sep 17 00:00:00 2001
|
||||
From: Albert Astals Cid <albert.astals@canonical.com>
|
||||
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 <simon.hausmann@theqtcompany.com>
|
||||
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
|
||||
---
|
||||
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
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
From 0d990b9ca117514fe83f53b39f25d6272304f2fb Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?K=C3=A5re=20S=C3=A4rs?= <kare.sars@iki.fi>
|
||||
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 <aleixpol@kde.org>
|
||||
Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
||||
---
|
||||
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<int> 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<int> 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<int> 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
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
From 8d6341a721d07e3cc30032bcc89f7e25cb00b9eb Mon Sep 17 00:00:00 2001
|
||||
From: Albert Astals Cid <aacid@kde.org>
|
||||
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 <alexander.blasche@theqtcompany.com>
|
||||
---
|
||||
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
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
From 8fccfef424e7d2b7a2019b1f828234145d4011df Mon Sep 17 00:00:00 2001
|
||||
From: Albert Astals Cid <albert.astals@canonical.com>
|
||||
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 <michael.bruning@theqtcompany.com>
|
||||
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@theqtcompany.com>
|
||||
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
|
||||
---
|
||||
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 <QGraphicsView *> 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 <QGraphicsView *> views = d->extra->proxyWidget->scene()->views();
|
||||
if (!views.isEmpty()) {
|
||||
const QPoint viewPortPos = views.first()->viewport()->mapFromGlobal(pos);
|
||||
--
|
||||
1.9.3
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
From f58e882b7594c59b6050d3c87562fcf836d10f60 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Goffart <ogoffart@woboq.com>
|
||||
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 <david.faure@kdab.com>
|
||||
---
|
||||
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
|
||||
|
|
@ -1,692 +0,0 @@
|
|||
From cff39fba10ffc10ee4dcfdc66ff6528eb26462d3 Mon Sep 17 00:00:00 2001
|
||||
From: Markus Goetz <markus@woboq.com>
|
||||
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 <peter-qt@hartmann.tk>
|
||||
---
|
||||
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<QRingBuffer> 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<QRingBuffer> 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<QSslError>)),
|
||||
this, SLOT(_q_sslErrors(QList<QSslError>)),
|
||||
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<QHttpNetworkRequest, QHttpNetworkReply*> 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<QNonContiguousByteDevice> uploadByteDevice;
|
||||
+ qint64 uploadByteDevicePosition;
|
||||
bool uploadDeviceChoking; // if we couldn't readPointer() any data at the moment
|
||||
QIODevice *outgoingData;
|
||||
QSharedPointer<QRingBuffer> 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<QSslError>)), 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<QSslError>)), 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<QSslError>)), 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=" <<numUploads;
|
||||
+
|
||||
+ // Sanity check because ecause of 9c2ecf89 most replies will error out but we want to make sure at least some of them worked
|
||||
+ QVERIFY(server.m_correctUploads > 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
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
From 3eca75de67b3fd2c890715b30c7899cebc096fe9 Mon Sep 17 00:00:00 2001
|
||||
From: Thiago Macieira <thiago.macieira@intel.com>
|
||||
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 <mitya57@gmail.com>
|
||||
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
|
||||
---
|
||||
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
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
From 36d6eb721e7d5997ade75e289d4088dc48678d0d Mon Sep 17 00:00:00 2001
|
||||
From: Thiago Macieira <thiago.macieira@intel.com>
|
||||
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 <simon.hausmann@theqtcompany.com>
|
||||
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
|
||||
---
|
||||
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
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
From 083c9269ed73e8771e1dbe10812696b45b7389f3 Mon Sep 17 00:00:00 2001
|
||||
From: Evangelos Foutras <evangelos@foutrelis.com>
|
||||
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 <thiago.macieira@intel.com>
|
||||
---
|
||||
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
|
||||
|
|
@ -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 <jgrulich@redhat.com> 5.4.2-1
|
||||
- Update to 5.4.2
|
||||
|
||||
* Tue May 26 2015 Rex Dieter <rdieter@fedoraproject.org> 5.4.1-20
|
||||
- SM_CLIENT_ID property is not set (QTBUG-46310)
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ index 39b031e..7f808da 100644
|
|||
@@ -429,16 +429,40 @@ QList<int> 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<QXcbScreen *>& 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<QXcbWindow *>(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<QXcbScreen*>(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<QXcbScreen *>(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;
|
||||
|
|
Loading…
Reference in New Issue