From 0261c22d41ed7be5adb5bab8a8ae4ee3c10968e9 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 20 Oct 2017 18:01:11 +0700 Subject: Add menu creation manual test We have found that there are three important operations when it comes to menu creation and putting it up in the native menubar: * Adding the action to its parent menu * Setting the submenu as the action's menu * Populating the actual submenu This application tests all possible permutations for these three operations, starting from the menubar and down two more menu levels. Two command-line options allow, first, to create a late menubar that will replace the original menubar from the main window form (--new-menubar) with, second, the option of creating it parentless (--no-parent) before setting it as the new main window menubar. While mostly interesting for platforms supporting QPA menus and menubars, this could be useful as a trivial check for QMenu and QMenuBar in a pure QWidget environment. As of today, the application shows at least three issues on macOS which will be fixed in upcoming patches. Change-Id: Id3c1e0f346c6fe27ab4656ff045b88a0a8623740 Reviewed-by: Shawn Rutledge --- .../widgets/bigmenucreator/bigmenucreator.pro | 34 +++++ .../manual/widgets/widgets/bigmenucreator/main.cpp | 54 ++++++++ .../widgets/widgets/bigmenucreator/mainwindow.cpp | 139 +++++++++++++++++++++ .../widgets/widgets/bigmenucreator/mainwindow.h | 63 ++++++++++ .../widgets/widgets/bigmenucreator/mainwindow.ui | 74 +++++++++++ 5 files changed, 364 insertions(+) create mode 100644 tests/manual/widgets/widgets/bigmenucreator/bigmenucreator.pro create mode 100644 tests/manual/widgets/widgets/bigmenucreator/main.cpp create mode 100644 tests/manual/widgets/widgets/bigmenucreator/mainwindow.cpp create mode 100644 tests/manual/widgets/widgets/bigmenucreator/mainwindow.h create mode 100644 tests/manual/widgets/widgets/bigmenucreator/mainwindow.ui diff --git a/tests/manual/widgets/widgets/bigmenucreator/bigmenucreator.pro b/tests/manual/widgets/widgets/bigmenucreator/bigmenucreator.pro new file mode 100644 index 0000000000..69fbea3834 --- /dev/null +++ b/tests/manual/widgets/widgets/bigmenucreator/bigmenucreator.pro @@ -0,0 +1,34 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2017-10-19T16:07:04 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = BigMenuCreator +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which as been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + main.cpp \ + mainwindow.cpp + +HEADERS += \ + mainwindow.h + +FORMS += \ + mainwindow.ui diff --git a/tests/manual/widgets/widgets/bigmenucreator/main.cpp b/tests/manual/widgets/widgets/bigmenucreator/main.cpp new file mode 100644 index 0000000000..303552c1d5 --- /dev/null +++ b/tests/manual/widgets/widgets/bigmenucreator/main.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mainwindow.h" +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + QCommandLineParser parser; + parser.setApplicationDescription("BigMenuCreator"); + parser.addHelpOption(); + parser.addOptions({ + { "new-menubar", QLatin1String("Use new menubar instead of QMainWindow's own.") }, + { "no-parent", QLatin1String("When using a new menubar, do *not* set its parent on construction.") } + }); + + parser.process(a); + + MainWindow::newMenubar = parser.isSet("new-menubar"); + MainWindow::parentlessMenubar = parser.isSet("no-parent"); + + MainWindow w; + w.show(); + + return a.exec(); +} diff --git a/tests/manual/widgets/widgets/bigmenucreator/mainwindow.cpp b/tests/manual/widgets/widgets/bigmenucreator/mainwindow.cpp new file mode 100644 index 0000000000..5b30c1be0b --- /dev/null +++ b/tests/manual/widgets/widgets/bigmenucreator/mainwindow.cpp @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mainwindow.h" +#include "ui_mainwindow.h" + +bool MainWindow::newMenubar = false; +bool MainWindow::parentlessMenubar = false; + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + ui->setupUi(this); + + const int level = 3; + QMenuBar *mb; + if (newMenubar) + mb = new QMenuBar(parentlessMenubar ? nullptr : this); + else + mb = ui->menuBar; + populateMenu(mb, level); + if (newMenubar) + setMenuBar(mb); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +// We do all the permutations on the following 3 operations: +// +// A: Add action to parent menu +// P: Populate the submenu +// S: Set action submenu +// +// Recursing on menu population gives more combinations of +// creation and insertions. + +void MainWindow::populateMenu(QWidget *menu, int level) +{ + if (level > 0) { + --level; + doAPS(menu, level); + doASP(menu, level); + doPAS(menu, level); + doSPA(menu, level); + doSAP(menu, level); + doPSA(menu, level); + } else { + static int itemCounter = 0; + static const char *sym[] = { "Foo", "Bar", "Baz", "Quux" }; + for (uint i = 0; i < sizeof(sym) / sizeof(sym[0]); i++) { + QString title = QString::fromLatin1("%1 Item %2").arg(QLatin1String(sym[i])).arg(itemCounter); + menu->addAction(new QAction(title)); + } + ++itemCounter; + } +} + +void MainWindow::doAPS(QWidget *menu, int level) +{ + auto *action = new QAction("A P S"); + menu->addAction(action); + auto *submenu = new QMenu; + populateMenu(submenu, level); + action->setMenu(submenu); +} + +void MainWindow::doASP(QWidget *menu, int level) +{ + auto *action = new QAction("A S P"); + menu->addAction(action); + auto *submenu = new QMenu; + action->setMenu(submenu); + populateMenu(submenu, level); +} + +void MainWindow::doPAS(QWidget *menu, int level) +{ + auto *submenu = new QMenu; + populateMenu(submenu, level); + auto *action = new QAction("P A S"); + menu->addAction(action); + action->setMenu(submenu); +} + +void MainWindow::doSPA(QWidget *menu, int level) +{ + auto *action = new QAction("S P A"); + auto *submenu = new QMenu; + action->setMenu(submenu); + populateMenu(submenu, level); + menu->addAction(action); +} + +void MainWindow::doSAP(QWidget *menu, int level) +{ + auto *action = new QAction("S A P"); + auto *submenu = new QMenu; + action->setMenu(submenu); + menu->addAction(action); + populateMenu(submenu, level); +} + +void MainWindow::doPSA(QWidget *menu, int level) +{ + auto *action = new QAction("P S A"); + auto *submenu = new QMenu; + populateMenu(submenu, level); + action->setMenu(submenu); + menu->addAction(action); +} diff --git a/tests/manual/widgets/widgets/bigmenucreator/mainwindow.h b/tests/manual/widgets/widgets/bigmenucreator/mainwindow.h new file mode 100644 index 0000000000..2990f592e9 --- /dev/null +++ b/tests/manual/widgets/widgets/bigmenucreator/mainwindow.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +namespace Ui { +class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + + void doAPS(QWidget *menu, int level); + void doASP(QWidget *menu, int level); + void doPAS(QWidget *menu, int level); + + void doSPA(QWidget *menu, int level); + void doSAP(QWidget *menu, int level); + void doPSA(QWidget *menu, int level); + + void populateMenu(QWidget *menu, int level); + + static bool newMenubar; + static bool parentlessMenubar; + +private: + Ui::MainWindow *ui; +}; + +#endif // MAINWINDOW_H diff --git a/tests/manual/widgets/widgets/bigmenucreator/mainwindow.ui b/tests/manual/widgets/widgets/bigmenucreator/mainwindow.ui new file mode 100644 index 0000000000..0668202ea5 --- /dev/null +++ b/tests/manual/widgets/widgets/bigmenucreator/mainwindow.ui @@ -0,0 +1,74 @@ + + + MainWindow + + + + 0 + 0 + 427 + 372 + + + + MainWindow + + + + + + + + 16 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'.SF NS Text'; font-size:16pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt;">We do all the permutations on the following 3 operations:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:14pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt; font-weight:600;"> A</span><span style=" font-size:14pt;">: Add action to parent menu</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt; font-weight:600;"> P</span><span style=" font-size:14pt;">: Populate the submenu</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt; font-weight:600;"> S</span><span style=" font-size:14pt;">: Set action submenu</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:14pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt;">This gets repeated 2 menu levels from the menubar. All menus and items are enabled and should show as such.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:14pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt;">The order of menus is APS, ASP, PAS, SPA, SAP, PSA.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:14pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt;">The order of terminal items is &quot;Foo&quot;, &quot;Bar&quot;, &quot;Baz&quot;, &quot;Quux&quot;.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:14pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt;">Rerun with &quot;--new-menubar&quot; and &quot;--no-parent&quot; to force using a new menubar instead of QMainWindow's own, with or without parent. QMainWindow::setMenuBar() will be called regardless of the parent option.</span></p></body></html> + + + true + + + + + + + + + 0 + 0 + 427 + 22 + + + + + + TopToolBarArea + + + false + + + + + + + + -- cgit v1.2.3 From 7c5475f1c03a4b9d6c023bc7ff937e1fc2f62271 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Thu, 19 Oct 2017 10:07:50 +0200 Subject: Doc: add hint about QMimeDatabase to QImageReader::canRead() Task-number: QTBUG-63568 Change-Id: I5b700138487dbebfc8cbe70eb3a076efceafb361 Reviewed-by: Venugopal Shivashankar --- src/gui/image/qimagereader.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 381ddb5b45..f49e90ba0a 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -1211,10 +1211,13 @@ float QImageReader::gamma() const see if the image data is valid. read() may still return false after canRead() returns \c true, if the image data is corrupt. + \note A QMimeDatabase lookup is normally a better approach than this + function for identifying potentially non-image files or data. + For images that support animation, canRead() returns \c false when all frames have been read. - \sa read(), supportedImageFormats() + \sa read(), supportedImageFormats(), QMimeDatabase */ bool QImageReader::canRead() const { -- cgit v1.2.3 From 7944423bfaec48e5c7642a042bede1557b1beff2 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 19 Oct 2017 09:36:15 +0200 Subject: Add clarifying documentation for QLayout::removeWidget() Change-Id: I6c256c6c5cdfed6ceb45758d708fdc8f74d2939f Reviewed-by: Leena Miettinen --- src/widgets/kernel/qlayout.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index 1e455b0d64..f3db4f4e2d 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -1350,7 +1350,8 @@ QRect QLayout::alignmentRect(const QRect &r) const /*! Removes the widget \a widget from the layout. After this call, it is the caller's responsibility to give the widget a reasonable - geometry or to put the widget back into a layout. + geometry or to put the widget back into a layout or to explicitly + hide it if necessary. \b{Note:} The ownership of \a widget remains the same as when it was added. -- cgit v1.2.3 From 7e7683cabb8df58097c5bc4638a2e08cf6e6ff71 Mon Sep 17 00:00:00 2001 From: Yulong Bai Date: Tue, 17 Oct 2017 14:41:42 +0200 Subject: QAction: fix ::setData() always emits changed() QAction::setData() always emits changed() even without actual data change. Original code lacks a guard to check if the data changes. According to http://doc.qt.io/qt-4.8/signalsandslots.html, adding guard also benefits to prevent infinite looping in case of cyclic connections. Task-number: QTBUG-62006 Change-Id: I776369b668082f9f02e4502a36b1ae234ee7e079 Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qaction.cpp | 2 ++ tests/auto/widgets/kernel/qaction/tst_qaction.cpp | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/widgets/kernel/qaction.cpp b/src/widgets/kernel/qaction.cpp index f1788bb3f4..7754defaac 100644 --- a/src/widgets/kernel/qaction.cpp +++ b/src/widgets/kernel/qaction.cpp @@ -1118,6 +1118,8 @@ void QAction::setData(const QVariant &data) { Q_D(QAction); + if (d->userData == data) + return; d->userData = data; d->sendDataChanged(); } diff --git a/tests/auto/widgets/kernel/qaction/tst_qaction.cpp b/tests/auto/widgets/kernel/qaction/tst_qaction.cpp index 83e1850524..3535e465b3 100644 --- a/tests/auto/widgets/kernel/qaction/tst_qaction.cpp +++ b/tests/auto/widgets/kernel/qaction/tst_qaction.cpp @@ -62,6 +62,7 @@ private slots: void task229128TriggeredSignalWithoutActiongroup(); void task229128TriggeredSignalWhenInActiongroup(); void repeat(); + void setData(); private: int m_lastEventType; @@ -408,5 +409,20 @@ void tst_QAction::repeat() QCOMPARE(spy.count(), 2); } +void tst_QAction::setData() // QTBUG-62006 +{ + QAction act(nullptr); + QSignalSpy spy(&act, &QAction::changed); + QCOMPARE(act.data(), QVariant()); + QCOMPARE(spy.count(), 0); + act.setData(QVariant()); + QCOMPARE(spy.count(), 0); + + act.setData(-1); + QCOMPARE(spy.count(), 1); + act.setData(-1); + QCOMPARE(spy.count(), 1); +} + QTEST_MAIN(tst_QAction) #include "tst_qaction.moc" -- cgit v1.2.3 From 18f0a45964e62bf3db7b657847902a356fd31f51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 19 Oct 2017 12:22:16 +0200 Subject: Fix redirecting all the other methods for HTTP 307 and 308 c4cf90b1f739c47383672de3d66b1d9d5427f5db made POST requests be redirected properly, but this wasn't enough and should have included every method/verb. Change-Id: I37b12dc9fdffcbf2aadbd2360d4fc2584c024939 Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- src/network/access/qnetworkreplyhttpimpl.cpp | 10 ++- .../access/qnetworkreply/tst_qnetworkreply.cpp | 83 ++++++++++++++++++---- 2 files changed, 73 insertions(+), 20 deletions(-) diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index fa49c8e05b..c1a9f628a0 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1110,16 +1110,14 @@ QNetworkAccessManager::Operation QNetworkReplyHttpImplPrivate::getRedirectOperat // HTTP status code can be used to decide if we can redirect with a GET // operation or not. See http://www.ietf.org/rfc/rfc2616.txt [Sec 10.3] for // more details - Q_UNUSED(httpStatus); + + // We MUST keep using the verb that was used originally when being redirected with 307 or 308. + if (httpStatus == 307 || httpStatus == 308) + return currentOp; switch (currentOp) { case QNetworkAccessManager::HeadOperation: return QNetworkAccessManager::HeadOperation; - case QNetworkAccessManager::PostOperation: - // We MUST keep using POST when being redirected with 307 or 308. - if (statusCode == 307 || statusCode == 308) - return QNetworkAccessManager::PostOperation; - break; default: break; } diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index d22850ba4e..93afca3d48 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -491,10 +491,12 @@ private Q_SLOTS: void ioHttpRedirect_data(); void ioHttpRedirect(); void ioHttpRedirectFromLocalToRemote(); - void ioHttpRedirectPost_data(); - void ioHttpRedirectPost(); + void ioHttpRedirectPostPut_data(); + void ioHttpRedirectPostPut(); void ioHttpRedirectMultipartPost_data(); void ioHttpRedirectMultipartPost(); + void ioHttpRedirectDelete(); + void ioHttpRedirectCustom(); #ifndef QT_NO_SSL void putWithServerClosingConnectionImmediately(); #endif @@ -546,7 +548,7 @@ static void setupSslServer(QSslSocket* serverSocket) } #endif -// Does not work for PUT! Limited support for POST. +// Limited support for POST and PUT. class MiniHttpServer: public QTcpServer { Q_OBJECT @@ -678,7 +680,7 @@ public slots: if (doubleEndlPos != -1) { const int endOfHeader = doubleEndlPos + 4; - hasContent = receivedData.startsWith("POST"); + hasContent = receivedData.startsWith("POST") || receivedData.startsWith("PUT"); if (hasContent && contentLength == 0) parseContentLength(); contentRead = receivedData.length() - endOfHeader; @@ -8546,37 +8548,46 @@ void tst_QNetworkReply::ioHttpRedirectFromLocalToRemote() QCOMPARE(reply->readAll(), reference.readAll()); } -void tst_QNetworkReply::ioHttpRedirectPost_data() +void tst_QNetworkReply::ioHttpRedirectPostPut_data() { + QTest::addColumn("usePost"); QTest::addColumn("status"); QTest::addColumn("data"); QTest::addColumn("contentType"); QByteArray data; data = "hello world"; - QTest::addRow("307") << "307 Temporary Redirect" << data << "text/plain"; + QTest::addRow("post-307") << true << "307 Temporary Redirect" << data << "text/plain"; + QTest::addRow("put-307") << false << "307 Temporary Redirect" << data << "text/plain"; QString permanentRedirect = "308 Permanent Redirect"; - QTest::addRow("308") << permanentRedirect << data << "text/plain"; + QTest::addRow("post-308") << true << permanentRedirect << data << "text/plain"; + QTest::addRow("put-308") << false << permanentRedirect << data << "text/plain"; // Some data from ::putToFile_data data = ""; - QTest::newRow("empty") << permanentRedirect << data << "application/octet-stream"; + QTest::newRow("post-empty") << true << permanentRedirect << data << "application/octet-stream"; + QTest::newRow("put-empty") << false << permanentRedirect << data << "application/octet-stream"; data = QByteArray("abcd\0\1\2\abcd",12); - QTest::newRow("with-nul") << permanentRedirect << data << "application/octet-stream"; + QTest::newRow("post-with-nul") << true << permanentRedirect << data << "application/octet-stream"; + QTest::newRow("put-with-nul") << false << permanentRedirect << data << "application/octet-stream"; data = QByteArray(4097, '\4'); - QTest::newRow("4k+1") << permanentRedirect << data << "application/octet-stream"; + QTest::newRow("post-4k+1") << true << permanentRedirect << data << "application/octet-stream"; + QTest::newRow("put-4k+1") << false << permanentRedirect << data << "application/octet-stream"; data = QByteArray(128*1024+1, '\177'); - QTest::newRow("128k+1") << permanentRedirect << data << "application/octet-stream"; + QTest::newRow("post-128k+1") << true << permanentRedirect << data << "application/octet-stream"; + QTest::newRow("put-128k+1") << false << permanentRedirect << data << "application/octet-stream"; data = QByteArray(2*1024*1024+1, '\177'); - QTest::newRow("2MB+1") << permanentRedirect << data << "application/octet-stream"; + QTest::newRow("post-2MB+1") << true << permanentRedirect << data << "application/octet-stream"; + QTest::newRow("put-2MB+1") << false << permanentRedirect << data << "application/octet-stream"; } -void tst_QNetworkReply::ioHttpRedirectPost() +void tst_QNetworkReply::ioHttpRedirectPostPut() { + QFETCH(bool, usePost); QFETCH(QString, status); QFETCH(QByteArray, data); QFETCH(QString, contentType); @@ -8595,7 +8606,7 @@ void tst_QNetworkReply::ioHttpRedirectPost() auto oldRedirectPolicy = manager.redirectPolicy(); manager.setRedirectPolicy(QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy); - QNetworkReplyPtr reply(manager.post(request, data)); + QNetworkReplyPtr reply(usePost ? manager.post(request, data) : manager.put(request, data)); // Restore previous policy: manager.setRedirectPolicy(oldRedirectPolicy); @@ -8664,6 +8675,50 @@ void tst_QNetworkReply::ioHttpRedirectMultipartPost() QCOMPARE(replyData, expectedReplyData); } +void tst_QNetworkReply::ioHttpRedirectDelete() +{ + MiniHttpServer target(httpEmpty200Response, false); + QUrl targetUrl("http://localhost/"); + targetUrl.setPort(target.serverPort()); + + QString redirectReply = tempRedirectReplyStr().arg(targetUrl.toString()); + MiniHttpServer redirectServer(redirectReply.toLatin1()); + QUrl url("http://localhost/"); + url.setPort(redirectServer.serverPort()); + QNetworkRequest request(url); + auto oldRedirectPolicy = manager.redirectPolicy(); + manager.setRedirectPolicy(QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy); + + QNetworkReplyPtr reply(manager.deleteResource(request)); + // Restore previous policy: + manager.setRedirectPolicy(oldRedirectPolicy); + + QCOMPARE(waitForFinish(reply), int(Success)); + QVERIFY2(target.receivedData.startsWith("DELETE"), "Target server called with the wrong method"); +} + +void tst_QNetworkReply::ioHttpRedirectCustom() +{ + MiniHttpServer target(httpEmpty200Response, false); + QUrl targetUrl("http://localhost/"); + targetUrl.setPort(target.serverPort()); + + QString redirectReply = tempRedirectReplyStr().arg(targetUrl.toString()); + MiniHttpServer redirectServer(redirectReply.toLatin1()); + QUrl url("http://localhost/"); + url.setPort(redirectServer.serverPort()); + QNetworkRequest request(url); + auto oldRedirectPolicy = manager.redirectPolicy(); + manager.setRedirectPolicy(QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy); + + QNetworkReplyPtr reply(manager.sendCustomRequest(request, QByteArrayLiteral("CUSTOM"))); + // Restore previous policy: + manager.setRedirectPolicy(oldRedirectPolicy); + + QCOMPARE(waitForFinish(reply), int(Success)); + QVERIFY2(target.receivedData.startsWith("CUSTOM"), "Target server called with the wrong method"); +} + #ifndef QT_NO_SSL class PutWithServerClosingConnectionImmediatelyHandler: public QObject -- cgit v1.2.3 From 4f9b2cb026e334eb24dd35b05422b9dad6d8a2f3 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Thu, 21 Sep 2017 13:14:40 +0200 Subject: Remove duplicate qnx from the platform file selector names Update the QFileSelector tests for QNX. Co-authored-by: James McDonnell Change-Id: I68a8fde86725596323b539433287ac1a18fac1eb Reviewed-by: Thiago Macieira --- src/corelib/io/qfileselector.cpp | 6 +++--- tests/auto/corelib/io/qfileselector/platforms/+qnx/test | 0 tests/auto/corelib/io/qfileselector/platforms/+qnx/test2 | 0 tests/auto/corelib/io/qfileselector/platforms/+unix/+qnx/test | 0 tests/auto/corelib/io/qfileselector/qfileselector.qrc | 3 +++ tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp | 2 +- 6 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 tests/auto/corelib/io/qfileselector/platforms/+qnx/test create mode 100644 tests/auto/corelib/io/qfileselector/platforms/+qnx/test2 create mode 100644 tests/auto/corelib/io/qfileselector/platforms/+unix/+qnx/test diff --git a/src/corelib/io/qfileselector.cpp b/src/corelib/io/qfileselector.cpp index 9db67f2f9b..0ba8b124f7 100644 --- a/src/corelib/io/qfileselector.cpp +++ b/src/corelib/io/qfileselector.cpp @@ -146,7 +146,7 @@ QFileSelectorPrivate::QFileSelectorPrivate() Selectors normally available are \list \li platform, any of the following strings which match the platform the application is running - on (list not exhaustive): android, ios, osx, darwin, mac, linux, wince, unix, windows. + on (list not exhaustive): android, ios, osx, darwin, mac, macos, linux, qnx, unix, windows. On Linux, if it can be determined, the name of the distribution too, like debian, fedora or opensuse. \li locale, same as QLocale().name(). @@ -373,8 +373,8 @@ QStringList QFileSelectorPrivate::platformSelectors() # endif #elif defined(Q_OS_UNIX) ret << QStringLiteral("unix"); -# if !defined(Q_OS_ANDROID) - // we don't want "linux" for Android +# if !defined(Q_OS_ANDROID) && !defined(Q_OS_QNX) + // we don't want "linux" for Android or two instances of "qnx" for QNX ret << QSysInfo::kernelType(); # ifdef Q_OS_MAC ret << QStringLiteral("mac"); // compatibility, since kernelType() is "darwin" diff --git a/tests/auto/corelib/io/qfileselector/platforms/+qnx/test b/tests/auto/corelib/io/qfileselector/platforms/+qnx/test new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/auto/corelib/io/qfileselector/platforms/+qnx/test2 b/tests/auto/corelib/io/qfileselector/platforms/+qnx/test2 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/auto/corelib/io/qfileselector/platforms/+unix/+qnx/test b/tests/auto/corelib/io/qfileselector/platforms/+unix/+qnx/test new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/auto/corelib/io/qfileselector/qfileselector.qrc b/tests/auto/corelib/io/qfileselector/qfileselector.qrc index ea9b8270e0..54b2e0a0e2 100644 --- a/tests/auto/corelib/io/qfileselector/qfileselector.qrc +++ b/tests/auto/corelib/io/qfileselector/qfileselector.qrc @@ -21,6 +21,7 @@ platforms/+unix/+darwin/test platforms/+unix/+haiku/test platforms/+unix/+linux/test + platforms/+unix/+qnx/test platforms/+unix/test platforms/+windows/+wince/test platforms/+windows/+winnt/test @@ -34,6 +35,7 @@ platforms/+mac/test platforms/+haiku/test platforms/+linux/test + platforms/+qnx/test platforms/+wince/test platforms/+winrt/test @@ -44,6 +46,7 @@ platforms/+macos/test2 platforms/+haiku/test2 platforms/+linux/test2 + platforms/+qnx/test2 platforms/+wince/test2 platforms/+winnt/test2 platforms/+winrt/test2 diff --git a/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp b/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp index c537e43802..c9f1e3d9f6 100644 --- a/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp +++ b/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp @@ -86,7 +86,7 @@ void tst_QFileSelector::basicTest_data() QString expectedPlatform2File(""); //Only the last selector QString expectedPlatform3File; // Only the first selector (the family) #if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID) && \ - !defined(Q_OS_DARWIN) && !defined(Q_OS_LINUX) && !defined(Q_OS_HAIKU) + !defined(Q_OS_DARWIN) && !defined(Q_OS_LINUX) && !defined(Q_OS_HAIKU) && !defined(Q_OS_QNX) /* We are only aware of specific unixes, and do not have test files for any of the others. However those unixes can get a selector added from the result of a uname call, so this will lead to a case where we don't have that file so we can't expect the concatenation of platform -- cgit v1.2.3 From 37a1478787d64b34a0716421c8a47f3246e41bfd Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 20 Oct 2017 11:07:59 +0700 Subject: Cocoa QPA: Code clean up, make some bits more readable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I7f37c1b0f7f72a79bb2ac5828ba54111a90a0a00 Reviewed-by: Jake Petroules Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/messages.cpp | 2 +- src/plugins/platforms/cocoa/messages.h | 11 +++++++++++ src/plugins/platforms/cocoa/qcocoamenuitem.mm | 10 +++------- src/plugins/platforms/cocoa/qcocoamenuloader.mm | 20 +++++++------------- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/plugins/platforms/cocoa/messages.cpp b/src/plugins/platforms/cocoa/messages.cpp index 85b814ce1c..8eea1e654e 100644 --- a/src/plugins/platforms/cocoa/messages.cpp +++ b/src/plugins/platforms/cocoa/messages.cpp @@ -75,7 +75,7 @@ QString qt_mac_applicationmenu_string(int type) QPlatformMenuItem::MenuRole detectMenuRole(const QString &caption) { QString captionNoAmpersand(caption); - captionNoAmpersand.remove(QChar('&')); + captionNoAmpersand.remove(QLatin1Char('&')); const QString aboutString = QCoreApplication::translate("QCocoaMenuItem", "About"); if (captionNoAmpersand.startsWith(aboutString, Qt::CaseInsensitive) || caption.endsWith(aboutString, Qt::CaseInsensitive)) return QPlatformMenuItem::AboutRole; diff --git a/src/plugins/platforms/cocoa/messages.h b/src/plugins/platforms/cocoa/messages.h index a9c9cc42e5..e41898fe59 100644 --- a/src/plugins/platforms/cocoa/messages.h +++ b/src/plugins/platforms/cocoa/messages.h @@ -45,6 +45,17 @@ QT_BEGIN_NAMESPACE +enum { + ServicesAppMenuItem = 0, + HideAppMenuItem, + HideOthersAppMenuItem, + ShowAllAppMenuItem, + PreferencesAppMenuItem, + QuitAppMenuItem, + AboutAppMenuItem +}; + + QString msgAboutQt(); QString qt_mac_applicationmenu_string(int type); diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 21f2b4de85..ecbab38a83 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -370,24 +370,20 @@ NSMenuItem *QCocoaMenuItem::sync() return m_native; } -QT_BEGIN_NAMESPACE -extern QString qt_mac_applicationmenu_string(int type); -QT_END_NAMESPACE - QString QCocoaMenuItem::mergeText() { QCocoaMenuLoader *loader = [QCocoaMenuLoader sharedMenuLoader]; if (m_native == [loader aboutMenuItem]) { - return qt_mac_applicationmenu_string(6).arg(qt_mac_applicationName()); + return qt_mac_applicationmenu_string(AboutAppMenuItem).arg(qt_mac_applicationName()); } else if (m_native== [loader aboutQtMenuItem]) { if (m_text == QString("About Qt")) return msgAboutQt(); else return m_text; } else if (m_native == [loader preferencesMenuItem]) { - return qt_mac_applicationmenu_string(4); + return qt_mac_applicationmenu_string(PreferencesAppMenuItem); } else if (m_native == [loader quitMenuItem]) { - return qt_mac_applicationmenu_string(5).arg(qt_mac_applicationName()); + return qt_mac_applicationmenu_string(QuitAppMenuItem).arg(qt_mac_applicationName()); } else if (m_text.contains('\t')) { return m_text.left(m_text.indexOf('\t')); } diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm index 01a3c04afb..0d9bb5009d 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm @@ -47,14 +47,8 @@ #include #include #include -#include -#include -#include #include -QT_FORWARD_DECLARE_CLASS(QCFString) -QT_FORWARD_DECLARE_CLASS(QString) - @implementation QCocoaMenuLoader + (instancetype)sharedMenuLoader @@ -314,13 +308,13 @@ QT_FORWARD_DECLARE_CLASS(QString) { #ifndef QT_NO_TRANSLATION - [servicesItem setTitle:qt_mac_applicationmenu_string(0).toNSString()]; - [hideItem setTitle:qt_mac_applicationmenu_string(1).arg(qt_mac_applicationName()).toNSString()]; - [hideAllOthersItem setTitle:qt_mac_applicationmenu_string(2).toNSString()]; - [showAllItem setTitle:qt_mac_applicationmenu_string(3).toNSString()]; - [preferencesItem setTitle:qt_mac_applicationmenu_string(4).toNSString()]; - [quitItem setTitle:qt_mac_applicationmenu_string(5).arg(qt_mac_applicationName()).toNSString()]; - [aboutItem setTitle:qt_mac_applicationmenu_string(6).arg(qt_mac_applicationName()).toNSString()]; + [servicesItem setTitle:qt_mac_applicationmenu_string(ServicesAppMenuItem).toNSString()]; + [hideItem setTitle:qt_mac_applicationmenu_string(HideAppMenuItem).arg(qt_mac_applicationName()).toNSString()]; + [hideAllOthersItem setTitle:qt_mac_applicationmenu_string(HideOthersAppMenuItem).toNSString()]; + [showAllItem setTitle:qt_mac_applicationmenu_string(ShowAllAppMenuItem).toNSString()]; + [preferencesItem setTitle:qt_mac_applicationmenu_string(PreferencesAppMenuItem).toNSString()]; + [quitItem setTitle:qt_mac_applicationmenu_string(QuitAppMenuItem).arg(qt_mac_applicationName()).toNSString()]; + [aboutItem setTitle:qt_mac_applicationmenu_string(AboutAppMenuItem).arg(qt_mac_applicationName()).toNSString()]; #endif } -- cgit v1.2.3 From abcf558e49d5e8c20eda14badc30e93e2e9cba32 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 16 Oct 2017 11:53:53 +0200 Subject: moc: Restore compatibility with Qt 5.7's -b option In Qt 5.7, it was possible to call moc "-bfoo.h" or "-b foo.h" and it had the same effect. With the port to QCommandLineOption, we broke the -b option as it was not annotated as a short option. (Regression in a7e3c17e755881aa3169a2bb662338bbd2c67512) Task-number: QTBUG-63706 Change-Id: I161d0f1a4e65d129063b5e8431802257677da19d Reviewed-by: Jake Petroules Reviewed-by: Thiago Macieira --- src/tools/moc/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp index b30de66258..98cc9652ab 100644 --- a/src/tools/moc/main.cpp +++ b/src/tools/moc/main.cpp @@ -267,6 +267,7 @@ int runMoc(int argc, char **argv) QCommandLineOption prependIncludeOption(QStringLiteral("b")); prependIncludeOption.setDescription(QStringLiteral("Prepend #include (preserve default include).")); prependIncludeOption.setValueName(QStringLiteral("file")); + prependIncludeOption.setFlags(QCommandLineOption::ShortOptionStyle); parser.addOption(prependIncludeOption); QCommandLineOption includeOption(QStringLiteral("include")); -- cgit v1.2.3 From 3b8f828174f08d9037a0947b8709648ac37cdc36 Mon Sep 17 00:00:00 2001 From: Maciej Czarnecki Date: Mon, 21 Aug 2017 13:28:51 +0200 Subject: QWizard: Do not remove the Next button's shortcut Currently on Windows, the Next button's shortcut doesn't work, because QWizard overrides it with an empty key sequence. The key sequence should be changed only if isVistaThemeEnabled() returns true. Task-number: QTBUG-46894 Change-Id: I54f26388b167973cc8065a867d9e771c1e6a2a72 Reviewed-by: Friedemann Kleint --- src/widgets/dialogs/qwizard.cpp | 4 ++-- tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp index 1984cb0a89..a4ea7ae8de 100644 --- a/src/widgets/dialogs/qwizard.cpp +++ b/src/widgets/dialogs/qwizard.cpp @@ -1468,8 +1468,8 @@ void QWizardPrivate::updateButtonTexts() // even in RTL mode, so do the same, even if it might be counter-intuitive. // The shortcut for 'back' is set in class QVistaBackButton. #if QT_CONFIG(shortcut) - if (btns[QWizard::NextButton]) - btns[QWizard::NextButton]->setShortcut(isVistaThemeEnabled() ? QKeySequence(Qt::ALT | Qt::Key_Right) : QKeySequence()); + if (btns[QWizard::NextButton] && isVistaThemeEnabled()) + btns[QWizard::NextButton]->setShortcut(QKeySequence(Qt::ALT | Qt::Key_Right)); #endif } diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp index db86fba59c..6ad93b2666 100644 --- a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp +++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp @@ -96,6 +96,7 @@ private slots: void task248107_backButton(); void task255350_fieldObjectDestroyed(); void taskQTBUG_25691_fieldObjectDestroyed2(); + void taskQTBUG_46894_nextButtonShortcut(); /* Things that could be added: @@ -2700,5 +2701,24 @@ void tst_QWizard::taskQTBUG_25691_fieldObjectDestroyed2() ::taskQTBUG_25691_fieldObjectDestroyed2(); } +void tst_QWizard::taskQTBUG_46894_nextButtonShortcut() +{ + for (int i = 0; i < QWizard::NStyles; ++i) { + QWizard wizard; + QWizard::WizardStyle style = static_cast(i); + wizard.setWizardStyle(style); + wizard.show(); + QVERIFY(QTest::qWaitForWindowExposed(&wizard)); + + if (wizard.button(QWizard::NextButton)->text() == "&Next") { + QCOMPARE(wizard.button(QWizard::NextButton)->shortcut(), + QKeySequence(Qt::ALT | Qt::Key_Right)); + } else { + QCOMPARE(wizard.button(QWizard::NextButton)->shortcut(), + QKeySequence::mnemonic(wizard.button(QWizard::NextButton)->text())); + } + } +} + QTEST_MAIN(tst_QWizard) #include "tst_qwizard.moc" -- cgit v1.2.3 From d020d3f4ede280d998e3b7069a39e134dc9319a5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 18 Sep 2017 10:17:54 +0200 Subject: Stabilize tst_qaccessibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure windows are cleaned up. Add scaling where native coordinates are used. Task-number: QTQAINFRA-1440 Change-Id: Ie080ff780c687418f4dc5d71fd49112486b217e6 Reviewed-by: Jan Arve Sæther Reviewed-by: Frederik Gladhorn --- .../other/qaccessibility/tst_qaccessibility.cpp | 27 +++++++++++----------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 4ffdc4c762..b857501e8f 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #if defined(Q_OS_WIN) && defined(interface) # undef interface @@ -301,6 +302,7 @@ void tst_QAccessibility::cleanup() qAccessibleEventString(list.at(i)->type()), list.at(i)->child()); } QTestAccessibility::clearEvents(); + QTRY_VERIFY(QApplication::topLevelWidgets().isEmpty()); } void tst_QAccessibility::eventTest() @@ -3743,14 +3745,14 @@ void tst_QAccessibility::bridgeTest() // Ideally it should be extended to test all aspects of the bridge. #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) // First, test MSAA part of bridge - QWidget *window = new QWidget; - QVBoxLayout *lay = new QVBoxLayout(window); - QPushButton *button = new QPushButton(tr("Push me"), window); - QTextEdit *te = new QTextEdit(window); + QWidget window; + QVBoxLayout *lay = new QVBoxLayout(&window); + QPushButton *button = new QPushButton(tr("Push me"), &window); + QTextEdit *te = new QTextEdit(&window); te->setText(QLatin1String("hello world\nhow are you today?\n")); // Add QTableWidget - QTableWidget *tableWidget = new QTableWidget(3, 3, window); + QTableWidget *tableWidget = new QTableWidget(3, 3, &window); tableWidget->setColumnCount(3); QStringList hHeader; hHeader << "h1" << "h2" << "h3"; @@ -3776,8 +3778,8 @@ void tst_QAccessibility::bridgeTest() lay->addWidget(tableWidget); lay->addWidget(label); - window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window)); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); /************************************************** @@ -3789,9 +3791,8 @@ void tst_QAccessibility::bridgeTest() QCOMPARE(buttonRect.topLeft(), buttonPos); // All set, now test the bridge. - POINT pt; - pt.x = buttonRect.center().x(); - pt.y = buttonRect.center().y(); + const QPoint nativePos = QHighDpi::toNativePixels(buttonRect.center(), window.windowHandle()); + POINT pt{nativePos.x(), nativePos.y()}; IAccessible *iaccButton; VARIANT varChild; @@ -3817,7 +3818,7 @@ void tst_QAccessibility::bridgeTest() QCOMPARE(SUCCEEDED(hr), false); hr = iaccButton->accLocation(&x, &y, &w, &h, varSELF); - QCOMPARE(buttonRect, QRect(x, y, w, h)); + QCOMPARE(buttonRect, QHighDpi::fromNativePixels(QRect(x, y, w, h), window.windowHandle())); #ifdef QT_SUPPORTS_IACCESSIBLE2 // Test IAccessible2 part of bridge @@ -3832,7 +3833,7 @@ void tst_QAccessibility::bridgeTest() long x, y; hr = ia2Component->get_locationInParent(&x, &y); QVERIFY(SUCCEEDED(hr)); - QCOMPARE(button->pos(), QPoint(x, y)); + QCOMPARE(button->pos(), QHighDpi::fromNativePixels(QPoint(x, y), window.windowHandle())); ia2Component->Release(); /***** Test IAccessibleAction *****/ @@ -3897,7 +3898,7 @@ void tst_QAccessibility::bridgeTest() /************************************************** * QWidget **************************************************/ - QWindow *windowHandle = window->windowHandle(); + QWindow *windowHandle = window.windowHandle(); QPlatformNativeInterface *platform = QGuiApplication::platformNativeInterface(); HWND hWnd = (HWND)platform->nativeResourceForWindow("handle", windowHandle); -- cgit v1.2.3 From 5ec02f7792e97208c0f621c9e8a16854168022e3 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 24 Oct 2017 14:33:24 +0200 Subject: winrt: Fix compilation with -no-pch Task-number: QTBUG-63210 Change-Id: Icdd4fcee67e3b386b86a131c302424b53b18e565 Reviewed-by: Maurice Kalinowski Reviewed-by: Jake Petroules --- src/corelib/kernel/qfunctions_winrt.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/kernel/qfunctions_winrt.h b/src/corelib/kernel/qfunctions_winrt.h index 9b33f8b120..d0c44be683 100644 --- a/src/corelib/kernel/qfunctions_winrt.h +++ b/src/corelib/kernel/qfunctions_winrt.h @@ -44,6 +44,7 @@ #ifdef Q_OS_WIN +#include #include #include #include -- cgit v1.2.3 From ecd183455b8039ee15b9d51fd1111992af19ed1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Arve=20S=C3=A6ther?= Date: Wed, 11 Oct 2017 11:35:42 +0200 Subject: Refactor childIdListForAccessibleObject It has several problems: 1. It could potentially create an intArray with uninitialized elements. This could happen because the index for getting interfaces were the same as the storage index. This was not correct, because they could diverge if iface->child() returned an invalid interface. 2. The count of accessible child elements could change while iterating. This could cause out-of-bounds condition when calling SetIntArrayRegion as described in QTBUG-45855. Instead now, we call SetIntArrayRegion only once, after we have gathered all the child interface ids. Task-number: QTBUG-45855 Change-Id: I77e813158df5f563d04931ac4e296e3fc2a16e67 Reviewed-by: Frederik Gladhorn --- src/plugins/platforms/android/androidjniaccessibility.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index e4d670239f..a3bc58bb89 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -105,15 +105,15 @@ namespace QtAndroidAccessibility { QAccessibleInterface *iface = interfaceFromId(objectId); if (iface && iface->isValid()) { - jintArray jArray = env->NewIntArray(jsize(iface->childCount())); - for (int i = 0; i < iface->childCount(); ++i) { + const int childCount = iface->childCount(); + QVarLengthArray ifaceIdArray(childCount); + for (int i = 0; i < childCount; ++i) { QAccessibleInterface *child = iface->child(i); - if (child && child->isValid()) { - QAccessible::Id ifaceId = QAccessible::uniqueId(child); - jint jid = ifaceId; - env->SetIntArrayRegion(jArray, i, 1, &jid); - } + if (child && child->isValid()) + ifaceIdArray.append(QAccessible::uniqueId(child)); } + jintArray jArray = env->NewIntArray(jsize(ifaceIdArray.count())); + env->SetIntArrayRegion(jArray, 0, ifaceIdArray.count(), ifaceIdArray.data()); return jArray; } -- cgit v1.2.3 From 5eb508a31717c75d804cfb55e46e867c19ae58d2 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 18 Oct 2017 15:34:52 +0200 Subject: Fix clazy-strict-iterators Change-Id: I9276a85f0a8061b2636687cf694b8ed1abaa18b8 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/statemachine/qstatemachine.cpp | 2 +- src/dbus/qdbusinternalfilters.cpp | 2 +- src/gui/text/qtexttable.cpp | 4 ++-- .../platforminputcontexts/compose/qcomposeplatforminputcontext.cpp | 2 +- src/tools/moc/preprocessor.cpp | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 1d80da55c9..2808ba2ced 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -411,7 +411,7 @@ QStateMachinePrivate::~QStateMachinePrivate() qDeleteAll(internalEventQueue); qDeleteAll(externalEventQueue); - for (QHash::const_iterator it = delayedEvents.begin(), eit = delayedEvents.end(); it != eit; ++it) { + for (QHash::const_iterator it = delayedEvents.cbegin(), eit = delayedEvents.cend(); it != eit; ++it) { delete it.value().event; } } diff --git a/src/dbus/qdbusinternalfilters.cpp b/src/dbus/qdbusinternalfilters.cpp index 0927f326f2..0ef5061b5f 100644 --- a/src/dbus/qdbusinternalfilters.cpp +++ b/src/dbus/qdbusinternalfilters.cpp @@ -407,7 +407,7 @@ QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNode &node QDBusAdaptorConnector::AdaptorMap::ConstIterator it; it = std::lower_bound(connector->adaptors.constBegin(), connector->adaptors.constEnd(), interface_name); - if (it != connector->adaptors.end() && interface_name == QLatin1String(it->interface)) { + if (it != connector->adaptors.cend() && interface_name == QLatin1String(it->interface)) { return propertyWriteReply(msg, interface_name, property_name, writeProperty(it->adaptor, property_name, value)); } diff --git a/src/gui/text/qtexttable.cpp b/src/gui/text/qtexttable.cpp index e4a3c2b915..9639c18d2b 100644 --- a/src/gui/text/qtexttable.cpp +++ b/src/gui/text/qtexttable.cpp @@ -1048,7 +1048,7 @@ void QTextTable::mergeCells(int row, int column, int numRows, int numCols) QFragmentFindHelper helper(origCellPosition, p->fragmentMap()); const auto begin = d->cells.cbegin(); const auto it = std::lower_bound(begin, d->cells.cend(), helper); - Q_ASSERT(it != d->cells.end()); + Q_ASSERT(it != d->cells.cend()); Q_ASSERT(!(helper < *it)); Q_ASSERT(*it == cellFragment); const int insertCellIndex = it - begin; @@ -1082,7 +1082,7 @@ void QTextTable::mergeCells(int row, int column, int numRows, int numCols) QFragmentFindHelper helper(pos, p->fragmentMap()); const auto begin = d->cells.cbegin(); const auto it = std::lower_bound(begin, d->cells.cend(), helper); - Q_ASSERT(it != d->cells.end()); + Q_ASSERT(it != d->cells.cend()); Q_ASSERT(!(helper < *it)); Q_ASSERT(*it == fragment); firstCellIndex = cellIndex = it - begin; diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp index 6016d460fc..48693ccdb0 100644 --- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp @@ -222,7 +222,7 @@ bool QComposeInputContext::checkComposeTable() int next = 1; do { // if we are at the end of the table, then we have nothing to do here - if (it + next != m_composeTable.end()) { + if (it + next != m_composeTable.constEnd()) { QComposeTableElement nextElem = *(it + next); if (isDuplicate(elem, nextElem)) { elem = nextElem; diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index 9a06fb38d0..a6725af924 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -992,7 +992,7 @@ static void mergeStringLiterals(Symbols *_symbols) mergeSymbolLexem.reserve(literalsLength); mergeSymbolLexem.append('"'); mergeSymbolLexem.append(mergeSymbolOriginalLexem); - for (Symbols::const_iterator j = mergeSymbol + 1; j != i; ++j) + for (Symbols::iterator j = mergeSymbol + 1; j != i; ++j) mergeSymbolLexem.append(j->lex.constData() + j->from + 1, j->len - 2); // append j->unquotedLexem() mergeSymbolLexem.append('"'); mergeSymbol->len = mergeSymbol->lex.length(); -- cgit v1.2.3 From 7a26582807b06d16d8d1b909a0c5ea34bcecfa42 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 9 Oct 2017 11:47:43 +0200 Subject: Make sure that QAccessibleWindowContainer::childCount is valid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When embedding foreign windows, we won't be able to return a valid child accessible interface, so do not report it at all. Supporting foreign windows properly is platform specific and something to consider, but at least we shouldn't crash. Task-number: QTBUG-63451 Change-Id: I19350cf97dc8d0c3f3052411eba0eee5f750dbab Reviewed-by: Jan Arve Sæther --- src/widgets/accessible/simplewidgets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/accessible/simplewidgets.cpp b/src/widgets/accessible/simplewidgets.cpp index 73de51ff45..bacb00fe2e 100644 --- a/src/widgets/accessible/simplewidgets.cpp +++ b/src/widgets/accessible/simplewidgets.cpp @@ -953,7 +953,7 @@ QAccessibleWindowContainer::QAccessibleWindowContainer(QWidget *w) int QAccessibleWindowContainer::childCount() const { - if (container()->containedWindow()) + if (container()->containedWindow() && QAccessible::queryAccessibleInterface(container()->containedWindow())) return 1; return 0; } -- cgit v1.2.3 From 4e339a5ac1c3ef721d040dd88d84adc9930626c7 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Fri, 16 Jun 2017 14:27:19 +0200 Subject: Doc: QImageReader assumes exclusive control over its device Make an explicit mention of the fact that modifying a device while it is being held by a QImageReader is undefined. Task-number: QTBUG-61121 Change-Id: Ie0a016255c2614c5b8b415c8cd9602169153c8f8 Reviewed-by: Paul Olav Tvete --- src/gui/image/qimagereader.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index f49e90ba0a..e1089936c2 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -72,6 +72,11 @@ that occurred, or errorString() to get a human readable description of what went wrong. + \note QImageReader assumes exclusive control over the file or + device that is assigned. Any attempts to modify the assigned file + or device during the lifetime of the QImageReader object will + yield undefined results. + \section1 Formats Call supportedImageFormats() for a list of formats that -- cgit v1.2.3 From 9574436666c1806a69fdd5f7a83f41ad0f6152ac Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 21 Sep 2017 13:59:05 -0700 Subject: QUrl: make sure setPort(nonnegative) is taken as part of authority There were a couple of corner cases where doing setPort() would result in QUrl thinking that an authority was not present. Since the full URL parsing implies that a host is always present if the authority is present, then we also imply that setting the port number makes the host be present too. Change-Id: I69f37f9304f24709a823fffd14e67c12da18d69f Reviewed-by: David Faure --- src/corelib/io/qurl.cpp | 14 ++++++------- tests/auto/corelib/io/qurl/tst_qurl.cpp | 35 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index a499dc2d30..cf7ed130ba 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -1037,6 +1037,7 @@ inline void QUrlPrivate::setAuthority(const QString &auth, int from, int end, QU { sectionIsPresent &= ~Authority; sectionIsPresent |= Host; + port = -1; // we never actually _loop_ while (from != end) { @@ -1061,10 +1062,8 @@ inline void QUrlPrivate::setAuthority(const QString &auth, int from, int end, QU } } - if (colonIndex == end - 1) { - // found a colon but no digits after it - port = -1; - } else if (uint(colonIndex) < uint(end)) { + if (uint(colonIndex) < uint(end) - 1) { + // found a colon with digits after it unsigned long x = 0; for (int i = colonIndex + 1; i < end; ++i) { ushort c = auth.at(i).unicode(); @@ -1083,8 +1082,6 @@ inline void QUrlPrivate::setAuthority(const QString &auth, int from, int end, QU if (mode == QUrl::StrictMode) break; } - } else { - port = -1; } setHost(auth, from, qMin(end, colonIndex), mode); @@ -1644,8 +1641,7 @@ inline QUrlPrivate::ErrorCode QUrlPrivate::validityError(QString *source, int *p if (path.isEmpty()) return NoError; if (path.at(0) == QLatin1Char('/')) { - if (sectionIsPresent & QUrlPrivate::Authority || port != -1 || - path.length() == 1 || path.at(1) != QLatin1Char('/')) + if (hasAuthority() || path.length() == 1 || path.at(1) != QLatin1Char('/')) return NoError; if (source) { *source = path; @@ -2474,6 +2470,8 @@ void QUrl::setPort(int port) } d->port = port; + if (port != -1) + d->sectionIsPresent |= QUrlPrivate::Host; } /*! diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 1ff85fc6dc..0bbd1b9f15 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -2080,6 +2080,11 @@ void tst_QUrl::isValid() QVERIFY(!url.isValid()); QVERIFY(url.toString().isEmpty()); QVERIFY(url.errorString().contains("Path component starts with '//' and authority is absent")); + + // should disappear if we set a port + url.setPort(80); + QVERIFY(url.isValid()); + QCOMPARE(url.toString(), QString("http://:80//example.com")); } { @@ -2088,6 +2093,13 @@ void tst_QUrl::isValid() QVERIFY(!url.isValid()); QVERIFY(url.toString().isEmpty()); QVERIFY(url.errorString().contains("':' before any '/'")); + + // this specific error disappears if we set anything in the authority, + // but then we run into another error + url.setPort(80); + QVERIFY(!url.isValid()); + QVERIFY(url.toString().isEmpty()); + QVERIFY(url.errorString().contains("Path component is relative and authority is present")); } { @@ -2827,6 +2839,29 @@ void tst_QUrl::setPort() QCOMPARE(url.port(), -1); QVERIFY(url.errorString().contains("out of range")); } + + { + QUrl reference("//:80"); + QUrl piecewise; + piecewise.setPort(80); + QCOMPARE(piecewise, reference); + } + + { + // setAuthority must clear the port + QUrl url("http://example.com:80"); + url.setAuthority("example.org"); + QCOMPARE(url.port(), -1); + QCOMPARE(url.toString(), QString("http://example.org")); + } + + { + // setAuthority must clear the port + QUrl url("http://example.com:80"); + url.setAuthority(QString()); + QCOMPARE(url.port(), -1); + QCOMPARE(url.toString(), QString("http:")); + } } void tst_QUrl::port_data() -- cgit v1.2.3 From a1d62e61cbdf93dde52bfe34caf6e7c0073be679 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 26 Sep 2017 15:38:07 +0200 Subject: Synthesize LICENSE.txt for FreeType documentation The LICENSE.txt we showed so far only mentioned the two mutual licenses (FTL and GPLv2), whithout actually spelling them out. This is required though. [ChangeLog][Third-Party Code] Improve documentation about Freetype 2 licenses. Change-Id: I3af84b732aff58b12218cb7e8bb8e8de00c86307 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/3rdparty/freetype/LICENSE.txt | 551 ++++++++++++++++++++++++++++++ src/3rdparty/freetype/qt_attribution.json | 4 +- 2 files changed, 553 insertions(+), 2 deletions(-) create mode 100644 src/3rdparty/freetype/LICENSE.txt diff --git a/src/3rdparty/freetype/LICENSE.txt b/src/3rdparty/freetype/LICENSE.txt new file mode 100644 index 0000000000..382225f105 --- /dev/null +++ b/src/3rdparty/freetype/LICENSE.txt @@ -0,0 +1,551 @@ +The FreeType 2 font engine is copyrighted work and cannot be used +legally without a software license. In order to make this project +usable to a vast majority of developers, we distribute it under two +mutually exclusive open-source licenses. + +This means that *you* must choose *one* of the two licenses described +below, then obey all its terms and conditions when using FreeType 2 in +any of your projects or products. + + - The FreeType License, found in the file `FTL.TXT', which is similar + to the original BSD license *with* an advertising clause that forces + you to explicitly cite the FreeType project in your product's + documentation. All details are in the license file. This license + is suited to products which don't use the GNU General Public + License. + + Note that this license is compatible to the GNU General Public + License version 3, but not version 2. + + - The GNU General Public License version 2, found in `GPLv2.TXT' (any + later version can be used also), for programs which already use the + GPL. Note that the FTL is incompatible with GPLv2 due to its + advertisement clause. + +The contributed BDF and PCF drivers come with a license similar to that +of the X Window System. It is compatible to the above two licenses (see +file src/bdf/README and src/pcf/README). + +The gzip module uses the zlib license (see src/gzip/zlib.h) which too is +compatible to the above two licenses. + +The MD5 checksum support (only used for debugging in development builds) +is in the public domain. + + +--- FDL.TXT --- + + The FreeType Project LICENSE + ---------------------------- + + 2006-Jan-27 + + Copyright 1996-2002, 2006 by + David Turner, Robert Wilhelm, and Werner Lemberg + + + +Introduction +============ + + The FreeType Project is distributed in several archive packages; + some of them may contain, in addition to the FreeType font engine, + various tools and contributions which rely on, or relate to, the + FreeType Project. + + This license applies to all files found in such packages, and + which do not fall under their own explicit license. The license + affects thus the FreeType font engine, the test programs, + documentation and makefiles, at the very least. + + This license was inspired by the BSD, Artistic, and IJG + (Independent JPEG Group) licenses, which all encourage inclusion + and use of free software in commercial and freeware products + alike. As a consequence, its main points are that: + + o We don't promise that this software works. However, we will be + interested in any kind of bug reports. (`as is' distribution) + + o You can use this software for whatever you want, in parts or + full form, without having to pay us. (`royalty-free' usage) + + o You may not pretend that you wrote this software. If you use + it, or only parts of it, in a program, you must acknowledge + somewhere in your documentation that you have used the + FreeType code. (`credits') + + We specifically permit and encourage the inclusion of this + software, with or without modifications, in commercial products. + We disclaim all warranties covering The FreeType Project and + assume no liability related to The FreeType Project. + + + Finally, many people asked us for a preferred form for a + credit/disclaimer to use in compliance with this license. We thus + encourage you to use the following text: + + """ + Portions of this software are copyright © The FreeType + Project (www.freetype.org). All rights reserved. + """ + + Please replace with the value from the FreeType version you + actually use. + + +Legal Terms +=========== + +0. Definitions +-------------- + + Throughout this license, the terms `package', `FreeType Project', + and `FreeType archive' refer to the set of files originally + distributed by the authors (David Turner, Robert Wilhelm, and + Werner Lemberg) as the `FreeType Project', be they named as alpha, + beta or final release. + + `You' refers to the licensee, or person using the project, where + `using' is a generic term including compiling the project's source + code as well as linking it to form a `program' or `executable'. + This program is referred to as `a program using the FreeType + engine'. + + This license applies to all files distributed in the original + FreeType Project, including all source code, binaries and + documentation, unless otherwise stated in the file in its + original, unmodified form as distributed in the original archive. + If you are unsure whether or not a particular file is covered by + this license, you must contact us to verify this. + + The FreeType Project is copyright (C) 1996-2000 by David Turner, + Robert Wilhelm, and Werner Lemberg. All rights reserved except as + specified below. + +1. No Warranty +-------------- + + THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO + USE, OF THE FREETYPE PROJECT. + +2. Redistribution +----------------- + + This license grants a worldwide, royalty-free, perpetual and + irrevocable right and license to use, execute, perform, compile, + display, copy, create derivative works of, distribute and + sublicense the FreeType Project (in both source and object code + forms) and derivative works thereof for any purpose; and to + authorize others to exercise some or all of the rights granted + herein, subject to the following conditions: + + o Redistribution of source code must retain this license file + (`FTL.TXT') unaltered; any additions, deletions or changes to + the original files must be clearly indicated in accompanying + documentation. The copyright notices of the unaltered, + original files must be preserved in all copies of source + files. + + o Redistribution in binary form must provide a disclaimer that + states that the software is based in part of the work of the + FreeType Team, in the distribution documentation. We also + encourage you to put an URL to the FreeType web page in your + documentation, though this isn't mandatory. + + These conditions apply to any software derived from or based on + the FreeType Project, not just the unmodified files. If you use + our work, you must acknowledge us. However, no fee need be paid + to us. + +3. Advertising +-------------- + + Neither the FreeType authors and contributors nor you shall use + the name of the other for commercial, advertising, or promotional + purposes without specific prior written permission. + + We suggest, but do not require, that you use one or more of the + following phrases to refer to this software in your documentation + or advertising materials: `FreeType Project', `FreeType Engine', + `FreeType library', or `FreeType Distribution'. + + As you have not signed this license, you are not required to + accept it. However, as the FreeType Project is copyrighted + material, only this license, or another one contracted with the + authors, grants you the right to use, distribute, and modify it. + Therefore, by using, distributing, or modifying the FreeType + Project, you indicate that you understand and accept all the terms + of this license. + +4. Contacts +----------- + + There are two mailing lists related to FreeType: + + o freetype@nongnu.org + + Discusses general use and applications of FreeType, as well as + future and wanted additions to the library and distribution. + If you are looking for support, start in this list if you + haven't found anything to help you in the documentation. + + o freetype-devel@nongnu.org + + Discusses bugs, as well as engine internals, design issues, + specific licenses, porting, etc. + + Our home page can be found at + + http://www.freetype.org + +--- end of FDL.TXT --- + +--- GPLv2.TXT --- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + +--- end of GPLv2.TXT --- + diff --git a/src/3rdparty/freetype/qt_attribution.json b/src/3rdparty/freetype/qt_attribution.json index 6c11f1b617..0a8e47a2e0 100644 --- a/src/3rdparty/freetype/qt_attribution.json +++ b/src/3rdparty/freetype/qt_attribution.json @@ -7,7 +7,7 @@ "Description": "FreeType is a freely available software library to render fonts.", "Homepage": "http://www.freetype.org", "License": "Freetype Project License or GNU General Public License v2.0 only", - "LicenseId": "FTL or GPL-2.0", - "LicenseFile": "docs/LICENSE.TXT", + "LicenseId": "FTL OR GPL-2.0", + "LicenseFile": "LICENSE.TXT", "Copyright": "Copyright 2006-2015 by David Turner, Robert Wilhelm, and Werner Lemberg." } -- cgit v1.2.3 From 870423f98ba4a3a53e4a32a96c80535580eeb04e Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 26 Sep 2017 16:58:42 +0200 Subject: Freetype: Also list BDF, PCF, ZLIB licenses These are third party licenses that are part of freetype. Change-Id: I8c54feb6b5537ccfb0d0a4ffc24bc830c3c530e4 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/3rdparty/freetype/BDF-LICENSE.txt | 43 +++++++++++++++++++ src/3rdparty/freetype/PCF-LICENSE.txt | 20 +++++++++ src/3rdparty/freetype/ZLIB-LICENSE.txt | 20 +++++++++ src/3rdparty/freetype/qt_attribution.json | 69 +++++++++++++++++++++++++------ 4 files changed, 139 insertions(+), 13 deletions(-) create mode 100644 src/3rdparty/freetype/BDF-LICENSE.txt create mode 100644 src/3rdparty/freetype/PCF-LICENSE.txt create mode 100644 src/3rdparty/freetype/ZLIB-LICENSE.txt diff --git a/src/3rdparty/freetype/BDF-LICENSE.txt b/src/3rdparty/freetype/BDF-LICENSE.txt new file mode 100644 index 0000000000..6fb375cf8b --- /dev/null +++ b/src/3rdparty/freetype/BDF-LICENSE.txt @@ -0,0 +1,43 @@ +Copyright (C) 2001-2002 by Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*** Portions of the driver (that is, bdflib.c and bdf.h): + +Copyright 2000 Computing Research Labs, New Mexico State University +Copyright 2001-2002, 2011 Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/3rdparty/freetype/PCF-LICENSE.txt b/src/3rdparty/freetype/PCF-LICENSE.txt new file mode 100644 index 0000000000..3f3a3b3f0c --- /dev/null +++ b/src/3rdparty/freetype/PCF-LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (C) 2000 by Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/3rdparty/freetype/ZLIB-LICENSE.txt b/src/3rdparty/freetype/ZLIB-LICENSE.txt new file mode 100644 index 0000000000..abbdfcc017 --- /dev/null +++ b/src/3rdparty/freetype/ZLIB-LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu diff --git a/src/3rdparty/freetype/qt_attribution.json b/src/3rdparty/freetype/qt_attribution.json index 0a8e47a2e0..e00f2062b0 100644 --- a/src/3rdparty/freetype/qt_attribution.json +++ b/src/3rdparty/freetype/qt_attribution.json @@ -1,13 +1,56 @@ -{ - "Id": "freetype", - "Name": "Freetype 2", - "QDocModule": "qtgui", - "QtUsage": "Optionally used in Qt GUI and platform plugins. Configure with -no-freetype, or -system-freetype to avoid.", - - "Description": "FreeType is a freely available software library to render fonts.", - "Homepage": "http://www.freetype.org", - "License": "Freetype Project License or GNU General Public License v2.0 only", - "LicenseId": "FTL OR GPL-2.0", - "LicenseFile": "LICENSE.TXT", - "Copyright": "Copyright 2006-2015 by David Turner, Robert Wilhelm, and Werner Lemberg." -} +[ + { + "Id": "freetype", + "Name": "Freetype 2", + "QDocModule": "qtgui", + "QtUsage": "Optionally used in Qt GUI and platform plugins. Configure with -no-freetype, or -system-freetype to avoid.", + + "Description": "FreeType is a freely available software library to render fonts.", + "Homepage": "http://www.freetype.org", + "License": "Freetype Project License or GNU General Public License v2.0 only", + "LicenseId": "FTL OR GPL-2.0", + "LicenseFile": "LICENSE.TXT", + "Copyright": "Copyright 2006-2015 by David Turner, Robert Wilhelm, and Werner Lemberg." + }, + { + "Id": "freetype-zlib", + "Name": "Freetype 2 - zlib", + "QDocModule": "qtgui", + "QtUsage": "Optionally used in Qt GUI and platform plugins. Configure with -no-freetype, or -system-freetype to avoid.", + + "Description": "FreeType is a freely available software library to render fonts.", + "Homepage": "http://www.freetype.org", + "License": "zlib License", + "LicenseId": "Zlib", + "LicenseFile": "ZLIB-LICENSE.TXT", + "Copyright": "Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler" + }, + { + "Id": "freetype-bdf", + "Name": "Freetype 2 - Bitmap Distribution Format (BDF) support", + "QDocModule": "qtgui", + "QtUsage": "Optionally used in Qt GUI and platform plugins. Configure with -no-freetype, or -system-freetype to avoid.", + + "Description": "FreeType is a freely available software library to render fonts.", + "Homepage": "http://www.freetype.org", + "License": "MIT License", + "LicenseId": "MIT", + "LicenseFile": "BDF-LICENSE.TXT", + "Copyright": "Copyright (C) 2001-2002 by Francesco Zappa Nardelli +Copyright 2000 Computing Research Labs, New Mexico State University +Copyright 2001-2002, 2011 Francesco Zappa Nardelli" + }, + { + "Id": "freetype-pcf", + "Name": "Freetype 2 - Portable Compiled Format (PCF) support", + "QDocModule": "qtgui", + "QtUsage": "Optionally used in Qt GUI and platform plugins. Configure with -no-freetype, or -system-freetype to avoid.", + + "Description": "FreeType is a freely available software library to render fonts.", + "Homepage": "http://www.freetype.org", + "License": "MIT License", + "LicenseId": "MIT", + "LicenseFile": "PCF-LICENSE.TXT", + "Copyright": "Copyright (C) 2000 by Francesco Zappa Nardelli" + } +] -- cgit v1.2.3 From d1422da26441e1a1c88ce2b6122c44cdfcd61ef7 Mon Sep 17 00:00:00 2001 From: Robert Szefner Date: Sun, 22 Oct 2017 22:53:55 +0200 Subject: Fix psql_schemas test Ignore case when comparing table names in PostgreSQL Task-number: QTBUG-63861 Change-Id: Iaf56dff11ee79f96fd3b136e1576f2578328ac79 Reviewed-by: Friedemann Kleint --- tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp index 932806d017..05c3d4c90d 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp @@ -1248,7 +1248,7 @@ void tst_QSqlDatabase::psql_schemas() QString table = schemaName + '.' + qTableName("qtesttable", __FILE__, db); QVERIFY_SQL(q, exec("CREATE TABLE " + table + " (id int primary key, name varchar(20))")); - QVERIFY(db.tables().contains(table)); + QVERIFY(db.tables().contains(table, Qt::CaseInsensitive)); QSqlRecord rec = db.record(table); QCOMPARE(rec.count(), 2); -- cgit v1.2.3 From 0bd4b194d13b76456fa74330f40cc76a0a2d2b80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Mon, 23 Oct 2017 12:50:52 +0200 Subject: Replace unneeded nullptr-checks with ASSERTS The manager and managerPrivate member variables are set in the constructor and never changed after that. Change-Id: I7cc2fd2eb3f50bdc529ed29485e74bf9c016b0c0 Coverity-Id: 185272 Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne --- src/network/access/qnetworkreplyhttpimpl.cpp | 72 ++++++++++++++-------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index c1a9f628a0..73f88025ac 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -182,6 +182,7 @@ QNetworkReplyHttpImpl::QNetworkReplyHttpImpl(QNetworkAccessManager* const manage : QNetworkReply(*new QNetworkReplyHttpImplPrivate, manager) { Q_D(QNetworkReplyHttpImpl); + Q_ASSERT(manager); d->manager = manager; d->managerPrivate = manager->d_func(); d->request = request; @@ -394,9 +395,9 @@ bool QNetworkReplyHttpImpl::canReadLine () const void QNetworkReplyHttpImpl::ignoreSslErrors() { Q_D(QNetworkReplyHttpImpl); + Q_ASSERT(d->managerPrivate); - if (d->managerPrivate && d->managerPrivate->stsEnabled - && d->managerPrivate->stsCache.isKnownHost(url())) { + if (d->managerPrivate->stsEnabled && d->managerPrivate->stsCache.isKnownHost(url())) { // We cannot ignore any Security Transport-related errors for this host. return; } @@ -407,9 +408,9 @@ void QNetworkReplyHttpImpl::ignoreSslErrors() void QNetworkReplyHttpImpl::ignoreSslErrorsImplementation(const QList &errors) { Q_D(QNetworkReplyHttpImpl); + Q_ASSERT(d->managerPrivate); - if (d->managerPrivate && d->managerPrivate->stsEnabled - && d->managerPrivate->stsCache.isKnownHost(url())) { + if (d->managerPrivate->stsEnabled && d->managerPrivate->stsCache.isKnownHost(url())) { // We cannot ignore any Security Transport-related errors for this host. return; } @@ -1144,6 +1145,8 @@ QNetworkRequest QNetworkReplyHttpImplPrivate::createRedirectRequest(const QNetwo void QNetworkReplyHttpImplPrivate::onRedirected(const QUrl &redirectUrl, int httpStatus, int maxRedirectsRemaining) { Q_Q(QNetworkReplyHttpImpl); + Q_ASSERT(manager); + Q_ASSERT(managerPrivate); if (isFinished) return; @@ -1178,7 +1181,7 @@ void QNetworkReplyHttpImplPrivate::onRedirected(const QUrl &redirectUrl, int htt redirectRequest = createRedirectRequest(originalRequest, url, maxRedirectsRemaining); operation = getRedirectOperation(operation, httpStatus); - if (const QNetworkCookieJar *const cookieJar = (manager ? manager->cookieJar() : nullptr)) { + if (const QNetworkCookieJar *const cookieJar = manager->cookieJar()) { auto cookies = cookieJar->cookiesForUrl(url); if (!cookies.empty()) { redirectRequest.setHeader(QNetworkRequest::KnownHeaders::CookieHeader, @@ -1195,6 +1198,7 @@ void QNetworkReplyHttpImplPrivate::onRedirected(const QUrl &redirectUrl, int htt void QNetworkReplyHttpImplPrivate::followRedirect() { Q_Q(QNetworkReplyHttpImpl); + Q_ASSERT(managerPrivate); rawHeaders.clear(); cookedHeaders.clear(); @@ -1206,7 +1210,7 @@ void QNetworkReplyHttpImplPrivate::followRedirect() // If the original request didn't need a session (i.e. it was to localhost) // then we might not have a session open, to which to redirect, if the // new URL is remote. When this happens, we need to open the session now: - if (managerPrivate && isSessionNeeded(url)) { + if (isSessionNeeded(url)) { if (auto session = managerPrivate->getNetworkSession()) { if (session->state() != QNetworkSession::State::Connected || !session->isOpen()) { startWaitForSession(session); @@ -2039,9 +2043,7 @@ void QNetworkReplyHttpImplPrivate::_q_bufferOutgoingData() void QNetworkReplyHttpImplPrivate::_q_networkSessionConnected() { Q_Q(QNetworkReplyHttpImpl); - - if (!manager) - return; + Q_ASSERT(managerPrivate); QSharedPointer session = managerPrivate->getNetworkSession(); if (!session) @@ -2171,28 +2173,27 @@ void QNetworkReplyHttpImplPrivate::finished() if (preMigrationDownloaded != Q_INT64_C(-1)) totalSize = totalSize.toLongLong() + preMigrationDownloaded; - if (manager) { #ifndef QT_NO_BEARERMANAGEMENT - QSharedPointer session = managerPrivate->getNetworkSession(); - if (session && session->state() == QNetworkSession::Roaming && - state == Working && errorCode != QNetworkReply::OperationCanceledError) { - // only content with a known size will fail with a temporary network failure error - if (!totalSize.isNull()) { - if (bytesDownloaded != totalSize) { - if (migrateBackend()) { - // either we are migrating or the request is finished/aborted - if (state == Reconnecting || state == WaitingForSession) { - return; // exit early if we are migrating. - } - } else { - error(QNetworkReply::TemporaryNetworkFailureError, - QNetworkReply::tr("Temporary network failure.")); + Q_ASSERT(managerPrivate); + QSharedPointer session = managerPrivate->getNetworkSession(); + if (session && session->state() == QNetworkSession::Roaming && + state == Working && errorCode != QNetworkReply::OperationCanceledError) { + // only content with a known size will fail with a temporary network failure error + if (!totalSize.isNull()) { + if (bytesDownloaded != totalSize) { + if (migrateBackend()) { + // either we are migrating or the request is finished/aborted + if (state == Reconnecting || state == WaitingForSession) { + return; // exit early if we are migrating. } + } else { + error(QNetworkReply::TemporaryNetworkFailureError, + QNetworkReply::tr("Temporary network failure.")); } } } -#endif } +#endif // if we don't know the total size of or we received everything save the cache if (totalSize.isNull() || totalSize == -1 || bytesDownloaded == totalSize) @@ -2250,17 +2251,16 @@ void QNetworkReplyHttpImplPrivate::_q_metaDataChanged() Q_Q(QNetworkReplyHttpImpl); // 1. do we have cookies? // 2. are we allowed to set them? - if (manager) { - const auto it = cookedHeaders.constFind(QNetworkRequest::SetCookieHeader); - if (it != cookedHeaders.cend() - && request.attribute(QNetworkRequest::CookieSaveControlAttribute, - QNetworkRequest::Automatic).toInt() == QNetworkRequest::Automatic) { - QNetworkCookieJar *jar = manager->cookieJar(); - if (jar) { - QList cookies = - qvariant_cast >(it.value()); - jar->setCookiesFromUrl(cookies, url); - } + Q_ASSERT(manager); + const auto it = cookedHeaders.constFind(QNetworkRequest::SetCookieHeader); + if (it != cookedHeaders.cend() + && request.attribute(QNetworkRequest::CookieSaveControlAttribute, + QNetworkRequest::Automatic).toInt() == QNetworkRequest::Automatic) { + QNetworkCookieJar *jar = manager->cookieJar(); + if (jar) { + QList cookies = + qvariant_cast >(it.value()); + jar->setCookiesFromUrl(cookies, url); } } emit q->metaDataChanged(); -- cgit v1.2.3 From 70b0c127f020205c3b0a892544d12dfd637b0919 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 25 Oct 2017 15:48:52 +0200 Subject: Fix private includes in qhttp2protocolhandler_p.h This file could not be included by user code in an installed Qt. Change-Id: Id222d56dda9ef47d010ab947efa01bf63ecac050 Reviewed-by: Timur Pocheptsov --- src/network/access/qhttp2protocolhandler_p.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/network/access/qhttp2protocolhandler_p.h b/src/network/access/qhttp2protocolhandler_p.h index df0cf6a288..5e04c79376 100644 --- a/src/network/access/qhttp2protocolhandler_p.h +++ b/src/network/access/qhttp2protocolhandler_p.h @@ -57,11 +57,11 @@ #if !defined(QT_NO_HTTP) -#include "http2/http2protocol_p.h" -#include "http2/http2streams_p.h" -#include "http2/http2frames_p.h" -#include "http2/hpacktable_p.h" -#include "http2/hpack_p.h" +#include +#include +#include +#include +#include #include #include -- cgit v1.2.3 From f239dbe60a075f6115d9933a3c53f49fdfbc6a2d Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 27 Oct 2017 11:10:13 +0200 Subject: tests: enforce Qt menubar in tst_QMenuBar::taskQTBUG56860_focus ... the same way other tests do in this file. Change-Id: Ifcaee084bd20c55d6b9f7ddcf35daebce2a02e07 Reviewed-by: Friedemann Kleint --- tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp index 9a70208b94..9325be17b9 100644 --- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp @@ -719,9 +719,7 @@ void tst_QMenuBar::taskQTBUG56860_focus() #endif QMainWindow w; QMenuBar *mb = w.menuBar(); - - if (mb->platformMenuBar()) - QSKIP("This test requires the Qt menubar."); + mb->setNativeMenuBar(false); QMenu *em = mb->addMenu("&Edit"); em->setObjectName("EditMenu"); -- cgit v1.2.3 From 754b636053869d8b673a0e131ae6470a5adace3b Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 27 Oct 2017 11:38:22 +0200 Subject: tests: use QSKIP for temporarily disabled tests Change-Id: Ib088e943668d00cbbd0e6e04ab7d565477b0cc51 Reviewed-by: Friedemann Kleint --- tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp index 9325be17b9..bc50e4f1d8 100644 --- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp @@ -763,8 +763,7 @@ void tst_QMenuBar::check_homeKey() { // I'm temporarily shutting up this testcase. // Seems like the behaviour i'm expecting isn't ok. - QVERIFY( true ); - return; + QSKIP("This test has been \"temporarily\" disabled at least since 2009 :)"); QEXPECT_FAIL( "0", "Popupmenu should respond to a Home key", Abort ); @@ -805,8 +804,7 @@ void tst_QMenuBar::check_endKey() { // I'm temporarily silenting this testcase. // Seems like the behaviour i'm expecting isn't ok. - QVERIFY( true ); - return; + QSKIP("This test has been \"temporarily\" disabled at least since 2009 :)"); QEXPECT_FAIL( "0", "Popupmenu should respond to an End key", Abort ); -- cgit v1.2.3 From e8d2e831a4054a7519c60b11d1ba9e6bec85c3bd Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Wed, 11 Oct 2017 15:19:17 +0300 Subject: QSslSocket::waitForDisconnected(): flush write buffer before waiting Otherwise, the plain socket might be blocked indefinitely on waiting for socket activity. This issue is tested by tst_QSslSocket::disconnectFromHostWhenConnected() which was unstable in CI. Task-number: QTBUG-64016 Change-Id: I6a1a111dea4d1d1adaf55e6a90c0c5f995a270af Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslsocket.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 9d11506fcb..8eba5db9fe 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1686,7 +1686,8 @@ bool QSslSocket::waitForDisconnected(int msecs) if (!d->plainSocket) return false; - if (d->mode == UnencryptedMode) + // Forward to the plain socket unless the connection is secure. + if (d->mode == UnencryptedMode && !d->autoStartHandshake) return d->plainSocket->waitForDisconnected(msecs); QElapsedTimer stopWatch; @@ -1697,6 +1698,17 @@ bool QSslSocket::waitForDisconnected(int msecs) if (!waitForEncrypted(msecs)) return false; } + // We are delaying the disconnect, if the write buffer is not empty. + // So, start the transmission. + if (!d->writeBuffer.isEmpty()) + d->transmit(); + + // At this point, the socket might be disconnected, if disconnectFromHost() + // was called just after the connectToHostEncrypted() call. Also, we can + // lose the connection as a result of the transmit() call. + if (state() == UnconnectedState) + return true; + bool retVal = d->plainSocket->waitForDisconnected(qt_subtract_from_timeout(msecs, stopWatch.elapsed())); if (!retVal) { setSocketState(d->plainSocket->state()); -- cgit v1.2.3 From cd45d0f712f844d05b88801bc000550db0856043 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 25 Oct 2017 13:36:33 +0200 Subject: tst_QFile: Introduce StdioFileGuard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guard the FILE * obtained by fopen() by a RAI class ensuring the file is closed on destruction. Change-Id: I9297f91ca2120238f3a44bad92bca5f920e01aa8 Reviewed-by: JÄ™drzej Nowacki --- tests/auto/corelib/io/qfile/tst_qfile.cpp | 64 +++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 32165ad2b8..450229e01e 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -109,6 +109,30 @@ QT_END_NAMESPACE Q_DECLARE_METATYPE(QFile::FileError) + +class StdioFileGuard +{ + Q_DISABLE_COPY(StdioFileGuard) +public: + explicit StdioFileGuard(FILE *f = nullptr) : m_file(f) {} + ~StdioFileGuard() { close(); } + + operator FILE *() const { return m_file; } + + void close(); + +private: + FILE * m_file; +}; + +void StdioFileGuard::close() +{ + if (m_file != nullptr) { + fclose(m_file); + m_file = nullptr; + } +} + class tst_QFile : public QObject { Q_OBJECT @@ -660,14 +684,13 @@ void tst_QFile::size() } { - QFile f; - FILE* stream = QT_FOPEN(filename.toLocal8Bit().constData(), "rb"); + StdioFileGuard stream(QT_FOPEN(filename.toLocal8Bit().constData(), "rb")); QVERIFY( stream ); + QFile f; QVERIFY( f.open(stream, QIODevice::ReadOnly) ); QCOMPARE( f.size(), size ); f.close(); - fclose(stream); } { @@ -1598,6 +1621,7 @@ void tst_QFile::largeUncFileSupport() qint64 dataOffset = Q_INT64_C(8589914592); QByteArray knownData("LargeFile content at offset 8589914592"); QString largeFile("//" + QtNetworkSettings::winServerName() + "/testsharelargefile/file.bin"); + const QByteArray largeFileEncoded = QFile::encodeName(largeFile); { // 1) Native file handling. @@ -1612,24 +1636,24 @@ void tst_QFile::largeUncFileSupport() } { // 2) stdlib file handling. + StdioFileGuard fh(fopen(largeFileEncoded.constData(), "rb")); + QVERIFY(fh); QFile file; - FILE *fh = fopen(QFile::encodeName(largeFile).data(), "rb"); QVERIFY(file.open(fh, QIODevice::ReadOnly)); QCOMPARE(file.size(), size); QVERIFY(file.seek(dataOffset)); QCOMPARE(file.read(knownData.size()), knownData); - fclose(fh); } { // 3) stdio file handling. - QFile file; - FILE *fh = fopen(QFile::encodeName(largeFile).data(), "rb"); + StdioFileGuard fh(fopen(largeFileEncoded.constData(), "rb")); + QVERIFY(fh); int fd = int(_fileno(fh)); + QFile file; QVERIFY(file.open(fd, QIODevice::ReadOnly)); QCOMPARE(file.size(), size); QVERIFY(file.seek(dataOffset)); QCOMPARE(file.read(knownData.size()), knownData); - fclose(fh); } } #endif @@ -1670,7 +1694,7 @@ void tst_QFile::bufferedRead() file.write("abcdef"); file.close(); - FILE *stdFile = fopen("stdfile.txt", "r"); + StdioFileGuard stdFile(fopen("stdfile.txt", "r")); QVERIFY(stdFile); char c; QCOMPARE(int(fread(&c, 1, 1, stdFile)), 1); @@ -1685,8 +1709,6 @@ void tst_QFile::bufferedRead() QCOMPARE(c, 'b'); QCOMPARE(file.pos(), qlonglong(2)); } - - fclose(stdFile); } #ifdef Q_OS_UNIX @@ -1815,7 +1837,7 @@ void tst_QFile::FILEReadWrite() f.close(); } - FILE *fp = fopen("FILEReadWrite.txt", "r+b"); + StdioFileGuard fp(fopen("FILEReadWrite.txt", "r+b")); QVERIFY(fp); QFile file; QVERIFY2(file.open(fp, QFile::ReadWrite), msgOpenFailed(file).constData()); @@ -1850,7 +1872,7 @@ void tst_QFile::FILEReadWrite() } file.close(); - fclose(fp); + fp.close(); // check modified file { @@ -2435,11 +2457,10 @@ void tst_QFile::virtualFile() void tst_QFile::textFile() { -#if defined(Q_OS_WIN) - FILE *fs = ::fopen("writeabletextfile", "wt"); -#else - FILE *fs = ::fopen("writeabletextfile", "w"); -#endif + const char *openMode = QOperatingSystemVersion::current().type() != QOperatingSystemVersion::Windows + ? "w" : "wt"; + StdioFileGuard fs(fopen("writeabletextfile", openMode)); + QVERIFY(fs); QFile f; QByteArray part1("This\nis\na\nfile\nwith\nnewlines\n"); QByteArray part2("Add\nsome\nmore\nnewlines\n"); @@ -2448,7 +2469,7 @@ void tst_QFile::textFile() f.write(part1); f.write(part2); f.close(); - ::fclose(fs); + fs.close(); QFile file("writeabletextfile"); QVERIFY2(file.open(QIODevice::ReadOnly), msgOpenFailed(file).constData()); @@ -2704,11 +2725,12 @@ void tst_QFile::handle() //test round trip of adopted stdio file handle QFile file2; - FILE *fp = fopen(qPrintable(m_testSourceFile), "r"); + StdioFileGuard fp(fopen(qPrintable(m_testSourceFile), "r")); + QVERIFY(fp); file2.open(fp, QIODevice::ReadOnly); QCOMPARE(int(file2.handle()), int(fileno(fp))); QCOMPARE(int(file2.handle()), int(fileno(fp))); - fclose(fp); + fp.close(); //test round trip of adopted posix file handle #ifdef Q_OS_UNIX -- cgit v1.2.3 From 1c3dc8cfb8e72770d56f2fbe131adbfe542a51c7 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 25 Oct 2017 13:57:26 +0200 Subject: tst_QFile::largeUncFileSupport(): Use QTRY_VERIFY() to open the file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Open failures due to sharing violations have been observed in Coin. Change-Id: If7fbe01a454b3c343c0b87f73db50c28eae901c3 Reviewed-by: Edward Welbourne Reviewed-by: JÄ™drzej Nowacki --- tests/auto/corelib/io/qfile/tst_qfile.cpp | 36 ++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 450229e01e..5f3ebeadd7 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -1615,6 +1615,27 @@ void tst_QFile::writeTextFile() } #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) +// Helper for executing QFile::open() with warning in QTRY_VERIFY(), which evaluates the condition +// multiple times +static bool qFileOpen(QFile &file, QIODevice::OpenMode ioFlags) +{ + const bool result = file.isOpen() || file.open(ioFlags); + if (!result) + qWarning() << "Cannot open" << file.fileName() << ':' << file.errorString(); + return result; +} + +// Helper for executing fopen() with warning in QTRY_VERIFY(), which evaluates the condition +// multiple times +static bool fOpen(const QByteArray &fileName, const char *mode, FILE **file) +{ + if (*file == nullptr) + *file = fopen(fileName.constData(), mode); + if (*file == nullptr) + qWarning("Cannot open %s: %s", fileName.constData(), strerror(errno)); + return *file != nullptr; +} + void tst_QFile::largeUncFileSupport() { qint64 size = Q_INT64_C(8589934592); @@ -1629,15 +1650,18 @@ void tst_QFile::largeUncFileSupport() QVERIFY2(file.exists(), msgFileDoesNotExist(largeFile)); QCOMPARE(file.size(), size); - QVERIFY2(file.open(QIODevice::ReadOnly), msgOpenFailed(file).constData()); + // Retry in case of sharing violation + QTRY_VERIFY2(qFileOpen(file, QIODevice::ReadOnly), msgOpenFailed(file).constData()); QCOMPARE(file.size(), size); QVERIFY(file.seek(dataOffset)); QCOMPARE(file.read(knownData.size()), knownData); } { // 2) stdlib file handling. - StdioFileGuard fh(fopen(largeFileEncoded.constData(), "rb")); - QVERIFY(fh); + FILE *fhF = nullptr; + // Retry in case of sharing violation + QTRY_VERIFY(fOpen(largeFileEncoded, "rb", &fhF)); + StdioFileGuard fh(fhF); QFile file; QVERIFY(file.open(fh, QIODevice::ReadOnly)); QCOMPARE(file.size(), size); @@ -1646,8 +1670,10 @@ void tst_QFile::largeUncFileSupport() } { // 3) stdio file handling. - StdioFileGuard fh(fopen(largeFileEncoded.constData(), "rb")); - QVERIFY(fh); + FILE *fhF = nullptr; + // Retry in case of sharing violation + QTRY_VERIFY(fOpen(largeFileEncoded, "rb", &fhF)); + StdioFileGuard fh(fhF); int fd = int(_fileno(fh)); QFile file; QVERIFY(file.open(fd, QIODevice::ReadOnly)); -- cgit v1.2.3 From 9f0dda29d5d070f63b7f098139f01f07ec91ffdf Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 27 Oct 2017 10:24:19 +0200 Subject: Windows QPA: Restrict warning about geometry failure Print warning only for visible windows or in debug mode. Task-number: QTBUG-63661 Change-Id: I742c86afcb40455074a6de753b0b1ce6a11d55af Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowswindow.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 16c2e16d64..402009c70d 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -66,6 +66,7 @@ #include #include +#include #include @@ -1473,7 +1474,7 @@ void QWindowsWindow::setGeometry(const QRect &rectIn) // achieve that size (for example, window title minimal constraint), // notify and warn. setGeometry_sys(rect); - if (m_data.geometry != rect) { + if (m_data.geometry != rect && (isVisible() || QLibraryInfo::isDebugBuild())) { qWarning("%s: Unable to set geometry %dx%d+%d+%d on %s/'%s'." " Resulting geometry: %dx%d+%d+%d " "(frame: %d, %d, %d, %d, custom margin: %d, %d, %d, %d" -- cgit v1.2.3 From 38a0909d4ed39b49e0463bd780d20a82ea672d35 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 20 Oct 2017 12:42:29 +0200 Subject: tst_qnetworkreply: Replace insignificant_test with blacklisting Neither the exit crash of QTBUG-21102 nor the Windows failure of QTBUG-24226 appear to be reproduceable. Add verbose error reporting to getErrors() and blacklist getErrors:ftp-host which has been found to fail with timeouts on Linux and ioHttpRedirectMultipartPost. Task-number: QTBUG-21102 Task-number: QTBUG-24226 Task-number: QTBUG-62860 Change-Id: I6b29f6184e83de8ffebf6ff0d80606512dca6419 Reviewed-by: Timur Pocheptsov --- tests/auto/network/access/qnetworkreply/BLACKLIST | 20 ++++++++++++++++++++ .../auto/network/access/qnetworkreply/test/test.pro | 3 --- .../access/qnetworkreply/tst_qnetworkreply.cpp | 13 ++++++++++++- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index 1d56c78bbc..f2ccefb9d6 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -1,5 +1,7 @@ # See qtbase/src/testlib/qtestblacklist.cpp for format osx +[authenticationCacheAfterCancel] +windows [ioGetFromBuiltinHttp:http+limited] ubuntu-14.04 [ioGetFromBuiltinHttp:https+limited] @@ -8,3 +10,21 @@ ubuntu-14.04 * [backgroundRequestInterruption:ftp, bg, nobg] * +[getErrors:ftp-host] +linux +[getFromHttpIntoBuffer] +windows +[getFromHttpIntoBuffer2] +windows +[headFromHttp] +windows +[ioGetFromHttpWithSocksProxy] +windows +[ioPostToHttpFromSocket] +windows +[ioHttpRedirectMultipartPost] +linux +[putWithServerClosingConnectionImmediately] +windows +[qtbug28035browserDoesNotLoadQtProjectOrgCorrectly] +windows diff --git a/tests/auto/network/access/qnetworkreply/test/test.pro b/tests/auto/network/access/qnetworkreply/test/test.pro index 0dcf5a250c..1f45ac0c49 100644 --- a/tests/auto/network/access/qnetworkreply/test/test.pro +++ b/tests/auto/network/access/qnetworkreply/test/test.pro @@ -13,7 +13,4 @@ RESOURCES += ../qnetworkreply.qrc TESTDATA += ../empty ../rfc3252.txt ../resource ../bigfile ../*.jpg ../certs \ ../index.html ../smb-file.txt -qtConfig(xcb): CONFIG+=insignificant_test # unstable, QTBUG-21102 -win32:CONFIG += insignificant_test # QTBUG-24226 - !winrt: TEST_HELPER_INSTALLS = ../echo/echo diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 93afca3d48..099ea8ff39 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -1994,6 +1994,16 @@ void tst_QNetworkReply::getErrors_data() << int(QNetworkReply::AuthenticationRequiredError) << 401 << false; } +static QByteArray msgGetErrors(int waitResult, const QNetworkReplyPtr &reply) +{ + QByteArray result ="waitResult=" + QByteArray::number(waitResult); + if (reply->isFinished()) + result += ", finished"; + if (reply->error() != QNetworkReply::NoError) + result += ", error: " + QByteArray::number(int(reply->error())); + return result; +} + void tst_QNetworkReply::getErrors() { QFETCH(QString, url); @@ -2023,7 +2033,8 @@ void tst_QNetworkReply::getErrors() QCOMPARE(reply->error(), QNetworkReply::NoError); // now run the request: - QVERIFY(waitForFinish(reply) != Timeout); + const int waitResult = waitForFinish(reply); + QVERIFY2(waitResult != Timeout, msgGetErrors(waitResult, reply)); QFETCH(int, error); QEXPECT_FAIL("ftp-is-dir", "QFtp cannot provide enough detail", Abort); -- cgit v1.2.3 From 01c7b474f5ad2c9fcf4b90c71048624070811618 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 26 Oct 2017 11:01:11 +0200 Subject: tst_QMenuBar: Port to QWindow-based mouse test API Add some helpers to convert the coordinates and change the code to use the QWindow-based mouse test API. Remove mouse presses on the second and third menu from task256322_highlight() since moving the mouse is sufficient to switch menus. Remove blacklisting/skipping of macOS and offscreen. Task-number: QTBUG-63988 Change-Id: If3e94170d11df369aec199d13d54d39382a78723 Reviewed-by: Gatis Paeglis --- tests/auto/widgets/widgets/qmenubar/BLACKLIST | 2 - .../auto/widgets/widgets/qmenubar/tst_qmenubar.cpp | 71 +++++++++++----------- 2 files changed, 37 insertions(+), 36 deletions(-) diff --git a/tests/auto/widgets/widgets/qmenubar/BLACKLIST b/tests/auto/widgets/widgets/qmenubar/BLACKLIST index ee08086e83..e2194e69ca 100644 --- a/tests/auto/widgets/widgets/qmenubar/BLACKLIST +++ b/tests/auto/widgets/widgets/qmenubar/BLACKLIST @@ -1,5 +1,3 @@ [check_menuPosition] ubuntu-14.04 ubuntu-16.04 -[task256322_highlight] -osx diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp index bc50e4f1d8..12afb77281 100644 --- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp @@ -48,6 +48,18 @@ QT_FORWARD_DECLARE_CLASS(QMainWindow) #include +// Helper to calculate the action position in window coordinates +static inline QPoint widgetToWindowPos(const QWidget *w, const QPoint &pos) +{ + const QWindow *window = w->window()->windowHandle(); + Q_ASSERT(window); + return window->mapFromGlobal(w->mapToGlobal(pos)); +} + +static QPoint menuBarActionWindowPos(const QMenuBar *mb, QAction *a) +{ + return widgetToWindowPos(mb, mb->actionGeometry(a).center()); +} class Menu : public QMenu { @@ -1194,21 +1206,19 @@ void tst_QMenuBar::check_menuPosition() menu.close(); } -# ifndef QT_NO_CURSOR // QTBUG-28031: Click at bottom-right corner. { w.move(400, 200); LayoutDirectionSaver directionSaver(Qt::RightToLeft); QMenuBar *mb = w.menuBar(); - const QPoint localPos = mb->actionGeometry(menu.menuAction()).bottomRight() - QPoint(1, 1); - const QPoint globalPos = mb->mapToGlobal(localPos); - QCursor::setPos(globalPos); - QTest::mouseClick(mb, Qt::LeftButton, 0, localPos); + const QPoint bottomRight = mb->actionGeometry(menu.menuAction()).bottomRight() - QPoint(1, 1); + const QPoint localPos = widgetToWindowPos(mb, bottomRight); + const QPoint globalPos = w.mapToGlobal(localPos); + QTest::mouseClick(w.windowHandle(), Qt::LeftButton, 0, localPos); QTRY_VERIFY(menu.isActiveWindow()); QCOMPARE(menu.geometry().right() - 1, globalPos.x()); menu.close(); } -# endif // QT_NO_CURSOR } #endif @@ -1246,10 +1256,8 @@ void tst_QMenuBar::task223138_triggered() void tst_QMenuBar::task256322_highlight() { - if (!QGuiApplication::platformName().compare(QLatin1String("minimal"), Qt::CaseInsensitive) - || !QGuiApplication::platformName().compare(QLatin1String("offscreen"), Qt::CaseInsensitive)) { - QSKIP("Highlighting does not work correctly for minimal/offscreen platforms"); - } + if (!QGuiApplication::platformName().compare(QLatin1String("minimal"), Qt::CaseInsensitive)) + QSKIP("Highlighting does not work correctly for minimal platform"); QMainWindow win; win.menuBar()->setNativeMenuBar(false); //we can't check the geometry of native menubars @@ -1266,31 +1274,26 @@ void tst_QMenuBar::task256322_highlight() QApplication::setActiveWindow(&win); QVERIFY(QTest::qWaitForWindowActive(&win)); - QTest::mousePress(win.menuBar(), Qt::LeftButton, 0, win.menuBar()->actionGeometry(file).center()); - QTest::mouseMove(win.menuBar(), win.menuBar()->actionGeometry(file).center()); - QTest::mouseRelease(win.menuBar(), Qt::LeftButton, 0, win.menuBar()->actionGeometry(file).center()); + const QPoint filePos = menuBarActionWindowPos(win.menuBar(), file); + QWindow *window = win.windowHandle(); + QTest::mousePress(window, Qt::LeftButton, 0, filePos); + QTest::mouseMove(window, filePos); + QTest::mouseRelease(window, Qt::LeftButton, 0, filePos); QTRY_VERIFY(menu.isVisible()); QVERIFY(!menu2.isVisible()); QCOMPARE(win.menuBar()->activeAction(), file); - QTest::mousePress(win.menuBar(), Qt::LeftButton, 0, win.menuBar()->actionGeometry(file2).center()); - QTest::mouseMove(win.menuBar(), win.menuBar()->actionGeometry(file2).center()); + const QPoint file2Pos = menuBarActionWindowPos(win.menuBar(), file2); + QTest::mouseMove(window, file2Pos); QTRY_VERIFY(!menu.isVisible()); - QVERIFY(menu2.isVisible()); + QTRY_VERIFY(menu2.isVisible()); QCOMPARE(win.menuBar()->activeAction(), file2); - QTest::mouseRelease(win.menuBar(), Qt::LeftButton, 0, win.menuBar()->actionGeometry(file2).center()); - QPoint nothingCenter = win.menuBar()->actionGeometry(nothing).center(); - QTest::mousePress(win.menuBar(), Qt::LeftButton, 0, nothingCenter); - QTest::mouseMove(win.menuBar(), nothingCenter); + QPoint nothingCenter = menuBarActionWindowPos(win.menuBar(), nothing); + QTest::mouseMove(window, nothingCenter); QTRY_VERIFY(!menu2.isVisible()); QVERIFY(!menu.isVisible()); -#ifdef Q_OS_MAC - if (win.menuBar()->activeAction() != nothing) - QEXPECT_FAIL("", "QTBUG-30565: Unstable test", Continue); -#endif QTRY_COMPARE(win.menuBar()->activeAction(), nothing); - QTest::mouseRelease(win.menuBar(), Qt::LeftButton, 0, nothingCenter); } void tst_QMenuBar::menubarSizeHint() @@ -1427,9 +1430,6 @@ void tst_QMenuBar::closeOnSecondClickAndOpenOnThirdClick() // QTBUG-32807, menu QMainWindow mainWindow; mainWindow.resize(300, 200); centerOnScreen(&mainWindow); -#ifndef QT_NO_CURSOR - QCursor::setPos(mainWindow.geometry().topLeft() - QPoint(100, 0)); -#endif QMenuBar *menuBar = mainWindow.menuBar(); menuBar->setNativeMenuBar(false); QMenu *fileMenu = menuBar->addMenu(QStringLiteral("OpenCloseOpen")); @@ -1437,14 +1437,17 @@ void tst_QMenuBar::closeOnSecondClickAndOpenOnThirdClick() // QTBUG-32807, menu mainWindow.show(); QApplication::setActiveWindow(&mainWindow); QVERIFY(QTest::qWaitForWindowActive(&mainWindow)); - const QPoint center = menuBar->actionGeometry(fileMenu->menuAction()).center(); - const QPoint globalPos = menuBar->mapToGlobal(center); - QTest::mouseMove(menuBar, center); - QTest::mouseClick(menuBar, Qt::LeftButton, 0, center); + + const QPoint center = menuBarActionWindowPos(mainWindow.menuBar(), fileMenu->menuAction()); + const QPoint globalPos = mainWindow.mapToGlobal(center); + + QWindow *window = mainWindow.windowHandle(); + QTest::mouseMove(window, center); + QTest::mouseClick(window, Qt::LeftButton, 0, center); QTRY_VERIFY(fileMenu->isVisible()); - QTest::mouseClick(fileMenu, Qt::LeftButton, 0, fileMenu->mapFromGlobal(globalPos)); + QTest::mouseClick(window, Qt::LeftButton, 0, fileMenu->mapFromGlobal(globalPos)); QTRY_VERIFY(!fileMenu->isVisible()); - QTest::mouseClick(menuBar, Qt::LeftButton, 0, center); + QTest::mouseClick(window, Qt::LeftButton, 0, center); QTRY_VERIFY(fileMenu->isVisible()); } -- cgit v1.2.3 From 1a647926528136850c8a0e4c2aa5ae23e22172ea Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 30 Oct 2017 09:58:15 +0100 Subject: tst_QTcpSocket::suddenRemoteDisconnect - fix flakyness This test starts two processes - server and client - and requires an external executable ('stressTest'). In .pro file we have SUBDIRS containing both 'test' (test itself) and 'stressTest' (client/server app), but there is no explicit dependency and as result we run the test before we build 'stressTest' thus failing to start those processes. This patch makes 'test' dependent on 'stressTest'. Task-number: QTBUG-36629 Change-Id: I286b08bcff86b9afc4bbee87a75e887527eaf5f2 Reviewed-by: Gatis Paeglis --- tests/auto/network/socket/qtcpsocket/qtcpsocket.pro | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/auto/network/socket/qtcpsocket/qtcpsocket.pro b/tests/auto/network/socket/qtcpsocket/qtcpsocket.pro index 1183b23556..1f13a396dd 100644 --- a/tests/auto/network/socket/qtcpsocket/qtcpsocket.pro +++ b/tests/auto/network/socket/qtcpsocket/qtcpsocket.pro @@ -1,6 +1,8 @@ TEMPLATE = subdirs SUBDIRS = test -!vxworks: SUBDIRS += stressTest - +!vxworks{ +SUBDIRS += stressTest +test.depends = stressTest +} requires(qtConfig(private_tests)) -- cgit v1.2.3 From b409cfa094c327cae0303c6fff39ae5dbb49ad80 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 30 Oct 2017 11:18:44 +0100 Subject: tst_QNetworkReply::ioHttpRedirectPolicy - blacklist for b2qt 64bit This test fails often and seems to be flaky. Task-number: QTBUG-62583 Change-Id: Id3af283c89e392634a7af6e11bd05775a4295798 Reviewed-by: Gatis Paeglis --- tests/auto/network/access/qnetworkreply/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index f2ccefb9d6..5edae13e34 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -24,6 +24,8 @@ windows windows [ioHttpRedirectMultipartPost] linux +[ioHttpRedirectPolicy] +b2qt 64bit [putWithServerClosingConnectionImmediately] windows [qtbug28035browserDoesNotLoadQtProjectOrgCorrectly] -- cgit v1.2.3 From acdb3340321d1b8823b54f2ea492f975c6f942d8 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 27 Oct 2017 08:36:25 +0200 Subject: Fix dragging inside a modal window when a QShapedPixmapWindow is used A regression was introduced with a3d59c7c7f675b0a4e128efeb781aa1c2f7db4c0 which caused dragging to fail within a modal dialog on the XCB platform. By adding an exception for the QShapedPixmapWindow, which is the window used for the drag, we can allow that to continue to work whilst blocking to the other newly created windows. Task-number: QTBUG-63846 Change-Id: I7c7f365f30fcf5f04f50dc1a7fff7a09e6e5ed6c Reviewed-by: Richard Moe Gustavsen --- src/gui/kernel/qwindow.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 43b201e9b0..9e5b687851 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -54,6 +54,7 @@ # include "qaccessible.h" #endif #include "qhighdpiscaling_p.h" +#include "qshapedpixmapdndwindow_p.h" #include @@ -576,7 +577,9 @@ void QWindow::setVisible(bool visible) QGuiApplicationPrivate::showModalWindow(this); else QGuiApplicationPrivate::hideModalWindow(this); - } else if (visible && QGuiApplication::modalWindow()) { + // QShapedPixmapWindow is used on some platforms for showing a drag pixmap, so don't block + // input to this window as it is performing a drag - QTBUG-63846 + } else if (visible && QGuiApplication::modalWindow() && !qobject_cast(this)) { QGuiApplicationPrivate::updateBlockedStatus(this); } -- cgit v1.2.3 From 3a92f7cf4f1abd7ad91bdfc7251b1f3e82bdf89f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 25 Oct 2017 15:43:30 +0200 Subject: macOS: Retain NSWindow during event delivery We have logic to deal with self.platformWindow and frame strut mouse events which happens after delivering the event to the NSWindow, but delivering it might dealloc the window, e.g. when closing it, so we need to explicitly retain it for the duration of [QNSWindow sendEvent:] Task-number: QTBUG-64023 Change-Id: I223fe3e3ac36a309da375522ba11f20f1ad6fc4f Reviewed-by: Timur Pocheptsov Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qnswindow.mm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm index 799704a407..5213008bd4 100644 --- a/src/plugins/platforms/cocoa/qnswindow.mm +++ b/src/plugins/platforms/cocoa/qnswindow.mm @@ -185,6 +185,10 @@ static bool isMouseEvent(NSEvent *ev) if (!self.platformWindow) return; + // Prevent deallocation of this NSWindow during event delivery, as we + // have logic further below that depends on the window being alive. + [[self retain] autorelease]; + const char *eventType = object_getClassName(theEvent); if (QWindowSystemInterface::handleNativeEvent(self.platformWindow->window(), QByteArray::fromRawData(eventType, qstrlen(eventType)), theEvent, nullptr)) { @@ -221,6 +225,7 @@ static bool isMouseEvent(NSEvent *ev) #pragma clang diagnostic ignored "-Wobjc-missing-super-calls" - (void)dealloc { + qCDebug(lcQpaCocoaWindow) << "dealloc" << self; qt_objcDynamicSuper(); } #pragma clang diagnostic pop -- cgit v1.2.3 From f4090b23b98c132c47237e4695bc4dc93170cbe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 25 Oct 2017 13:05:49 +0200 Subject: macOS: Add categorized logging of event and notification forwarding Useful for debugging issues in this area. Change-Id: Ic343ef790e20b66371028265efe2ec1816c954bd Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoawindow.mm | 17 ++++++++++++++++- src/plugins/platforms/cocoa/qnswindow.mm | 20 ++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index ed942af1b1..af44564968 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -79,6 +79,8 @@ static void qt_closePopups() } } +Q_LOGGING_CATEGORY(lcCocoaNotifications, "qt.qpa.cocoa.notifications"); + static void qRegisterNotificationCallbacks() { static const QLatin1String notificationHandlerPrefix(Q_NOTIFICATION_PREFIX); @@ -110,11 +112,24 @@ static void qRegisterNotificationCallbacks() if (QNSView *qnsView = qnsview_cast(notification.object)) cocoaWindows += qnsView.platformWindow; } else { - qCWarning(lcQpaCocoaWindow) << "Unhandled notifcation" + qCWarning(lcCocoaNotifications) << "Unhandled notifcation" << notification.name << "for" << notification.object; return; } + if (lcCocoaNotifications().isDebugEnabled()) { + if (cocoaWindows.isEmpty()) { + qCDebug(lcCocoaNotifications) << "Could not find forwarding target for" << + qPrintable(notificationName) << "from" << notification.object; + } else { + QVector debugWindows; + for (QCocoaWindow *cocoaWindow : cocoaWindows) + debugWindows += cocoaWindow; + qCDebug(lcCocoaNotifications) << "Forwarding" << qPrintable(notificationName) << + "to" << debugWindows; + } + } + // FIXME: Could be a foreign window, look up by iterating top level QWindows for (QCocoaWindow *cocoaWindow : cocoaWindows) { diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm index 5213008bd4..e846fa043c 100644 --- a/src/plugins/platforms/cocoa/qnswindow.mm +++ b/src/plugins/platforms/cocoa/qnswindow.mm @@ -46,6 +46,8 @@ #include #include +Q_LOGGING_CATEGORY(lcCocoaEvents, "qt.qpa.cocoa.events"); + static bool isMouseEvent(NSEvent *ev) { switch ([ev type]) { @@ -116,6 +118,22 @@ static bool isMouseEvent(NSEvent *ev) return qnsview_cast(self.contentView).platformWindow; } +- (NSString *)description +{ + NSMutableString *description = [NSMutableString stringWithString:qt_objcDynamicSuper()]; + +#ifndef QT_NO_DEBUG_STREAM + QString contentViewDescription; + QDebug debug(&contentViewDescription); + debug.nospace() << "; contentView=" << qnsview_cast(self.contentView) << ">"; + + NSRange lastCharacter = [description rangeOfComposedCharacterSequenceAtIndex:description.length - 1]; + [description replaceCharactersInRange:lastCharacter withString:contentViewDescription.toNSString()]; +#endif + + return description; +} + - (BOOL)canBecomeKeyWindow { QCocoaWindow *pw = self.platformWindow; @@ -177,6 +195,8 @@ static bool isMouseEvent(NSEvent *ev) - (void)sendEvent:(NSEvent*)theEvent { + qCDebug(lcCocoaEvents) << "Sending" << theEvent << "to" << self; + // We might get events for a NSWindow after the corresponding platform // window has been deleted, as the NSWindow can outlive the QCocoaWindow // e.g. if being retained by other parts of AppKit, or in an auto-release -- cgit v1.2.3 From 196f295b928fd67c931b55fde5f6097e4cc3c78f Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Mon, 23 Oct 2017 15:42:52 +0200 Subject: Fix shadow prefix framework builds Bundle data source files which don't exist at qmake time need to be handled specially. This also required splitting the generated list of public headers, as was already done for private ones. Task-number: QTBUG-60413 Change-Id: I97acfa88622da6b73839b8f976f73ace3cb10223 Reviewed-by: Oswald Buddenhagen --- bin/syncqt.pl | 21 ++++++++++++++------- mkspecs/features/qt_installs.prf | 2 +- mkspecs/features/qt_module.prf | 10 +++++++++- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/bin/syncqt.pl b/bin/syncqt.pl index d62ffcbc37..e741f22f65 100755 --- a/bin/syncqt.pl +++ b/bin/syncqt.pl @@ -925,6 +925,7 @@ foreach my $lib (@modules_to_sync) { #information used after the syncing my $pri_install_classes = ""; my $pri_install_files = ""; + my $pri_install_ifiles = ""; my $pri_install_pfiles = ""; my $pri_install_ipfiles = ""; my $pri_install_qpafiles = ""; @@ -1080,11 +1081,7 @@ foreach my $lib (@modules_to_sync) { my $pri_install_iheader = fixPaths($iheader, $dir); my $injection = ""; - if($public_header) { - #put it into the master file - $master_contents{$public_header} = $requires if (!$shadow && shouldMasterInclude($iheader)); - - #deal with the install directives + if ($public_header) { foreach my $class (@classes) { # Strip namespaces: $class =~ s/^.*:://; @@ -1096,8 +1093,17 @@ foreach my $lib (@modules_to_sync) { unless($pri_install_classes =~ $class_header); $injection .= ":$class"; } - $pri_install_files.= "$pri_install_iheader ";; - $pri_clean_files .= "$pri_install_iheader".($requires ? ":".$requires : "")." " if ($clean_header); + + if ($shadow) { + $pri_install_ifiles .= "$pri_install_iheader "; + } else { + # put it into the master file + $master_contents{$public_header} = $requires if (shouldMasterInclude($iheader)); + + # deal with the install directives + $pri_install_files .= "$pri_install_iheader "; + $pri_clean_files .= "$pri_install_iheader".($requires ? ":".$requires : "")." " if ($clean_header); + } } elsif ($qpa_header) { $pri_install_qpafiles.= "$pri_install_iheader ";; @@ -1247,6 +1253,7 @@ foreach my $lib (@modules_to_sync) { #handle the headers.pri for each module my $headers_pri_contents = ""; $headers_pri_contents .= "SYNCQT.HEADER_FILES = $pri_install_files\n"; + $headers_pri_contents .= "SYNCQT.INJECTED_HEADER_FILES = $pri_install_ifiles\n"; $headers_pri_contents .= "SYNCQT.HEADER_CLASSES = $pri_install_classes\n"; $headers_pri_contents .= "SYNCQT.PRIVATE_HEADER_FILES = $pri_install_pfiles\n"; $headers_pri_contents .= "SYNCQT.INJECTED_PRIVATE_HEADER_FILES = $pri_install_ipfiles\n"; diff --git a/mkspecs/features/qt_installs.prf b/mkspecs/features/qt_installs.prf index 0d3dfb6b93..90d84cc535 100644 --- a/mkspecs/features/qt_installs.prf +++ b/mkspecs/features/qt_installs.prf @@ -32,7 +32,7 @@ qt_install_headers { class_headers.path = $$[QT_INSTALL_HEADERS]/$$MODULE_INCNAME INSTALLS += class_headers - targ_headers.files = $$SYNCQT.HEADER_FILES + targ_headers.files = $$SYNCQT.HEADER_FILES $$SYNCQT.INJECTED_HEADER_FILES targ_headers.path = $$[QT_INSTALL_HEADERS]/$$MODULE_INCNAME INSTALLS += targ_headers diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index 8a8c17f01b..a5c40a7899 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -136,9 +136,17 @@ lib_bundle { if(if(!debug_and_release|CONFIG(release, debug|release))) { FRAMEWORK_HEADERS.version = Versions FRAMEWORK_HEADERS.files = $$SYNCQT.HEADER_FILES $$SYNCQT.HEADER_CLASSES + # Non-existing paths (yet, they will be generated) are used verbatim. + for (injected_header, SYNCQT.INJECTED_HEADER_FILES): \ + FRAMEWORK_HEADERS.files += \ + $$relative_path($$absolute_path($$injected_header, $$_PRO_FILE_PWD_), $$OUT_PWD) + FRAMEWORK_HEADERS.path = Headers FRAMEWORK_PRIVATE_HEADERS.version = Versions - FRAMEWORK_PRIVATE_HEADERS.files = $$SYNCQT.PRIVATE_HEADER_FILES $$SYNCQT.INJECTED_PRIVATE_HEADER_FILES + FRAMEWORK_PRIVATE_HEADERS.files = $$SYNCQT.PRIVATE_HEADER_FILES + for (injected_header, SYNCQT.INJECTED_PRIVATE_HEADER_FILES): \ + FRAMEWORK_PRIVATE_HEADERS.files += \ + $$relative_path($$absolute_path($$injected_header, $$_PRO_FILE_PWD_), $$OUT_PWD) FRAMEWORK_PRIVATE_HEADERS.path = Headers/$$VERSION/$$MODULE_INCNAME/private FRAMEWORK_QPA_HEADERS.version = Versions FRAMEWORK_QPA_HEADERS.files = $$SYNCQT.QPA_HEADER_FILES -- cgit v1.2.3 From e6fb36389e7f69e852c10c79d0af72f85ade300b Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Tue, 24 Oct 2017 18:59:55 +0200 Subject: QDateTimeParser: Remove unused variable Change-Id: Iaa6460d4eb96632f3cb03bc29b57934c53cbf88e Reviewed-by: Jesus Fernandez Reviewed-by: Edward Welbourne --- src/corelib/tools/qdatetimeparser.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 978b663444..dd277f7753 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -1090,7 +1090,6 @@ QDateTimeParser::scanString(const QDateTime &defaultValue, int dayofweek = defaultDate.dayOfWeek(); Qt::TimeSpec tspec = defaultValue.timeSpec(); int zoneOffset = 0; // In seconds; local - UTC - QString zoneName; QTimeZone timeZone; switch (tspec) { case Qt::OffsetFromUTC: // timeZone is ignored -- cgit v1.2.3 From 6ca6efb22aae2c80868c5d0d8f50b55505cfc0d6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 21 Aug 2017 16:16:20 -0700 Subject: Fix unused variable warning when compiling in release mode with GCC 7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit error: unused variable ‘ret’ [-Werror=unused-variable] Change-Id: I6e9274c1e7444ad48c81fffd14dcff9278d4376b Reviewed-by: Lars Knoll --- src/corelib/global/qrandom.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index 0bbe79aeb4..9abb9ece7f 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -138,11 +138,13 @@ public: // getentropy can't fail under normal circumstances int ret = getentropy(reinterpret_cast(buffer) + read, 256); Q_ASSERT(ret == 0); + Q_UNUSED(ret); read += 256; } int ret = getentropy(reinterpret_cast(buffer) + read, count - read); Q_ASSERT(ret == 0); + Q_UNUSED(ret); return count; } }; -- cgit v1.2.3 From 38bc9956079e2291d19b15d68cc2e6dd4a20f202 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 31 Oct 2017 09:21:44 +0100 Subject: Fix redundant Vulkan logging category definition Task-number: QTBUG-64124 Change-Id: Ic8f9a7f62e3c00dba5f345037c45fb45908be848 Reviewed-by: Andy Nichols --- src/gui/vulkan/qvulkanwindow.cpp | 44 +++++++++++----------- .../vkconvenience/qbasicvulkanplatforminstance.cpp | 12 +++--- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/gui/vulkan/qvulkanwindow.cpp b/src/gui/vulkan/qvulkanwindow.cpp index bc82f5df08..7dea743ea8 100644 --- a/src/gui/vulkan/qvulkanwindow.cpp +++ b/src/gui/vulkan/qvulkanwindow.cpp @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE -Q_LOGGING_CATEGORY(lcVk, "qt.vulkan") +Q_LOGGING_CATEGORY(lcGuiVk, "qt.vulkan") /*! \class QVulkanWindow @@ -357,7 +357,7 @@ QVector QVulkanWindow::availablePhysicalDevices() return d->physDevProps; } - qCDebug(lcVk, "%d physical devices", count); + qCDebug(lcGuiVk, "%d physical devices", count); if (!count) return d->physDevProps; @@ -373,7 +373,7 @@ QVector QVulkanWindow::availablePhysicalDevices() for (uint32_t i = 0; i < count; ++i) { VkPhysicalDeviceProperties *p = &d->physDevProps[i]; f->vkGetPhysicalDeviceProperties(d->physDevs.at(i), p); - qCDebug(lcVk, "Physical device [%d]: name '%s' version %d.%d.%d", i, p->deviceName, + qCDebug(lcGuiVk, "Physical device [%d]: name '%s' version %d.%d.%d", i, p->deviceName, VK_VERSION_MAJOR(p->driverVersion), VK_VERSION_MINOR(p->driverVersion), VK_VERSION_PATCH(p->driverVersion)); } @@ -442,7 +442,7 @@ QVulkanInfoVector QVulkanWindow::supportedDeviceExtensions() exts.append(ext); } d->supportedDevExtensions.insert(physDev, exts); - qDebug(lcVk) << "Supported device extensions:" << exts; + qDebug(lcGuiVk) << "Supported device extensions:" << exts; return exts; } } @@ -615,7 +615,7 @@ void QVulkanWindowPrivate::init() Q_Q(QVulkanWindow); Q_ASSERT(status == StatusUninitialized); - qCDebug(lcVk, "QVulkanWindow init"); + qCDebug(lcGuiVk, "QVulkanWindow init"); inst = q->vulkanInstance(); if (!inst) { @@ -648,7 +648,7 @@ void QVulkanWindowPrivate::init() qWarning("QVulkanWindow: Invalid physical device index; defaulting to 0"); physDevIndex = 0; } - qCDebug(lcVk, "Using physical device [%d]", physDevIndex); + qCDebug(lcGuiVk, "Using physical device [%d]", physDevIndex); // Give a last chance to do decisions based on the physical device and the surface. if (renderer) @@ -665,7 +665,7 @@ void QVulkanWindowPrivate::init() presQueueFamilyIdx = uint32_t(-1); for (int i = 0; i < queueFamilyProps.count(); ++i) { const bool supportsPresent = inst->supportsPresent(physDev, i, q); - qCDebug(lcVk, "queue family %d: flags=0x%x count=%d supportsPresent=%d", i, + qCDebug(lcGuiVk, "queue family %d: flags=0x%x count=%d supportsPresent=%d", i, queueFamilyProps[i].queueFlags, queueFamilyProps[i].queueCount, supportsPresent); if (gfxQueueFamilyIdx == uint32_t(-1) && (queueFamilyProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) @@ -675,7 +675,7 @@ void QVulkanWindowPrivate::init() if (gfxQueueFamilyIdx != uint32_t(-1)) { presQueueFamilyIdx = gfxQueueFamilyIdx; } else { - qCDebug(lcVk, "No queue with graphics+present; trying separate queues"); + qCDebug(lcGuiVk, "No queue with graphics+present; trying separate queues"); for (int i = 0; i < queueFamilyProps.count(); ++i) { if (gfxQueueFamilyIdx == uint32_t(-1) && (queueFamilyProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)) gfxQueueFamilyIdx = i; @@ -698,7 +698,7 @@ void QVulkanWindowPrivate::init() if (qEnvironmentVariableIsSet("QT_VK_PRESENT_QUEUE_INDEX")) presQueueFamilyIdx = qEnvironmentVariableIntValue("QT_VK_PRESENT_QUEUE_INDEX"); #endif - qCDebug(lcVk, "Using queue families: graphics = %u present = %u", gfxQueueFamilyIdx, presQueueFamilyIdx); + qCDebug(lcGuiVk, "Using queue families: graphics = %u present = %u", gfxQueueFamilyIdx, presQueueFamilyIdx); VkDeviceQueueCreateInfo queueInfo[2]; const float prio[] = { 0 }; @@ -724,7 +724,7 @@ void QVulkanWindowPrivate::init() if (supportedExtensions.contains(ext)) devExts.append(ext.constData()); } - qCDebug(lcVk) << "Enabling device extensions:" << devExts; + qCDebug(lcGuiVk) << "Enabling device extensions:" << devExts; VkDeviceCreateInfo devInfo; memset(&devInfo, 0, sizeof(devInfo)); @@ -774,7 +774,7 @@ void QVulkanWindowPrivate::init() physDevs.clear(); physDevProps.clear(); status = StatusUninitialized; - qCDebug(lcVk, "Attempting to restart in 2 seconds"); + qCDebug(lcGuiVk, "Attempting to restart in 2 seconds"); QTimer::singleShot(2000, q, [this]() { ensureStarted(); }); return; } @@ -819,7 +819,7 @@ void QVulkanWindowPrivate::init() f->vkGetPhysicalDeviceMemoryProperties(physDev, &physDevMemProps); for (uint32_t i = 0; i < physDevMemProps.memoryTypeCount; ++i) { const VkMemoryType *memType = physDevMemProps.memoryTypes; - qCDebug(lcVk, "memtype %d: flags=0x%x", i, memType[i].propertyFlags); + qCDebug(lcGuiVk, "memtype %d: flags=0x%x", i, memType[i].propertyFlags); // Find a host visible, host coherent memtype. If there is one that is // cached as well (in addition to being coherent), prefer that. const int hostVisibleAndCoherent = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; @@ -831,7 +831,7 @@ void QVulkanWindowPrivate::init() } } } - qCDebug(lcVk, "Picked memtype %d for host visible memory", hostVisibleMemIndex); + qCDebug(lcGuiVk, "Picked memtype %d for host visible memory", hostVisibleMemIndex); deviceLocalMemIndex = 0; for (uint32_t i = 0; i < physDevMemProps.memoryTypeCount; ++i) { const VkMemoryType *memType = physDevMemProps.memoryTypes; @@ -841,7 +841,7 @@ void QVulkanWindowPrivate::init() break; } } - qCDebug(lcVk, "Picked memtype %d for device local memory", deviceLocalMemIndex); + qCDebug(lcGuiVk, "Picked memtype %d for device local memory", deviceLocalMemIndex); if (!vkGetPhysicalDeviceSurfaceCapabilitiesKHR || !vkGetPhysicalDeviceSurfaceFormatsKHR) { vkGetPhysicalDeviceSurfaceCapabilitiesKHR = reinterpret_cast( @@ -906,7 +906,7 @@ void QVulkanWindowPrivate::init() if (dsFormatIdx == dsFormatCandidateCount) qWarning("QVulkanWindow: Failed to find an optimal depth-stencil format"); - qCDebug(lcVk, "Color format: %d Depth-stencil format: %d", colorFormat, dsFormat); + qCDebug(lcGuiVk, "Color format: %d Depth-stencil format: %d", colorFormat, dsFormat); if (!createDefaultRenderPass()) return; @@ -922,7 +922,7 @@ void QVulkanWindowPrivate::reset() if (!dev) // do not rely on 'status', a half done init must be cleaned properly too return; - qCDebug(lcVk, "QVulkanWindow reset"); + qCDebug(lcGuiVk, "QVulkanWindow reset"); devFuncs->vkDeviceWaitIdle(dev); @@ -1118,7 +1118,7 @@ void QVulkanWindowPrivate::recreateSwapChain() swapChainInfo.clipped = true; swapChainInfo.oldSwapchain = oldSwapChain; - qCDebug(lcVk, "Creating new swap chain of %d buffers, size %dx%d", reqBufferCount, bufferSize.width, bufferSize.height); + qCDebug(lcGuiVk, "Creating new swap chain of %d buffers, size %dx%d", reqBufferCount, bufferSize.width, bufferSize.height); VkSwapchainKHR newSwapChain; VkResult err = vkCreateSwapchainKHR(dev, &swapChainInfo, nullptr, &newSwapChain); @@ -1139,7 +1139,7 @@ void QVulkanWindowPrivate::recreateSwapChain() return; } - qCDebug(lcVk, "Actual swap chain buffer count: %d (supportsReadback=%d)", + qCDebug(lcGuiVk, "Actual swap chain buffer count: %d (supportsReadback=%d)", actualSwapChainBufferCount, swapChainSupportsReadBack); if (actualSwapChainBufferCount > MAX_SWAPCHAIN_BUFFER_COUNT) { qWarning("QVulkanWindow: Too many swapchain buffers (%d)", actualSwapChainBufferCount); @@ -1389,7 +1389,7 @@ bool QVulkanWindowPrivate::createTransientImage(VkFormat format, return false; } startIndex = memInfo.memoryTypeIndex + 1; - qCDebug(lcVk, "Allocating %u bytes for transient image (memtype %u)", + qCDebug(lcGuiVk, "Allocating %u bytes for transient image (memtype %u)", uint32_t(memInfo.allocationSize), memInfo.memoryTypeIndex); err = devFuncs->vkAllocateMemory(dev, &memInfo, nullptr, mem); if (err != VK_SUCCESS && err != VK_ERROR_OUT_OF_DEVICE_MEMORY) { @@ -1435,7 +1435,7 @@ void QVulkanWindowPrivate::releaseSwapChain() if (!dev || !swapChain) // do not rely on 'status', a half done init must be cleaned properly too return; - qCDebug(lcVk, "Releasing swapchain"); + qCDebug(lcGuiVk, "Releasing swapchain"); devFuncs->vkDeviceWaitIdle(dev); @@ -2059,10 +2059,10 @@ bool QVulkanWindowPrivate::checkDeviceLost(VkResult err) qWarning("QVulkanWindow: Device lost"); if (renderer) renderer->logicalDeviceLost(); - qCDebug(lcVk, "Releasing all resources due to device lost"); + qCDebug(lcGuiVk, "Releasing all resources due to device lost"); releaseSwapChain(); reset(); - qCDebug(lcVk, "Restarting"); + qCDebug(lcGuiVk, "Restarting"); ensureStarted(); return true; } diff --git a/src/platformsupport/vkconvenience/qbasicvulkanplatforminstance.cpp b/src/platformsupport/vkconvenience/qbasicvulkanplatforminstance.cpp index 1a2a07260a..382d142334 100644 --- a/src/platformsupport/vkconvenience/qbasicvulkanplatforminstance.cpp +++ b/src/platformsupport/vkconvenience/qbasicvulkanplatforminstance.cpp @@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE -Q_LOGGING_CATEGORY(lcVk, "qt.vulkan") +Q_LOGGING_CATEGORY(lcPlatVk, "qt.vulkan") /*! \class QBasicPlatformVulkanInstance @@ -87,7 +87,7 @@ void QBasicPlatformVulkanInstance::init(QLibrary *lib) if (m_vkGetInstanceProcAddr) return; - qCDebug(lcVk, "Vulkan init (%s)", qPrintable(lib->fileName())); + qCDebug(lcPlatVk, "Vulkan init (%s)", qPrintable(lib->fileName())); // While not strictly required with every implementation, try to follow the spec // and do not rely on core functions being exported. @@ -137,7 +137,7 @@ void QBasicPlatformVulkanInstance::init(QLibrary *lib) m_supportedLayers.append(layer); } } - qCDebug(lcVk) << "Supported Vulkan instance layers:" << m_supportedLayers; + qCDebug(lcPlatVk) << "Supported Vulkan instance layers:" << m_supportedLayers; uint32_t extCount = 0; m_vkEnumerateInstanceExtensionProperties(nullptr, &extCount, nullptr); @@ -152,7 +152,7 @@ void QBasicPlatformVulkanInstance::init(QLibrary *lib) m_supportedExtensions.append(ext); } } - qDebug(lcVk) << "Supported Vulkan instance extensions:" << m_supportedExtensions; + qDebug(lcPlatVk) << "Supported Vulkan instance extensions:" << m_supportedExtensions; } QVulkanInfoVector QBasicPlatformVulkanInstance::supportedLayers() const @@ -206,13 +206,13 @@ void QBasicPlatformVulkanInstance::initInstance(QVulkanInstance *instance, const if (!m_supportedLayers.contains(layerName)) m_enabledLayers.removeAt(i--); } - qDebug(lcVk) << "Enabling Vulkan instance layers:" << m_enabledLayers; + qDebug(lcPlatVk) << "Enabling Vulkan instance layers:" << m_enabledLayers; for (int i = 0; i < m_enabledExtensions.count(); ++i) { const QByteArray &extName(m_enabledExtensions[i]); if (!m_supportedExtensions.contains(extName)) m_enabledExtensions.removeAt(i--); } - qDebug(lcVk) << "Enabling Vulkan instance extensions:" << m_enabledExtensions; + qDebug(lcPlatVk) << "Enabling Vulkan instance extensions:" << m_enabledExtensions; VkInstanceCreateInfo instInfo; memset(&instInfo, 0, sizeof(instInfo)); -- cgit v1.2.3 From 89951262bf8bbc764ee15be53e63e0294dae15db Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 31 Oct 2017 11:58:26 +0100 Subject: Drop qvulkan headers from QtGui master header ...in order to allow applications built against Vulkan-enabled pre-built packages to include on systems without Vulkan headers. This has the downside of not being able to pull in qvulkan* headers via the master header. This is an acceptable compromise for now. Task-number: QTBUG-64073 Change-Id: I63c5834dcec60e66aba34c003d4bfe8e7d31607f Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Oswald Buddenhagen --- src/gui/vulkan/qvulkaninstance.h | 4 ++++ src/gui/vulkan/qvulkanwindow.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/gui/vulkan/qvulkaninstance.h b/src/gui/vulkan/qvulkaninstance.h index ada297be43..57459e458c 100644 --- a/src/gui/vulkan/qvulkaninstance.h +++ b/src/gui/vulkan/qvulkaninstance.h @@ -42,6 +42,10 @@ #include +#if 0 +#pragma qt_no_master_include +#endif + #if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC) #ifndef VK_NO_PROTOTYPES diff --git a/src/gui/vulkan/qvulkanwindow.h b/src/gui/vulkan/qvulkanwindow.h index 65249ecbfc..927c81042f 100644 --- a/src/gui/vulkan/qvulkanwindow.h +++ b/src/gui/vulkan/qvulkanwindow.h @@ -42,6 +42,10 @@ #include +#if 0 +#pragma qt_no_master_include +#endif + #if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC) #include -- cgit v1.2.3 From 58f46077015fc5dd71543ca25f762ff34fc12621 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 3 Nov 2017 11:02:51 +0100 Subject: QWindowPrivate::globalPosition(): Take embedded windows into account MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QPlatformWindow::mapToGlobal() should also be used in case a window is embedded. Task-number: QTBUG-64116 Change-Id: I1fbdf3d185659d0faea13a593db901e36ab27d8d Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 9969124339..369f3ea3ab 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2575,7 +2575,7 @@ QPoint QWindowPrivate::globalPosition() const QPoint offset = q->position(); for (const QWindow *p = q->parent(); p; p = p->parent()) { QPlatformWindow *pw = p->handle(); - if (pw && pw->isForeignWindow()) { + if (pw && (pw->isForeignWindow() || pw->isEmbedded())) { // Use mapToGlobal() for foreign windows offset += p->mapToGlobal(QPoint(0, 0)); break; -- cgit v1.2.3 From c988a8a28214914d20f4b8858e7f314a51b27507 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 3 Oct 2017 10:10:46 +0200 Subject: Make QCOMPARE print QColor alpha values on failure Currently, when two colors are equal except for their alpha values, QCOMPARE produces the following failure message: FAIL! : tst_Test::test() Compared values are not the same Actual (colorA): #ff0000 Expected (colorB): #ff0000 By using the HexArgb format instead of the default HexRgb, we can see the full hex string, with alpha values included: FAIL! : tst_Test::test() Compared values are not the same Actual (colorA): #88ff0000 Expected (colorB): #ffff0000 Task-number: QTBUG-55574 Change-Id: Id82c60a1b473ac6025a6f6ac560fce95a910d782 Reviewed-by: Friedemann Kleint Reviewed-by: Edward Welbourne --- src/testlib/qtest_gui.h | 2 +- .../auto/testlib/selftests/cmptest/tst_cmptest.cpp | 20 ++++-- .../testlib/selftests/expected_cmptest.lightxml | 80 ++++++++++++---------- .../testlib/selftests/expected_cmptest.teamcity | 75 ++++++++++---------- tests/auto/testlib/selftests/expected_cmptest.txt | 79 +++++++++++---------- tests/auto/testlib/selftests/expected_cmptest.xml | 80 ++++++++++++---------- .../testlib/selftests/expected_cmptest.xunitxml | 11 +-- 7 files changed, 195 insertions(+), 152 deletions(-) diff --git a/src/testlib/qtest_gui.h b/src/testlib/qtest_gui.h index d848f08d55..2b486aae5d 100644 --- a/src/testlib/qtest_gui.h +++ b/src/testlib/qtest_gui.h @@ -83,7 +83,7 @@ namespace QTest */ template<> inline char *toString(const QColor &color) { - return qstrdup(color.name().toLocal8Bit().constData()); + return qstrdup(color.name(QColor::HexArgb).toLocal8Bit().constData()); } template<> inline char *toString(const QRegion ®ion) diff --git a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp index 2cfe987f7d..a662fea615 100644 --- a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp +++ b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp @@ -140,6 +140,7 @@ private slots: void compareQListInt(); void compareQListDouble(); #ifdef QT_GUI_LIB + void compareQColor_data(); void compareQColor(); void compareQPixmaps(); void compareQPixmaps_data(); @@ -377,13 +378,22 @@ void tst_Cmptest::compareQListDouble() } #ifdef QT_GUI_LIB +void tst_Cmptest::compareQColor_data() +{ + QTest::addColumn("colorA"); + QTest::addColumn("colorB"); + + QTest::newRow("Qt::yellow vs \"yellow\"") << QColor(Qt::yellow) << QColor(QStringLiteral("yellow")); + QTest::newRow("Qt::yellow vs Qt::green") << QColor(Qt::yellow) << QColor(Qt::green); + QTest::newRow("0x88ff0000 vs 0xffff0000") << QColor::fromRgba(0x88ff0000) << QColor::fromRgba(0xffff0000); +} + void tst_Cmptest::compareQColor() { - const QColor yellow(Qt::yellow); - const QColor yellowFromName(QStringLiteral("yellow")); - const QColor green(Qt::green); - QCOMPARE(yellow, yellowFromName); - QCOMPARE(yellow, green); + QFETCH(QColor, colorA); + QFETCH(QColor, colorB); + + QCOMPARE(colorA, colorB); } void tst_Cmptest::compareQPixmaps_data() diff --git a/tests/auto/testlib/selftests/expected_cmptest.lightxml b/tests/auto/testlib/selftests/expected_cmptest.lightxml index eb11d236d4..d47967a445 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.lightxml +++ b/tests/auto/testlib/selftests/expected_cmptest.lightxml @@ -8,13 +8,13 @@ - + - + @@ -22,7 +22,7 @@ - + @@ -42,7 +42,7 @@ - + - + - + - + ) @@ -78,31 +78,31 @@ - + - + - + - + - + - + @@ -119,7 +119,7 @@ - + @@ -127,10 +127,20 @@ - + + + + + + + + + + Actual (colorA): #88ff0000 + Expected (colorB): #ffff0000]]> @@ -138,13 +148,13 @@ - + - + - + - + @@ -169,13 +179,13 @@ - + - + - + - + - + @@ -206,7 +216,7 @@ - + - + - + @@ -232,7 +242,7 @@ - + @@ -240,7 +250,7 @@ - + @@ -248,25 +258,25 @@ - + - + - + - + diff --git a/tests/auto/testlib/selftests/expected_cmptest.teamcity b/tests/auto/testlib/selftests/expected_cmptest.teamcity index c49f5d6b79..a0dc509279 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.teamcity +++ b/tests/auto/testlib/selftests/expected_cmptest.teamcity @@ -2,13 +2,13 @@ ##teamcity[testStarted name='initTestCase()' flowId='tst_Cmptest'] ##teamcity[testFinished name='initTestCase()' flowId='tst_Cmptest'] ##teamcity[testStarted name='compare_unregistered_enums()' flowId='tst_Cmptest'] -##teamcity[testFailed name='compare_unregistered_enums()' message='Failure! |[Loc: tst_cmptest.cpp(160)|]' details='Compared values are not the same' flowId='tst_Cmptest'] +##teamcity[testFailed name='compare_unregistered_enums()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same' flowId='tst_Cmptest'] ##teamcity[testFinished name='compare_unregistered_enums()' flowId='tst_Cmptest'] ##teamcity[testStarted name='compare_registered_enums()' flowId='tst_Cmptest'] -##teamcity[testFailed name='compare_registered_enums()' message='Failure! |[Loc: tst_cmptest.cpp(167)|]' details='Compared values are not the same|n Actual (Qt::Monday): Monday|n Expected (Qt::Sunday): Sunday' flowId='tst_Cmptest'] +##teamcity[testFailed name='compare_registered_enums()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (Qt::Monday): Monday|n Expected (Qt::Sunday): Sunday' flowId='tst_Cmptest'] ##teamcity[testFinished name='compare_registered_enums()' flowId='tst_Cmptest'] ##teamcity[testStarted name='compare_class_enums()' flowId='tst_Cmptest'] -##teamcity[testFailed name='compare_class_enums()' message='Failure! |[Loc: tst_cmptest.cpp(173)|]' details='Compared values are not the same|n Actual (MyClassEnum::MyClassEnumValue1): MyClassEnumValue1|n Expected (MyClassEnum::MyClassEnumValue2): MyClassEnumValue2' flowId='tst_Cmptest'] +##teamcity[testFailed name='compare_class_enums()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (MyClassEnum::MyClassEnumValue1): MyClassEnumValue1|n Expected (MyClassEnum::MyClassEnumValue2): MyClassEnumValue2' flowId='tst_Cmptest'] ##teamcity[testFinished name='compare_class_enums()' flowId='tst_Cmptest'] ##teamcity[testStarted name='compare_boolfuncs()' flowId='tst_Cmptest'] ##teamcity[testFinished name='compare_boolfuncs()' flowId='tst_Cmptest'] @@ -17,112 +17,117 @@ ##teamcity[testStarted name='compare_pointerfuncs()' flowId='tst_Cmptest'] ##teamcity[testFinished name='compare_pointerfuncs()' flowId='tst_Cmptest'] ##teamcity[testStarted name='compare_tostring(int, string)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compare_tostring(int, string)' message='Failure! |[Loc: tst_cmptest.cpp(262)|]' details='Compared values are not the same|n Actual (actual) : QVariant(int,123)|n Expected (expected): QVariant(QString,hi)' flowId='tst_Cmptest'] +##teamcity[testFailed name='compare_tostring(int, string)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (actual) : QVariant(int,123)|n Expected (expected): QVariant(QString,hi)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compare_tostring(int, string)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compare_tostring(both invalid)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compare_tostring(both invalid)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compare_tostring(null hash, invalid)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compare_tostring(null hash, invalid)' message='Failure! |[Loc: tst_cmptest.cpp(262)|]' details='Compared values are not the same|n Actual (actual) : QVariant(QVariantHash)|n Expected (expected): QVariant()' flowId='tst_Cmptest'] +##teamcity[testFailed name='compare_tostring(null hash, invalid)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (actual) : QVariant(QVariantHash)|n Expected (expected): QVariant()' flowId='tst_Cmptest'] ##teamcity[testFinished name='compare_tostring(null hash, invalid)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compare_tostring(string, null user type)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compare_tostring(string, null user type)' message='Failure! |[Loc: tst_cmptest.cpp(262)|]' details='Compared values are not the same|n Actual (actual) : QVariant(QString,A simple string)|n Expected (expected): QVariant(PhonyClass)' flowId='tst_Cmptest'] +##teamcity[testFailed name='compare_tostring(string, null user type)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (actual) : QVariant(QString,A simple string)|n Expected (expected): QVariant(PhonyClass)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compare_tostring(string, null user type)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compare_tostring(both non-null user type)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compare_tostring(both non-null user type)' message='Failure! |[Loc: tst_cmptest.cpp(262)|]' details='Compared values are not the same|n Actual (actual) : QVariant(PhonyClass,)|n Expected (expected): QVariant(PhonyClass,)' flowId='tst_Cmptest'] +##teamcity[testFailed name='compare_tostring(both non-null user type)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (actual) : QVariant(PhonyClass,)|n Expected (expected): QVariant(PhonyClass,)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compare_tostring(both non-null user type)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQStringLists(empty lists)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQStringLists(empty lists)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQStringLists(equal lists)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQStringLists(equal lists)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQStringLists(last item different)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQStringLists(last item different)' message='Failure! |[Loc: tst_cmptest.cpp(356)|]' details='Compared lists differ at index 2.|n Actual (opA): "string3"|n Expected (opB): "DIFFERS"' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQStringLists(last item different)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared lists differ at index 2.|n Actual (opA): "string3"|n Expected (opB): "DIFFERS"' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQStringLists(last item different)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQStringLists(second-last item different)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQStringLists(second-last item different)' message='Failure! |[Loc: tst_cmptest.cpp(356)|]' details='Compared lists differ at index 2.|n Actual (opA): "string3"|n Expected (opB): "DIFFERS"' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQStringLists(second-last item different)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared lists differ at index 2.|n Actual (opA): "string3"|n Expected (opB): "DIFFERS"' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQStringLists(second-last item different)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQStringLists(prefix)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQStringLists(prefix)' message='Failure! |[Loc: tst_cmptest.cpp(356)|]' details='Compared lists have different sizes.|n Actual (opA) size: 2|n Expected (opB) size: 1' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQStringLists(prefix)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared lists have different sizes.|n Actual (opA) size: 2|n Expected (opB) size: 1' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQStringLists(prefix)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQStringLists(short list second)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQStringLists(short list second)' message='Failure! |[Loc: tst_cmptest.cpp(356)|]' details='Compared lists have different sizes.|n Actual (opA) size: 12|n Expected (opB) size: 1' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQStringLists(short list second)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared lists have different sizes.|n Actual (opA) size: 12|n Expected (opB) size: 1' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQStringLists(short list second)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQStringLists(short list first)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQStringLists(short list first)' message='Failure! |[Loc: tst_cmptest.cpp(356)|]' details='Compared lists have different sizes.|n Actual (opA) size: 1|n Expected (opB) size: 12' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQStringLists(short list first)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared lists have different sizes.|n Actual (opA) size: 1|n Expected (opB) size: 12' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQStringLists(short list first)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQListInt()' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQListInt()' message='Failure! |[Loc: tst_cmptest.cpp(363)|]' details='Compared lists differ at index 2.|n Actual (int1): 3|n Expected (int2): 4' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQListInt()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared lists differ at index 2.|n Actual (int1): 3|n Expected (int2): 4' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQListInt()' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQListDouble()' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQListDouble()' message='Failure! |[Loc: tst_cmptest.cpp(370)|]' details='Compared lists differ at index 0.|n Actual (double1): 1.5|n Expected (double2): 1' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQListDouble()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared lists differ at index 0.|n Actual (double1): 1.5|n Expected (double2): 1' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQListDouble()' flowId='tst_Cmptest'] -##teamcity[testStarted name='compareQColor()' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQColor()' message='Failure! |[Loc: tst_cmptest.cpp(380)|]' details='Compared values are not the same|n Actual (yellow): #ffff00|n Expected (green) : #00ff00' flowId='tst_Cmptest'] -##teamcity[testFinished name='compareQColor()' flowId='tst_Cmptest'] +##teamcity[testStarted name='compareQColor(Qt::yellow vs "yellow")' flowId='tst_Cmptest'] +##teamcity[testFinished name='compareQColor(Qt::yellow vs "yellow")' flowId='tst_Cmptest'] +##teamcity[testStarted name='compareQColor(Qt::yellow vs Qt::green)' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQColor(Qt::yellow vs Qt::green)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (colorA): #ffffff00|n Expected (colorB): #ff00ff00' flowId='tst_Cmptest'] +##teamcity[testFinished name='compareQColor(Qt::yellow vs Qt::green)' flowId='tst_Cmptest'] +##teamcity[testStarted name='compareQColor(0x88ff0000 vs 0xffff0000)' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQColor(0x88ff0000 vs 0xffff0000)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (colorA): #88ff0000|n Expected (colorB): #ffff0000' flowId='tst_Cmptest'] +##teamcity[testFinished name='compareQColor(0x88ff0000 vs 0xffff0000)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQPixmaps(both null)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQPixmaps(both null)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQPixmaps(one null)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQPixmaps(one null)' message='Failure! |[Loc: tst_cmptest.cpp(405)|]' details='Compared QPixmaps differ.|n Actual (opA).isNull(): 1|n Expected (opB).isNull(): 0' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQPixmaps(one null)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared QPixmaps differ.|n Actual (opA).isNull(): 1|n Expected (opB).isNull(): 0' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQPixmaps(one null)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQPixmaps(other null)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQPixmaps(other null)' message='Failure! |[Loc: tst_cmptest.cpp(405)|]' details='Compared QPixmaps differ.|n Actual (opA).isNull(): 0|n Expected (opB).isNull(): 1' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQPixmaps(other null)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared QPixmaps differ.|n Actual (opA).isNull(): 0|n Expected (opB).isNull(): 1' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQPixmaps(other null)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQPixmaps(equal)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQPixmaps(equal)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQPixmaps(different size)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQPixmaps(different size)' message='Failure! |[Loc: tst_cmptest.cpp(405)|]' details='Compared QPixmaps differ in size.|n Actual (opA): 11x20|n Expected (opB): 20x20' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQPixmaps(different size)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared QPixmaps differ in size.|n Actual (opA): 11x20|n Expected (opB): 20x20' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQPixmaps(different size)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQPixmaps(different pixels)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQPixmaps(different pixels)' message='Failure! |[Loc: tst_cmptest.cpp(405)|]' details='Compared values are not the same' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQPixmaps(different pixels)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQPixmaps(different pixels)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQImages(both null)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQImages(both null)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQImages(one null)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQImages(one null)' message='Failure! |[Loc: tst_cmptest.cpp(432)|]' details='Compared QImages differ.|n Actual (opA).isNull(): 1|n Expected (opB).isNull(): 0' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQImages(one null)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared QImages differ.|n Actual (opA).isNull(): 1|n Expected (opB).isNull(): 0' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQImages(one null)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQImages(other null)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQImages(other null)' message='Failure! |[Loc: tst_cmptest.cpp(432)|]' details='Compared QImages differ.|n Actual (opA).isNull(): 0|n Expected (opB).isNull(): 1' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQImages(other null)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared QImages differ.|n Actual (opA).isNull(): 0|n Expected (opB).isNull(): 1' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQImages(other null)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQImages(equal)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQImages(equal)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQImages(different size)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQImages(different size)' message='Failure! |[Loc: tst_cmptest.cpp(432)|]' details='Compared QImages differ in size.|n Actual (opA): 11x20|n Expected (opB): 20x20' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQImages(different size)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared QImages differ in size.|n Actual (opA): 11x20|n Expected (opB): 20x20' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQImages(different size)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQImages(different format)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQImages(different format)' message='Failure! |[Loc: tst_cmptest.cpp(432)|]' details='Compared QImages differ in format.|n Actual (opA): 6|n Expected (opB): 3' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQImages(different format)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared QImages differ in format.|n Actual (opA): 6|n Expected (opB): 3' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQImages(different format)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQImages(different pixels)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQImages(different pixels)' message='Failure! |[Loc: tst_cmptest.cpp(432)|]' details='Compared values are not the same' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQImages(different pixels)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQImages(different pixels)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQRegion(equal-empty)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQRegion(equal-empty)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQRegion(1-empty)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQRegion(1-empty)' message='Failure! |[Loc: tst_cmptest.cpp(455)|]' details='Compared values are not the same|n Actual (rA): QRegion(200x50+10+10)|n Expected (rB): QRegion(null)' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQRegion(1-empty)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (rA): QRegion(200x50+10+10)|n Expected (rB): QRegion(null)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQRegion(1-empty)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQRegion(equal)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQRegion(equal)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQRegion(different lists)' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQRegion(different lists)' message='Failure! |[Loc: tst_cmptest.cpp(455)|]' details='Compared values are not the same|n Actual (rA): QRegion(200x50+10+10)|n Expected (rB): QRegion(2 rectangles, 50x200+100+200, 200x50+10+10)' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQRegion(different lists)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (rA): QRegion(200x50+10+10)|n Expected (rB): QRegion(2 rectangles, 50x200+100+200, 200x50+10+10)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQRegion(different lists)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQVector2D()' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQVector2D()' message='Failure! |[Loc: tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (v2a): QVector2D(1, 2)|n Expected (v2b): QVector2D(1, 3)' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQVector2D()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (v2a): QVector2D(1, 2)|n Expected (v2b): QVector2D(1, 3)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQVector2D()' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQVector3D()' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQVector3D()' message='Failure! |[Loc: tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (v3a): QVector3D(1, 2, 3)|n Expected (v3b): QVector3D(1, 3, 3)' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQVector3D()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (v3a): QVector3D(1, 2, 3)|n Expected (v3b): QVector3D(1, 3, 3)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQVector3D()' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQVector4D()' flowId='tst_Cmptest'] -##teamcity[testFailed name='compareQVector4D()' message='Failure! |[Loc: tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (v4a): QVector4D(1, 2, 3, 4)|n Expected (v4b): QVector4D(1, 3, 3, 4)' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQVector4D()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (v4a): QVector4D(1, 2, 3, 4)|n Expected (v4b): QVector4D(1, 3, 3, 4)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQVector4D()' flowId='tst_Cmptest'] ##teamcity[testStarted name='verify()' flowId='tst_Cmptest'] -##teamcity[testFailed name='verify()' message='Failure! |[Loc: tst_cmptest.cpp(467)|]' details='|'opaqueFunc() < 2|' returned FALSE. ()' flowId='tst_Cmptest'] +##teamcity[testFailed name='verify()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='|'opaqueFunc() < 2|' returned FALSE. ()' flowId='tst_Cmptest'] ##teamcity[testFinished name='verify()' flowId='tst_Cmptest'] ##teamcity[testStarted name='verify2()' flowId='tst_Cmptest'] -##teamcity[testFailed name='verify2()' message='Failure! |[Loc: tst_cmptest.cpp(473)|]' details='|'opaqueFunc() < 2|' returned FALSE. (42)' flowId='tst_Cmptest'] +##teamcity[testFailed name='verify2()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='|'opaqueFunc() < 2|' returned FALSE. (42)' flowId='tst_Cmptest'] ##teamcity[testFinished name='verify2()' flowId='tst_Cmptest'] ##teamcity[testStarted name='tryVerify()' flowId='tst_Cmptest'] -##teamcity[testFailed name='tryVerify()' message='Failure! |[Loc: tst_cmptest.cpp(479)|]' details='|'opaqueFunc() < 2|' returned FALSE. ()' flowId='tst_Cmptest'] +##teamcity[testFailed name='tryVerify()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='|'opaqueFunc() < 2|' returned FALSE. ()' flowId='tst_Cmptest'] ##teamcity[testFinished name='tryVerify()' flowId='tst_Cmptest'] ##teamcity[testStarted name='tryVerify2()' flowId='tst_Cmptest'] -##teamcity[testFailed name='tryVerify2()' message='Failure! |[Loc: tst_cmptest.cpp(485)|]' details='|'opaqueFunc() < 2|' returned FALSE. (42)' flowId='tst_Cmptest'] +##teamcity[testFailed name='tryVerify2()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='|'opaqueFunc() < 2|' returned FALSE. (42)' flowId='tst_Cmptest'] ##teamcity[testFinished name='tryVerify2()' flowId='tst_Cmptest'] ##teamcity[testStarted name='verifyExplicitOperatorBool()' flowId='tst_Cmptest'] ##teamcity[testFinished name='verifyExplicitOperatorBool()' flowId='tst_Cmptest'] diff --git a/tests/auto/testlib/selftests/expected_cmptest.txt b/tests/auto/testlib/selftests/expected_cmptest.txt index 179136a2c7..78df990dea 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.txt +++ b/tests/auto/testlib/selftests/expected_cmptest.txt @@ -2,136 +2,141 @@ Config: Using QtTest library PASS : tst_Cmptest::initTestCase() FAIL! : tst_Cmptest::compare_unregistered_enums() Compared values are not the same - Loc: [tst_cmptest.cpp(160)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compare_registered_enums() Compared values are not the same Actual (Qt::Monday): Monday Expected (Qt::Sunday): Sunday - Loc: [tst_cmptest.cpp(167)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compare_class_enums() Compared values are not the same Actual (MyClassEnum::MyClassEnumValue1): MyClassEnumValue1 Expected (MyClassEnum::MyClassEnumValue2): MyClassEnumValue2 - Loc: [tst_cmptest.cpp(173)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] PASS : tst_Cmptest::compare_boolfuncs() PASS : tst_Cmptest::compare_to_nullptr() PASS : tst_Cmptest::compare_pointerfuncs() FAIL! : tst_Cmptest::compare_tostring(int, string) Compared values are not the same Actual (actual) : QVariant(int,123) Expected (expected): QVariant(QString,hi) - Loc: [tst_cmptest.cpp(262)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] PASS : tst_Cmptest::compare_tostring(both invalid) FAIL! : tst_Cmptest::compare_tostring(null hash, invalid) Compared values are not the same Actual (actual) : QVariant(QVariantHash) Expected (expected): QVariant() - Loc: [tst_cmptest.cpp(262)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compare_tostring(string, null user type) Compared values are not the same Actual (actual) : QVariant(QString,A simple string) Expected (expected): QVariant(PhonyClass) - Loc: [tst_cmptest.cpp(262)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compare_tostring(both non-null user type) Compared values are not the same Actual (actual) : QVariant(PhonyClass,) Expected (expected): QVariant(PhonyClass,) - Loc: [tst_cmptest.cpp(262)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] PASS : tst_Cmptest::compareQStringLists(empty lists) PASS : tst_Cmptest::compareQStringLists(equal lists) FAIL! : tst_Cmptest::compareQStringLists(last item different) Compared lists differ at index 2. Actual (opA): "string3" Expected (opB): "DIFFERS" - Loc: [tst_cmptest.cpp(356)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compareQStringLists(second-last item different) Compared lists differ at index 2. Actual (opA): "string3" Expected (opB): "DIFFERS" - Loc: [tst_cmptest.cpp(356)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compareQStringLists(prefix) Compared lists have different sizes. Actual (opA) size: 2 Expected (opB) size: 1 - Loc: [tst_cmptest.cpp(356)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compareQStringLists(short list second) Compared lists have different sizes. Actual (opA) size: 12 Expected (opB) size: 1 - Loc: [tst_cmptest.cpp(356)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compareQStringLists(short list first) Compared lists have different sizes. Actual (opA) size: 1 Expected (opB) size: 12 - Loc: [tst_cmptest.cpp(356)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compareQListInt() Compared lists differ at index 2. Actual (int1): 3 Expected (int2): 4 - Loc: [tst_cmptest.cpp(363)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compareQListDouble() Compared lists differ at index 0. Actual (double1): 1.5 Expected (double2): 1 - Loc: [tst_cmptest.cpp(370)] -FAIL! : tst_Cmptest::compareQColor() Compared values are not the same - Actual (yellow): #ffff00 - Expected (green) : #00ff00 - Loc: [tst_cmptest.cpp(380)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] +PASS : tst_Cmptest::compareQColor(Qt::yellow vs "yellow") +FAIL! : tst_Cmptest::compareQColor(Qt::yellow vs Qt::green) Compared values are not the same + Actual (colorA): #ffffff00 + Expected (colorB): #ff00ff00 + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] +FAIL! : tst_Cmptest::compareQColor(0x88ff0000 vs 0xffff0000) Compared values are not the same + Actual (colorA): #88ff0000 + Expected (colorB): #ffff0000 + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] PASS : tst_Cmptest::compareQPixmaps(both null) FAIL! : tst_Cmptest::compareQPixmaps(one null) Compared QPixmaps differ. Actual (opA).isNull(): 1 Expected (opB).isNull(): 0 - Loc: [tst_cmptest.cpp(405)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compareQPixmaps(other null) Compared QPixmaps differ. Actual (opA).isNull(): 0 Expected (opB).isNull(): 1 - Loc: [tst_cmptest.cpp(405)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] PASS : tst_Cmptest::compareQPixmaps(equal) FAIL! : tst_Cmptest::compareQPixmaps(different size) Compared QPixmaps differ in size. Actual (opA): 11x20 Expected (opB): 20x20 - Loc: [tst_cmptest.cpp(405)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compareQPixmaps(different pixels) Compared values are not the same - Loc: [tst_cmptest.cpp(405)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] PASS : tst_Cmptest::compareQImages(both null) FAIL! : tst_Cmptest::compareQImages(one null) Compared QImages differ. Actual (opA).isNull(): 1 Expected (opB).isNull(): 0 - Loc: [tst_cmptest.cpp(432)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compareQImages(other null) Compared QImages differ. Actual (opA).isNull(): 0 Expected (opB).isNull(): 1 - Loc: [tst_cmptest.cpp(432)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] PASS : tst_Cmptest::compareQImages(equal) FAIL! : tst_Cmptest::compareQImages(different size) Compared QImages differ in size. Actual (opA): 11x20 Expected (opB): 20x20 - Loc: [tst_cmptest.cpp(432)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compareQImages(different format) Compared QImages differ in format. Actual (opA): 6 Expected (opB): 3 - Loc: [tst_cmptest.cpp(432)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compareQImages(different pixels) Compared values are not the same - Loc: [tst_cmptest.cpp(432)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] PASS : tst_Cmptest::compareQRegion(equal-empty) FAIL! : tst_Cmptest::compareQRegion(1-empty) Compared values are not the same Actual (rA): QRegion(200x50+10+10) Expected (rB): QRegion(null) - Loc: [tst_cmptest.cpp(455)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] PASS : tst_Cmptest::compareQRegion(equal) FAIL! : tst_Cmptest::compareQRegion(different lists) Compared values are not the same Actual (rA): QRegion(200x50+10+10) Expected (rB): QRegion(2 rectangles, 50x200+100+200, 200x50+10+10) - Loc: [tst_cmptest.cpp(455)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compareQVector2D() Compared values are not the same Actual (v2a): QVector2D(1, 2) Expected (v2b): QVector2D(1, 3) - Loc: [tst_cmptest.cpp(0)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compareQVector3D() Compared values are not the same Actual (v3a): QVector3D(1, 2, 3) Expected (v3b): QVector3D(1, 3, 3) - Loc: [tst_cmptest.cpp(0)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compareQVector4D() Compared values are not the same Actual (v4a): QVector4D(1, 2, 3, 4) Expected (v4b): QVector4D(1, 3, 3, 4) - Loc: [tst_cmptest.cpp(0)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::verify() 'opaqueFunc() < 2' returned FALSE. () - Loc: [tst_cmptest.cpp(467)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::verify2() 'opaqueFunc() < 2' returned FALSE. (42) - Loc: [tst_cmptest.cpp(473)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::tryVerify() 'opaqueFunc() < 2' returned FALSE. () - Loc: [tst_cmptest.cpp(479)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::tryVerify2() 'opaqueFunc() < 2' returned FALSE. (42) - Loc: [tst_cmptest.cpp(485)] + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] PASS : tst_Cmptest::verifyExplicitOperatorBool() PASS : tst_Cmptest::cleanupTestCase() -Totals: 15 passed, 33 failed, 0 skipped, 0 blacklisted, 0ms +Totals: 16 passed, 34 failed, 0 skipped, 0 blacklisted, 0ms ********* Finished testing of tst_Cmptest ********* diff --git a/tests/auto/testlib/selftests/expected_cmptest.xml b/tests/auto/testlib/selftests/expected_cmptest.xml index b281b04677..01b725f247 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.xml +++ b/tests/auto/testlib/selftests/expected_cmptest.xml @@ -10,13 +10,13 @@ - + - + @@ -24,7 +24,7 @@ - + @@ -44,7 +44,7 @@ - + - + - + - + ) @@ -80,31 +80,31 @@ - + - + - + - + - + - + @@ -121,7 +121,7 @@ - + @@ -129,10 +129,20 @@ - + + + + + + + + + + Actual (colorA): #88ff0000 + Expected (colorB): #ffff0000]]> @@ -140,13 +150,13 @@ - + - + - + - + @@ -171,13 +181,13 @@ - + - + - + - + - + @@ -208,7 +218,7 @@ - + - + - + @@ -234,7 +244,7 @@ - + @@ -242,7 +252,7 @@ - + @@ -250,25 +260,25 @@ - + - + - + - + diff --git a/tests/auto/testlib/selftests/expected_cmptest.xunitxml b/tests/auto/testlib/selftests/expected_cmptest.xunitxml index c2c0c86058..812696ffcf 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.xunitxml +++ b/tests/auto/testlib/selftests/expected_cmptest.xunitxml @@ -1,5 +1,5 @@ - + @@ -64,9 +64,12 @@ Expected (double2): 1" result="fail"/> - + + +#include #ifndef QT_NO_ACCESSIBILITY #include "qwindowscombase.h" diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp index e214d47137..d48cb9674f 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp @@ -37,7 +37,7 @@ ** ****************************************************************************/ -#include +#include #ifndef QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index 47b179250a..fe2b9335cb 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -37,7 +37,7 @@ ** ****************************************************************************/ -#include +#include #ifndef QT_NO_ACCESSIBILITY #include "qwindowsmsaaaccessible.h" diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h index e654f262da..5380fc2411 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h @@ -39,9 +39,8 @@ #ifndef QWINDOWSMSAAACCESSIBLE_H #define QWINDOWSMSAAACCESSIBLE_H -#include -#ifndef QT_NO_ACCESSIBILITY #include +#ifndef QT_NO_ACCESSIBILITY #include #include -- cgit v1.2.3 From 8f1277da8c137270ff857128d8fea1423d8a7700 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 22 Oct 2017 21:39:31 +0200 Subject: QStorageInfo: Properly decode labels from /dev/disk/by-label udev encodes the labels for /dev/disk/by-label/ with ID_LABEL_FS_ENC which is done with blkid_encode_string(). This function encodes some unsafe 1-byte utf-8 characters as hex (e.g. '\' or ' ') Task-number: QTBUG-61420 Change-Id: If82f4381d348acf9008b79ec5ac7c55e6d3819de Reviewed-by: Thiago Macieira --- src/corelib/io/qstorageinfo_unix.cpp | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index 9072b34f54..1fc32e0f2d 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -544,6 +544,38 @@ void QStorageInfoPrivate::initRootPath() } } +#ifdef Q_OS_LINUX +// udev encodes the labels with ID_LABEL_FS_ENC which is done with +// blkid_encode_string(). Within this function some 1-byte utf-8 +// characters not considered safe (e.g. '\' or ' ') are encoded as hex +static QString decodeFsEncString(const QString &str) +{ + QString decoded; + decoded.reserve(str.size()); + + int i = 0; + while (i < str.size()) { + if (i <= str.size() - 4) { // we need at least four characters \xAB + if (str.at(i) == QLatin1Char('\\') && + str.at(i+1) == QLatin1Char('x')) { + bool bOk; + const int code = str.midRef(i+2, 2).toInt(&bOk, 16); + // only decode characters between 0x20 and 0x7f but not + // the backslash to prevent collisions + if (bOk && code >= 0x20 && code < 0x80 && code != '\\') { + decoded += QChar(code); + i += 4; + continue; + } + } + } + decoded += str.at(i); + ++i; + } + return decoded; +} +#endif + static inline QString retrieveLabel(const QByteArray &device) { #ifdef Q_OS_LINUX @@ -557,7 +589,7 @@ static inline QString retrieveLabel(const QByteArray &device) it.next(); QFileInfo fileInfo(it.fileInfo()); if (fileInfo.isSymLink() && fileInfo.symLinkTarget() == devicePath) - return fileInfo.fileName(); + return decodeFsEncString(fileInfo.fileName()); } #elif defined Q_OS_HAIKU fs_info fsInfo; -- cgit v1.2.3 From a4f9cf23444dd76a11d4eb67c4ea65d5c3948894 Mon Sep 17 00:00:00 2001 From: Elvis Angelaccio Date: Sat, 29 Jul 2017 11:28:13 +0200 Subject: Disable window shortcuts if there is a window modal dialog If a window is blocked by a WindowModal dialog, it should not be possible to trigger window shortcuts on that window if it receives a WindowActivate event. This currently happens if the blocked window gets clicked, because the window becomes the active_window and then QApplication sends it a WindowActivate event (this doesn't happen with application modal dialogs). The correctWidgetContext() function calls QApplicationPrivate::tryModalHelper() only if the shortcut context is ApplicationShortcut. This patch makes it call even if the shortcut context is WindowShortcut. Change-Id: Iff87d85bcae603a6a24128e0cedfa9d33b6485fd Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qshortcut.cpp | 2 +- tests/auto/widgets/kernel/qaction/tst_qaction.cpp | 52 ++++++++++++++++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp index f944a7097b..32600d4152 100644 --- a/src/widgets/kernel/qshortcut.cpp +++ b/src/widgets/kernel/qshortcut.cpp @@ -205,7 +205,7 @@ static bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidge #if defined(DEBUG_QSHORTCUTMAP) qDebug().nospace() << "..true [Pass-through]"; #endif - return true; + return QApplicationPrivate::tryModalHelper(w, nullptr); } #if QT_CONFIG(graphicsview) diff --git a/tests/auto/widgets/kernel/qaction/tst_qaction.cpp b/tests/auto/widgets/kernel/qaction/tst_qaction.cpp index 3535e465b3..88ddb7c11d 100644 --- a/tests/auto/widgets/kernel/qaction/tst_qaction.cpp +++ b/tests/auto/widgets/kernel/qaction/tst_qaction.cpp @@ -26,7 +26,8 @@ ** ****************************************************************************/ - +#include +#include #include #include @@ -63,6 +64,8 @@ private slots: void task229128TriggeredSignalWhenInActiongroup(); void repeat(); void setData(); + void disableShortcutsWithBlockedWidgets_data(); + void disableShortcutsWithBlockedWidgets(); private: int m_lastEventType; @@ -424,5 +427,52 @@ void tst_QAction::setData() // QTBUG-62006 QCOMPARE(spy.count(), 1); } +void tst_QAction::disableShortcutsWithBlockedWidgets_data() +{ + QTest::addColumn("shortcutContext"); + QTest::addColumn("windowModality"); + + QTest::newRow("application modal dialog should block window shortcut.") + << Qt::WindowShortcut << Qt::ApplicationModal; + + QTest::newRow("application modal dialog should block application shortcut.") + << Qt::ApplicationShortcut << Qt::ApplicationModal; + + QTest::newRow("window modal dialog should block application shortcut.") + << Qt::ApplicationShortcut << Qt::WindowModal; + + QTest::newRow("window modal dialog should block window shortcut.") + << Qt::WindowShortcut << Qt::WindowModal; +} + + +void tst_QAction::disableShortcutsWithBlockedWidgets() +{ + QMainWindow window; + + QFETCH(Qt::ShortcutContext, shortcutContext); + QAction action(&window); + window.addAction(&action); + action.setShortcut(QKeySequence(Qt::Key_1)); + action.setShortcutContext(shortcutContext); + + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + + QDialog dialog(&window); + QFETCH(Qt::WindowModality, windowModality); + dialog.setWindowModality(windowModality); + + dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dialog)); + + QApplication::setActiveWindow(&window); + QVERIFY(QTest::qWaitForWindowActive(&window)); + + QSignalSpy spy(&action, &QAction::triggered); + QTest::keyPress(&window, Qt::Key_1); + QCOMPARE(spy.count(), 0); +} + QTEST_MAIN(tst_QAction) #include "tst_qaction.moc" -- cgit v1.2.3 From 937ded010b09250c6ab9a57917f2e430fb5875f5 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 28 Oct 2017 19:13:58 +0200 Subject: QListView: make sure to respect grid size during dataChanged() handling When the dataChanged() signal is handled by QIconModeViewBase, the size of the items are recalculated. During this operation the optional grid size is not taken into account which leads to a screwed up layout. This patch adds the missing check similar it is done in doStaticLayout()/doDynamicLayout(). Task-number: QTBUG-45427 Change-Id: Iba7adb44b1510c511a69c289ccb4f168992a6871 Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qlistview.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 9e959c8e1e..9217fec10e 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -2874,10 +2874,19 @@ void QIconModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand) void QIconModeViewBase::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { if (column() >= topLeft.column() && column() <= bottomRight.column()) { - QStyleOptionViewItem option = viewOptions(); - int bottom = qMin(items.count(), bottomRight.row() + 1); + const QStyleOptionViewItem option = viewOptions(); + const int bottom = qMin(items.count(), bottomRight.row() + 1); + const bool useItemSize = !dd->grid.isValid(); for (int row = topLeft.row(); row < bottom; ++row) - items[row].resize(itemSize(option, modelIndex(row))); + { + QSize s = itemSize(option, modelIndex(row)); + if (!useItemSize) + { + s.setWidth(qMin(dd->grid.width(), s.width())); + s.setHeight(qMin(dd->grid.height(), s.height())); + } + items[row].resize(s); + } } } -- cgit v1.2.3 From ca0f05ebe2a6a8e51e4c58b2994620cc51638a3f Mon Sep 17 00:00:00 2001 From: Sami Nurmenniemi Date: Fri, 3 Nov 2017 09:47:00 +0200 Subject: Skip d-bus tests also on armv7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both of the new toolchains (armv7 + arm64) have some problems with d-bus tests. Skip them until the toolchain has been fixed. Task-number: QTBUG-60263 Change-Id: Ic300f419635fb6b49b3ea7f48fa76c19088c88bd Reviewed-by: Tony Sarajärvi --- tests/auto/auto.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 3caa6a3b65..a1ffe5b3ce 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -46,5 +46,5 @@ else:!qtConfig(process): SUBDIRS -= tools # QTBUG-63915 boot2qt: { - contains(QT_ARCH, arm64): SUBDIRS -= dbus + SUBDIRS -= dbus } -- cgit v1.2.3 From 851c226247d692a608d78a1d7f9e621f4a82f40d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 2 Nov 2017 08:56:09 +0100 Subject: QFilesystemWatcher/Windows: Use event dispatcher of thread Previously, the native event filter listening on removable drivers was installed on QCoreApplication::eventDispatcher() which led to a mismatch when launched from a non-GUI thread since ~QAbstractNativeEventFilter() removes itself from QAbstractEventDispatcher::instance(). Amends 45580aa92557caa4f3f5be783573ddb80602e494, e612fe8d47bc0fe762668617a5189117ad1aee15. Task-number: QTBUG-64171 Change-Id: Icbe289bd585f124d66989d0cd574040b986e680c Reviewed-by: Thiago Macieira --- src/corelib/io/qfilesystemwatcher_win.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_win.cpp b/src/corelib/io/qfilesystemwatcher_win.cpp index cdb79e7c97..9e43d11e71 100644 --- a/src/corelib/io/qfilesystemwatcher_win.cpp +++ b/src/corelib/io/qfilesystemwatcher_win.cpp @@ -308,7 +308,7 @@ void QWindowsRemovableDriveListener::addPath(const QString &p) notify.dbch_size = sizeof(notify); notify.dbch_devicetype = DBT_DEVTYP_HANDLE; notify.dbch_handle = volumeHandle; - QEventDispatcherWin32 *winEventDispatcher = static_cast(QCoreApplication::eventDispatcher()); + QEventDispatcherWin32 *winEventDispatcher = static_cast(QAbstractEventDispatcher::instance()); re.devNotify = RegisterDeviceNotification(winEventDispatcher->internalHwnd(), ¬ify, DEVICE_NOTIFY_WINDOW_HANDLE); // Empirically found: The notifications also work when the handle is immediately @@ -336,7 +336,7 @@ QWindowsFileSystemWatcherEngine::QWindowsFileSystemWatcherEngine(QObject *parent : QFileSystemWatcherEngine(parent) { #ifndef Q_OS_WINRT - if (QAbstractEventDispatcher *eventDispatcher = QCoreApplication::eventDispatcher()) { + if (QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance()) { m_driveListener = new QWindowsRemovableDriveListener(this); eventDispatcher->installNativeEventFilter(m_driveListener); parent->setProperty("_q_driveListener", -- cgit v1.2.3 From d366d6dfd30de6e6f83afc807a4648f008b396e5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 27 Oct 2017 13:21:22 +0200 Subject: Windows QPA: Restrict file dialog to file system items in Directory mode Qt cannot handle places like 'Network', etc. Task-number: QTBUG-63645 Change-Id: I53d0eedc2996af6a1ec3230e3d65a3e272aa3710 Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowsdialoghelpers.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index f4527bcc60..75ca090cef 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -1010,7 +1010,9 @@ void QWindowsNativeFileDialogBase::setMode(QFileDialogOptions::FileMode mode, break; case QFileDialogOptions::Directory: case QFileDialogOptions::DirectoryOnly: - flags |= FOS_PICKFOLDERS | FOS_FILEMUSTEXIST; + // QTBUG-63645: Restrict to file system items, as Qt cannot deal with + // places like 'Network', etc. + flags |= FOS_PICKFOLDERS | FOS_FILEMUSTEXIST | FOS_FORCEFILESYSTEM; break; case QFileDialogOptions::ExistingFiles: flags |= FOS_FILEMUSTEXIST | FOS_ALLOWMULTISELECT; @@ -1219,6 +1221,8 @@ void QWindowsNativeFileDialogBase::onSelectionChange() { const QList current = selectedFiles(); m_data.setSelectedFiles(current); + qDebug() << __FUNCTION__ << current << current.size(); + if (current.size() == 1) emit currentChanged(current.front()); } -- cgit v1.2.3 From b4ac5525612812dd411c93e671813d079a152e57 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 27 Oct 2017 13:28:44 +0200 Subject: Windows QPA: Pass on Url of non-filesystem directory items Do not attempt to copy directory items, which will fail and result in empty result lists. Amends 5865e582fd537fff530c13301e5229a7b4ed21c7. Task-number: QTBUG-57070 Task-number: QTBUG-63645 Change-Id: I59efce196b28099ec8aff5a802ef0a4d9a098453 Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowsdialoghelpers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 75ca090cef..4b08528d17 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -1419,7 +1419,7 @@ QList QWindowsNativeOpenFileDialog::dialogResult() const for (IShellItem *item : QWindowsShellItem::itemsFromItemArray(items)) { QWindowsShellItem qItem(item); const QString path = qItem.path(); - if (path.isEmpty()) { + if (path.isEmpty() && !qItem.isDir()) { const QString temporaryCopy = createTemporaryItemCopy(qItem); if (temporaryCopy.isEmpty()) qWarning() << "Unable to create a local copy of" << qItem; -- cgit v1.2.3 From 92c61b11c1704450adfa3a8ac839478c0f3dd19d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 27 Oct 2017 15:23:39 +0200 Subject: Windows: Use SM_CXSMICON instead of SM_CXICON for the tray icon size Partially reverts b465fe759695bb7e1de693c3d4d20acfd2c49779. Task-number: QTBUG-63447 Change-Id: Iaf8a54b59a054e33811f65f64322af3aa746885e Reviewed-by: Oliver Wolff --- src/widgets/util/qsystemtrayicon_win.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/widgets/util/qsystemtrayicon_win.cpp b/src/widgets/util/qsystemtrayicon_win.cpp index 3f007f24c1..57d46912e0 100644 --- a/src/widgets/util/qsystemtrayicon_win.cpp +++ b/src/widgets/util/qsystemtrayicon_win.cpp @@ -313,9 +313,8 @@ HICON QSystemTrayIconSys::createIcon() const QIcon icon = q->icon(); if (icon.isNull()) return oldIcon; - const QSize requestedSize = QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA - ? QSize(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)) - : QSize(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); + // When merging this to 5.10, change at src/plugins/platforms/windows/qwindowssystemtrayicon.cpp:351. + const QSize requestedSize = QSize(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); const QSize size = icon.actualSize(requestedSize); const QPixmap pm = icon.pixmap(size); if (pm.isNull()) -- cgit v1.2.3 From d674d227f7ab22aed206d3a7f5c96e5e8dfa48f2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 6 Apr 2017 13:20:18 -0700 Subject: qGlobalQHashSeed: initialize the seed before returning it If you had never used QHash before, this function returned -1. That's not useful if you're trying to implement your own QHash that uses Qt's global seed. Change-Id: Ib0e40a7a3ebc44329f23fffd14b2e875b970a55c Reviewed-by: Lars Knoll --- src/corelib/tools/qhash.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index 4cc9ec8ec8..1662e944cf 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -361,6 +361,7 @@ static void qt_initialize_qhash_seed() */ int qGlobalQHashSeed() { + qt_initialize_qhash_seed(); return qt_qhash_seed.load(); } -- cgit v1.2.3 From 484a186f50de59279cf3c02088273ff114f4cfcf Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 4 Oct 2017 12:00:57 -0700 Subject: QNativeSocketEngine/Win: fix getting the datagram destination Looks like I never even tested this. There were two problems: 1) when we asked for the recvmsg and sendmsg functions, we used the wrong variable (socketDescriptor was still -1) 2) we extracted the destination addresses, but never set them in the QIpPacketHeader object The added tests confirm that this works on Windows, Linux, Darwin, FreeBSD. There also seems to be a problem, obtaining the destination address on an IPv4 socket with a dual-stack sender (I can reproduce that on FreeBSD, macOS and Windows, plus an old version of Linux). Task-number: QTBUG-63605 Change-Id: I638cf58bfa7b4e5fb386fffd14ea732bddbc0c42 Reviewed-by: Timur Pocheptsov --- src/network/socket/qnativesocketengine_win.cpp | 20 +-- tests/auto/network/socket/qudpsocket/test/test.pro | 1 + .../network/socket/qudpsocket/tst_qudpsocket.cpp | 171 +++++++++++++++------ 3 files changed, 137 insertions(+), 55 deletions(-) diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index eb633eb1d2..3ecfb06411 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -408,13 +408,13 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc // get the pointer to sendmsg and recvmsg DWORD bytesReturned; GUID recvmsgguid = WSAID_WSARECVMSG; - if (WSAIoctl(socketDescriptor, SIO_GET_EXTENSION_FUNCTION_POINTER, + if (WSAIoctl(socket, SIO_GET_EXTENSION_FUNCTION_POINTER, &recvmsgguid, sizeof(recvmsgguid), &recvmsg, sizeof(recvmsg), &bytesReturned, NULL, NULL) == SOCKET_ERROR) recvmsg = 0; GUID sendmsgguid = WSAID_WSASENDMSG; - if (WSAIoctl(socketDescriptor, SIO_GET_EXTENSION_FUNCTION_POINTER, + if (WSAIoctl(socket, SIO_GET_EXTENSION_FUNCTION_POINTER, &sendmsgguid, sizeof(sendmsgguid), &sendmsg, sizeof(sendmsg), &bytesReturned, NULL, NULL) == SOCKET_ERROR) sendmsg = 0; @@ -1257,26 +1257,28 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL qt_socket_getPortAndAddress(socketDescriptor, &aa, &header->senderPort, &header->senderAddress); } - if (ret != -1 && recvmsg) { + if (ret != -1 && recvmsg && options != QAbstractSocketEngine::WantNone) { // get the ancillary data + header->destinationPort = localPort; WSACMSGHDR *cmsgptr; for (cmsgptr = WSA_CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = WSA_CMSG_NXTHDR(&msg, cmsgptr)) { if (cmsgptr->cmsg_level == IPPROTO_IPV6 && cmsgptr->cmsg_type == IPV6_PKTINFO && cmsgptr->cmsg_len >= WSA_CMSG_LEN(sizeof(in6_pktinfo))) { in6_pktinfo *info = reinterpret_cast(WSA_CMSG_DATA(cmsgptr)); - QHostAddress target(reinterpret_cast(&info->ipi6_addr)); - if (info->ipi6_ifindex) - target.setScopeId(QString::number(info->ipi6_ifindex)); + + header->destinationAddress.setAddress(reinterpret_cast(&info->ipi6_addr)); + header->ifindex = info->ipi6_ifindex; + if (header->ifindex) + header->destinationAddress.setScopeId(QString::number(info->ipi6_ifindex)); } if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_PKTINFO && cmsgptr->cmsg_len >= WSA_CMSG_LEN(sizeof(in_pktinfo))) { in_pktinfo *info = reinterpret_cast(WSA_CMSG_DATA(cmsgptr)); u_long addr; WSANtohl(socketDescriptor, info->ipi_addr.s_addr, &addr); - QHostAddress target(addr); - if (info->ipi_ifindex) - target.setScopeId(QString::number(info->ipi_ifindex)); + header->destinationAddress.setAddress(addr); + header->ifindex = info->ipi_ifindex; } if (cmsgptr->cmsg_len == WSA_CMSG_LEN(sizeof(int)) diff --git a/tests/auto/network/socket/qudpsocket/test/test.pro b/tests/auto/network/socket/qudpsocket/test/test.pro index 73486a2bc3..e856776ddc 100644 --- a/tests/auto/network/socket/qudpsocket/test/test.pro +++ b/tests/auto/network/socket/qudpsocket/test/test.pro @@ -1,6 +1,7 @@ CONFIG += testcase testcase.timeout = 800 # this test is slow SOURCES += ../tst_qudpsocket.cpp +INCLUDEPATH += ../../../../../shared/ QT = core network testlib MOC_DIR=tmp diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index aeb6e61cd2..0f46caa7c2 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2017 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -45,6 +45,7 @@ #include #include "../../../network-settings.h" +#include "emulationdetector.h" #ifndef QT_NO_BEARERMANAGEMENT #include @@ -227,6 +228,9 @@ void tst_QUdpSocket::initTestCase() QSKIP("No network test server available"); allAddresses = QNetworkInterface::allAddresses(); m_skipUnsupportedIPv6Tests = shouldSkipIpv6TestsForBrokenSetsockopt(); + + if (EmulationDetector::isRunningArmOnX86()) + QSKIP("This test is unreliable due to QEMU emulation shortcomings."); } void tst_QUdpSocket::init() @@ -445,31 +449,58 @@ void tst_QUdpSocket::loop() paul.setProperty("_q_networksession", QVariant::fromValue(networkSession)); #endif - QVERIFY2(peter.bind(), peter.errorString().toLatin1().constData()); - QVERIFY2(paul.bind(), paul.errorString().toLatin1().constData()); + // make sure we bind to IPv4 + QHostAddress localhost = QHostAddress::LocalHost; + QVERIFY2(peter.bind(localhost), peter.errorString().toLatin1().constData()); + QVERIFY2(paul.bind(localhost), paul.errorString().toLatin1().constData()); QHostAddress peterAddress = makeNonAny(peter.localAddress()); - QHostAddress pualAddress = makeNonAny(paul.localAddress()); + QHostAddress paulAddress = makeNonAny(paul.localAddress()); QCOMPARE(peter.writeDatagram(peterMessage.data(), peterMessage.length(), - pualAddress, paul.localPort()), qint64(peterMessage.length())); + paulAddress, paul.localPort()), qint64(peterMessage.length())); QCOMPARE(paul.writeDatagram(paulMessage.data(), paulMessage.length(), peterAddress, peter.localPort()), qint64(paulMessage.length())); QVERIFY2(peter.waitForReadyRead(9000), QtNetworkSettings::msgSocketError(peter).constData()); QVERIFY2(paul.waitForReadyRead(9000), QtNetworkSettings::msgSocketError(paul).constData()); - char peterBuffer[16*1024]; - char paulBuffer[16*1024]; + + QNetworkDatagram peterDatagram = peter.receiveDatagram(paulMessage.length() * 2); + QNetworkDatagram paulDatagram = paul.receiveDatagram(peterMessage.length() * 2); if (success) { - QCOMPARE(peter.readDatagram(peterBuffer, sizeof(peterBuffer)), qint64(paulMessage.length())); - QCOMPARE(paul.readDatagram(paulBuffer, sizeof(peterBuffer)), qint64(peterMessage.length())); + QCOMPARE(peterDatagram.data().length(), qint64(paulMessage.length())); + QCOMPARE(paulDatagram.data().length(), qint64(peterMessage.length())); } else { - QVERIFY(peter.readDatagram(peterBuffer, sizeof(peterBuffer)) != paulMessage.length()); - QVERIFY(paul.readDatagram(paulBuffer, sizeof(peterBuffer)) != peterMessage.length()); + // this code path seems to never be executed + QVERIFY(peterDatagram.data().length() != paulMessage.length()); + QVERIFY(paulDatagram.data().length() != peterMessage.length()); } - QCOMPARE(QByteArray(peterBuffer, paulMessage.length()), paulMessage); - QCOMPARE(QByteArray(paulBuffer, peterMessage.length()), peterMessage); + QCOMPARE(peterDatagram.data().left(paulMessage.length()), paulMessage); + QCOMPARE(paulDatagram.data().left(peterMessage.length()), peterMessage); + + QCOMPARE(peterDatagram.senderAddress(), paulAddress); + QCOMPARE(paulDatagram.senderAddress(), peterAddress); + QCOMPARE(paulDatagram.senderPort(), int(peter.localPort())); + QCOMPARE(peterDatagram.senderPort(), int(paul.localPort())); + + // Unlike for IPv6 with IPV6_PKTINFO, IPv4 has no standardized way of + // obtaining the packet's destination addresses. The destinationAddress and + // destinationPort calls could fail, so whitelist the OSes for which we + // know we have an implementation. +#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) || defined(Q_OS_WIN) + QVERIFY(peterDatagram.destinationPort() != -1); + QVERIFY(paulDatagram.destinationPort() != -1); +#endif + if (peterDatagram.destinationPort() == -1) { + QCOMPARE(peterDatagram.destinationAddress().protocol(), QAbstractSocket::UnknownNetworkLayerProtocol); + QCOMPARE(paulDatagram.destinationAddress().protocol(), QAbstractSocket::UnknownNetworkLayerProtocol); + } else { + QCOMPARE(peterDatagram.destinationAddress(), makeNonAny(peter.localAddress())); + QCOMPARE(paulDatagram.destinationAddress(), makeNonAny(paul.localAddress())); + QVERIFY(peterDatagram.destinationAddress().isEqual(makeNonAny(peter.localAddress()))); + QVERIFY(paulDatagram.destinationAddress().isEqual(makeNonAny(paul.localAddress()))); + } } //---------------------------------------------------------------------------------- @@ -492,8 +523,8 @@ void tst_QUdpSocket::ipv6Loop() paul.setProperty("_q_networksession", QVariant::fromValue(networkSession)); #endif - quint16 peterPort; - quint16 paulPort; + int peterPort; + int paulPort; if (!peter.bind(QHostAddress(QHostAddress::LocalHostIPv6), 0)) { QCOMPARE(peter.error(), QUdpSocket::UnsupportedSocketOperationError); @@ -502,6 +533,8 @@ void tst_QUdpSocket::ipv6Loop() QVERIFY(paul.bind(QHostAddress(QHostAddress::LocalHostIPv6), 0)); + QHostAddress peterAddress = makeNonAny(peter.localAddress()); + QHostAddress paulAddress = makeNonAny(paul.localAddress()); peterPort = peter.localPort(); paulPort = paul.localPort(); @@ -510,20 +543,33 @@ void tst_QUdpSocket::ipv6Loop() QCOMPARE(paul.writeDatagram(paulMessage.data(), paulMessage.length(), QHostAddress("::1"), peterPort), qint64(paulMessage.length())); - char peterBuffer[16*1024]; - char paulBuffer[16*1024]; QVERIFY(peter.waitForReadyRead(5000)); QVERIFY(paul.waitForReadyRead(5000)); + QNetworkDatagram peterDatagram = peter.receiveDatagram(paulMessage.length() * 2); + QNetworkDatagram paulDatagram = paul.receiveDatagram(peterMessage.length() * 2); + if (success) { - QCOMPARE(peter.readDatagram(peterBuffer, sizeof(peterBuffer)), qint64(paulMessage.length())); - QCOMPARE(paul.readDatagram(paulBuffer, sizeof(peterBuffer)), qint64(peterMessage.length())); + QCOMPARE(peterDatagram.data().length(), qint64(paulMessage.length())); + QCOMPARE(paulDatagram.data().length(), qint64(peterMessage.length())); } else { - QVERIFY(peter.readDatagram(peterBuffer, sizeof(peterBuffer)) != paulMessage.length()); - QVERIFY(paul.readDatagram(paulBuffer, sizeof(peterBuffer)) != peterMessage.length()); + // this code path seems to never be executed + QVERIFY(peterDatagram.data().length() != paulMessage.length()); + QVERIFY(paulDatagram.data().length() != peterMessage.length()); } - QCOMPARE(QByteArray(peterBuffer, paulMessage.length()), paulMessage); - QCOMPARE(QByteArray(paulBuffer, peterMessage.length()), peterMessage); + QCOMPARE(peterDatagram.data().left(paulMessage.length()), paulMessage); + QCOMPARE(paulDatagram.data().left(peterMessage.length()), peterMessage); + + QCOMPARE(peterDatagram.senderAddress(), paulAddress); + QCOMPARE(paulDatagram.senderAddress(), peterAddress); + QCOMPARE(paulDatagram.senderPort(), peterPort); + QCOMPARE(peterDatagram.senderPort(), paulPort); + + // For IPv6, IPV6_PKTINFO is a mandatory feature (RFC 3542). + QCOMPARE(peterDatagram.destinationAddress(), makeNonAny(peter.localAddress())); + QCOMPARE(paulDatagram.destinationAddress(), makeNonAny(paul.localAddress())); + QCOMPARE(peterDatagram.destinationPort(), peterPort); + QCOMPARE(paulDatagram.destinationPort(), paulPort); } void tst_QUdpSocket::dualStack() @@ -539,17 +585,23 @@ void tst_QUdpSocket::dualStack() QByteArray v4Data("v4"); QVERIFY(v4Sock.bind(QHostAddress(QHostAddress::AnyIPv4), 0)); - QHostAddress from; - quint16 port; - QByteArray buffer; //test v4 -> dual QCOMPARE((int)v4Sock.writeDatagram(v4Data.constData(), v4Data.length(), QHostAddress(QHostAddress::LocalHost), dualSock.localPort()), v4Data.length()); QVERIFY2(dualSock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(dualSock).constData()); - buffer.reserve(100); - qint64 size = dualSock.readDatagram(buffer.data(), 100, &from, &port); - QCOMPARE((int)size, v4Data.length()); - buffer.resize(size); - QCOMPARE(buffer, v4Data); + QNetworkDatagram dgram = dualSock.receiveDatagram(100); + QVERIFY(dgram.isValid()); + QCOMPARE(dgram.data(), v4Data); + QCOMPARE(dgram.senderPort(), int(v4Sock.localPort())); + // receiving v4 on dual stack will receive as IPv6, so use isEqual() + QVERIFY(dgram.senderAddress().isEqual(makeNonAny(v4Sock.localAddress(), QHostAddress::Null))); + if (dualSock.localAddress().protocol() == QAbstractSocket::IPv4Protocol) + QCOMPARE(dgram.senderAddress(), makeNonAny(v4Sock.localAddress(), QHostAddress::Null)); + if (dgram.destinationPort() != -1) { + QCOMPARE(dgram.destinationPort(), int(dualSock.localPort())); + QVERIFY(dgram.destinationAddress().isEqual(dualSock.localAddress())); + } else { + qInfo("Getting IPv4 destination address failed."); + } if (QtNetworkSettings::hasIPv6()) { QUdpSocket v6Sock; @@ -559,30 +611,41 @@ void tst_QUdpSocket::dualStack() //test v6 -> dual QCOMPARE((int)v6Sock.writeDatagram(v6Data.constData(), v6Data.length(), QHostAddress(QHostAddress::LocalHostIPv6), dualSock.localPort()), v6Data.length()); QVERIFY2(dualSock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(dualSock).constData()); - buffer.reserve(100); - size = dualSock.readDatagram(buffer.data(), 100, &from, &port); - QCOMPARE((int)size, v6Data.length()); - buffer.resize(size); - QCOMPARE(buffer, v6Data); + dgram = dualSock.receiveDatagram(100); + QVERIFY(dgram.isValid()); + QCOMPARE(dgram.data(), v6Data); + QCOMPARE(dgram.senderPort(), int(v6Sock.localPort())); + QCOMPARE(dgram.senderAddress(), makeNonAny(v6Sock.localAddress(), QHostAddress::LocalHostIPv6)); + QCOMPARE(dgram.destinationPort(), int(dualSock.localPort())); + QCOMPARE(dgram.destinationAddress(), makeNonAny(dualSock.localAddress(), QHostAddress::LocalHostIPv6)); //test dual -> v6 QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHostIPv6), v6Sock.localPort()), dualData.length()); QVERIFY2(v6Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v6Sock).constData()); - buffer.reserve(100); - size = v6Sock.readDatagram(buffer.data(), 100, &from, &port); - QCOMPARE((int)size, dualData.length()); - buffer.resize(size); - QCOMPARE(buffer, dualData); + dgram = v6Sock.receiveDatagram(100); + QVERIFY(dgram.isValid()); + QCOMPARE(dgram.data(), dualData); + QCOMPARE(dgram.senderPort(), int(dualSock.localPort())); + QCOMPARE(dgram.senderAddress(), makeNonAny(dualSock.localAddress(), QHostAddress::LocalHostIPv6)); + QCOMPARE(dgram.destinationPort(), int(v6Sock.localPort())); + QCOMPARE(dgram.destinationAddress(), makeNonAny(v6Sock.localAddress(), QHostAddress::LocalHostIPv6)); } //test dual -> v4 QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHost), v4Sock.localPort()), dualData.length()); QVERIFY2(v4Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v4Sock).constData()); - buffer.reserve(100); - size = v4Sock.readDatagram(buffer.data(), 100, &from, &port); - QCOMPARE((int)size, dualData.length()); - buffer.resize(size); - QCOMPARE(buffer, dualData); + dgram = v4Sock.receiveDatagram(100); + QVERIFY(dgram.isValid()); + QCOMPARE(dgram.data(), dualData); + QCOMPARE(dgram.senderPort(), int(dualSock.localPort())); + QCOMPARE(dgram.senderAddress(), makeNonAny(dualSock.localAddress(), QHostAddress::LocalHost)); +#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) || defined(Q_OS_WIN) + QVERIFY(dgram.destinationPort() != -1); +#endif + if (dgram.destinationPort() != -1) { + QCOMPARE(dgram.destinationPort(), int(v4Sock.localPort())); + QCOMPARE(dgram.destinationAddress(), makeNonAny(v4Sock.localAddress(), QHostAddress::LocalHost)); + } } void tst_QUdpSocket::dualStackAutoBinding() @@ -1603,6 +1666,8 @@ void tst_QUdpSocket::linkLocalIPv6() QVERIFY(dgram.isValid()); QCOMPARE(dgram.senderAddress(), s->localAddress()); QCOMPARE(dgram.senderPort(), int(s->localPort())); + QCOMPARE(dgram.destinationAddress(), s->localAddress()); + QCOMPARE(dgram.destinationPort(), int(neutral.localPort())); QCOMPARE(dgram.data().length(), testData.length()); QCOMPARE(dgram.data(), testData); @@ -1684,6 +1749,20 @@ void tst_QUdpSocket::linkLocalIPv4() QCOMPARE(dgram.data().length(), testData.length()); QCOMPARE(dgram.data(), testData); + // Unlike for IPv6 with IPV6_PKTINFO, IPv4 has no standardized way of + // obtaining the packet's destination addresses. The destinationAddress + // and destinationPort calls could fail, so whitelist the OSes we know + // we have an implementation. +#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) || defined(Q_OS_WIN) + QVERIFY(dgram.destinationPort() != -1); +#endif + if (dgram.destinationPort() == -1) { + QCOMPARE(dgram.destinationAddress().protocol(), QAbstractSocket::UnknownNetworkLayerProtocol); + } else { + QCOMPARE(dgram.destinationAddress(), s->localAddress()); + QCOMPARE(dgram.destinationPort(), int(neutral.localPort())); + } + QVERIFY(neutral.writeDatagram(dgram.makeReply(testData))); dgram = s->receiveDatagram(testData.length() * 2); -- cgit v1.2.3 From 84396a3f938453b81e6ecc73bd54ff6b08960e8f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 3 Nov 2017 13:55:50 +0100 Subject: tst_QNetworkReply: Blacklist ioHttpRedirectPostPut for Linux Change-Id: I7db143bbd2e178e944f4cfc6c184850238f3bc8c Reviewed-by: Timur Pocheptsov --- tests/auto/network/access/qnetworkreply/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index 5edae13e34..091ec28bea 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -26,6 +26,8 @@ windows linux [ioHttpRedirectPolicy] b2qt 64bit +[ioHttpRedirectPostPut] +linux [putWithServerClosingConnectionImmediately] windows [qtbug28035browserDoesNotLoadQtProjectOrgCorrectly] -- cgit v1.2.3 From 254849b62a4aa5a34f18bf8e47a9cb9293d3f8b9 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 30 Oct 2017 09:15:23 +0100 Subject: macOS: Blacklist tst_QSequentialAnimationGroup::groupWithZeroDurationAnimations() Task-number: QTBUG-64109 Change-Id: Iebe5a07d108ba647baa74ded71b730c867bd1c41 Reviewed-by: Jesus Fernandez --- tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST b/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST index 391e3f67af..2a31afd735 100644 --- a/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST +++ b/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST @@ -3,3 +3,5 @@ windows [finishWithUncontrolledAnimation] windows osx-10.12 +[groupWithZeroDurationAnimations] +osx -- cgit v1.2.3 From 8ba1f91d4eed03be09046bf4ef81944787316ef9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 26 Oct 2017 10:06:10 +0200 Subject: macOS: Add logging of screen add/remove/changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ic9c9ac307441dde98bb43d656466a03805746917 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoaintegration.mm | 5 +++++ src/plugins/platforms/cocoa/qcocoascreen.h | 4 ++++ src/plugins/platforms/cocoa/qcocoascreen.mm | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index dd17848109..d185905782 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -222,6 +222,8 @@ QCocoaIntegration::Options QCocoaIntegration::options() const return mOptions; } +Q_LOGGING_CATEGORY(lcCocoaScreen, "qt.qpa.cocoa.screens"); + /*! \brief Synchronizes the screen list, adds new screens, removes deleted ones */ @@ -261,9 +263,11 @@ void QCocoaIntegration::updateScreens() if (screen) { remainingScreens.remove(screen); screen->updateGeometry(); + qCDebug(lcCocoaScreen) << "Updated properties of" << screen; } else { screen = new QCocoaScreen(i); mScreens.append(screen); + qCDebug(lcCocoaScreen) << "Adding" << screen; screenAdded(screen); } siblings << screen; @@ -280,6 +284,7 @@ void QCocoaIntegration::updateScreens() mScreens.removeOne(screen); // Prevent stale references to NSScreen during destroy screen->m_screenIndex = -1; + qCDebug(lcCocoaScreen) << "Removing" << screen; destroyScreen(screen); } } diff --git a/src/plugins/platforms/cocoa/qcocoascreen.h b/src/plugins/platforms/cocoa/qcocoascreen.h index eb17efa937..937002f493 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.h +++ b/src/plugins/platforms/cocoa/qcocoascreen.h @@ -102,6 +102,10 @@ public: QList m_siblings; }; +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug debug, const QCocoaScreen *screen); +#endif + QT_END_NAMESPACE #endif diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index 13e5220b6a..f523873bde 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -275,4 +275,22 @@ QCocoaScreen *QCocoaScreen::primaryScreen() return static_cast(QGuiApplication::primaryScreen()->handle()); } +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug debug, const QCocoaScreen *screen) +{ + QDebugStateSaver saver(debug); + debug.nospace(); + debug << "QCocoaScreen(" << (const void *)screen; + if (screen) { + debug << ", index=" << screen->m_screenIndex; + debug << ", native=" << screen->nativeScreen(); + debug << ", geometry=" << screen->geometry(); + debug << ", dpr=" << screen->devicePixelRatio(); + debug << ", name=" << screen->name(); + } + debug << ')'; + return debug; +} +#endif // !QT_NO_DEBUG_STREAM + QT_END_NAMESPACE -- cgit v1.2.3 From 01f5f77c66dd6e4c15e0e0d8445e3560543e1973 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Mon, 30 Oct 2017 13:44:03 +0100 Subject: tests: skip tst_QMenuBar::check_cursorKeys* on Unity This test is flaky on Unity due to regression introduced by QTBUG-39362. Skip the test functions until QTBUG-39362 is resolved. These test functions do not fail on Gnome and KDE, so the functionality tested by check_cursorKeys* will be covered by other linux distributions in CI. Change-Id: Ifd1a7779a9728142424f4956dd6466c822ccde91 Reviewed-by: Frederik Gladhorn --- tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp index 12afb77281..65181a9516 100644 --- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp @@ -633,6 +633,9 @@ void tst_QMenuBar::check_accelKeys() #if !defined(Q_OS_DARWIN) void tst_QMenuBar::check_cursorKeys1() { + if (qgetenv("XDG_CURRENT_DESKTOP") == "Unity") + QSKIP("This test is flaky on Ubuntu/Unity due to regression introduced by QTBUG-39362"); + QMainWindow w; initWindowWithComplexMenuBar(w); w.show(); @@ -667,6 +670,9 @@ void tst_QMenuBar::check_cursorKeys1() #if !defined(Q_OS_DARWIN) void tst_QMenuBar::check_cursorKeys2() { + if (qgetenv("XDG_CURRENT_DESKTOP") == "Unity") + QSKIP("This test is flaky on Ubuntu/Unity due to regression introduced by QTBUG-39362"); + QMainWindow w; initWindowWithComplexMenuBar(w); w.show(); @@ -700,6 +706,9 @@ void tst_QMenuBar::check_cursorKeys2() #if !defined(Q_OS_DARWIN) void tst_QMenuBar::check_cursorKeys3() { + if (qgetenv("XDG_CURRENT_DESKTOP") == "Unity") + QSKIP("This test is flaky on Ubuntu/Unity due to regression introduced by QTBUG-39362"); + QMainWindow w; initWindowWithComplexMenuBar(w); w.show(); -- cgit v1.2.3 From ad36da8ff416501e249beb098e5b84eaa2fba43d Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Mon, 30 Oct 2017 13:45:18 +0100 Subject: testlib: start sharing common helper functions ... by moving them in QTestPrivate namespace (qtesthelpers_p.h). This header file is a convenient staging area for helper APIs, eventually some could be moved to public QTest API. This header file utilizes the same pattern as other qtestlib header files - wrapping functions with QT_${LIBNAME}_LIB to automatically enable certain APIs based on what is in the projects dependencies, e.g. QT += widgets. Change-Id: Ic0266429939c1f3788912ad8b84fc6e0d5edd68b Reviewed-by: Edward Welbourne --- src/testlib/qtesthelpers_p.h | 112 +++++++++++++++++++++ src/testlib/testlib.pro | 3 +- .../corelib/io/qtemporarydir/qtemporarydir.pro | 2 +- .../corelib/io/qtemporarydir/tst_qtemporarydir.cpp | 13 +-- .../corelib/io/qtemporaryfile/qtemporaryfile.pro | 2 +- .../io/qtemporaryfile/tst_qtemporaryfile.cpp | 16 +-- tests/auto/other/qaccessibility/qaccessibility.pro | 2 +- .../other/qaccessibility/tst_qaccessibility.cpp | 12 +-- .../graphicsview/qgraphicsitem/qgraphicsitem.pro | 2 +- .../qgraphicsitem/tst_qgraphicsitem.cpp | 14 +-- .../graphicsview/qgraphicsview/qgraphicsview.pro | 2 +- .../qgraphicsview/tst_qgraphicsview.cpp | 12 +-- .../qabstractitemview/qabstractitemview.pro | 2 +- .../qabstractitemview/tst_qabstractitemview.cpp | 15 +-- .../widgets/itemviews/qcolumnview/qcolumnview.pro | 2 +- .../itemviews/qcolumnview/tst_qcolumnview.cpp | 11 +- .../auto/widgets/itemviews/qlistview/qlistview.pro | 2 +- .../widgets/itemviews/qlistview/tst_qlistview.cpp | 14 +-- .../widgets/itemviews/qtableview/qtableview.pro | 2 +- .../itemviews/qtableview/tst_qtableview.cpp | 14 +-- .../auto/widgets/itemviews/qtreeview/qtreeview.pro | 2 +- .../widgets/itemviews/qtreeview/tst_qtreeview.cpp | 14 +-- .../auto/widgets/kernel/qboxlayout/qboxlayout.pro | 2 +- .../widgets/kernel/qboxlayout/tst_qboxlayout.cpp | 10 +- .../widgets/kernel/qformlayout/qformlayout.pro | 2 +- .../widgets/kernel/qformlayout/tst_qformlayout.cpp | 12 +-- .../widgets/kernel/qgridlayout/qgridlayout.pro | 2 +- .../widgets/kernel/qgridlayout/tst_qgridlayout.cpp | 12 +-- tests/auto/widgets/kernel/qlayout/qlayout.pro | 2 +- tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp | 10 +- tests/auto/widgets/kernel/qwidget/qwidget.pro | 2 +- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 19 +--- .../kernel/qwidget_window/qwidget_window.pro | 2 +- .../kernel/qwidget_window/tst_qwidget_window.cpp | 10 +- .../widgets/kernel/qwidgetaction/qwidgetaction.pro | 2 +- .../kernel/qwidgetaction/tst_qwidgetaction.cpp | 10 +- tests/auto/widgets/styles/qstyle/qstyle.pro | 2 +- tests/auto/widgets/styles/qstyle/tst_qstyle.cpp | 12 +-- .../styles/qstylesheetstyle/qstylesheetstyle.pro | 2 +- .../qstylesheetstyle/tst_qstylesheetstyle.cpp | 7 +- tests/auto/widgets/util/qcompleter/qcompleter.pro | 2 +- .../widgets/util/qcompleter/tst_qcompleter.cpp | 10 +- .../widgets/qabstractslider/qabstractslider.pro | 2 +- .../qabstractslider/tst_qabstractslider.cpp | 12 +-- .../widgets/qabstractspinbox/qabstractspinbox.pro | 2 +- .../qabstractspinbox/tst_qabstractspinbox.cpp | 13 +-- tests/auto/widgets/widgets/qcombobox/qcombobox.pro | 2 +- .../widgets/widgets/qcombobox/tst_qcombobox.cpp | 10 +- tests/auto/widgets/widgets/qlineedit/qlineedit.pro | 2 +- .../widgets/widgets/qlineedit/tst_qlineedit.cpp | 12 +-- tests/auto/widgets/widgets/qmenu/qmenu.pro | 2 +- tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp | 14 +-- tests/auto/widgets/widgets/qmenubar/qmenubar.pro | 2 +- .../auto/widgets/widgets/qmenubar/tst_qmenubar.cpp | 10 +- .../auto/widgets/widgets/qscrollbar/qscrollbar.pro | 2 +- .../widgets/widgets/qscrollbar/tst_qscrollbar.cpp | 11 +- 56 files changed, 223 insertions(+), 275 deletions(-) create mode 100644 src/testlib/qtesthelpers_p.h diff --git a/src/testlib/qtesthelpers_p.h b/src/testlib/qtesthelpers_p.h new file mode 100644 index 0000000000..0e39f7aea2 --- /dev/null +++ b/src/testlib/qtesthelpers_p.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtTest module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTESTHELPERS_P_H +#define QTESTHELPERS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include + +#ifdef QT_GUI_LIB +#include +#include +#endif + +#ifdef QT_WIDGETS_LIB +#include +#endif + +QT_BEGIN_NAMESPACE + +namespace QTestPrivate { + +static inline bool canHandleUnicodeFileNames() +{ +#if defined(Q_OS_WIN) + return true; +#else + // Check for UTF-8 by converting the Euro symbol (see tst_utf8) + return QFile::encodeName(QString(QChar(0x20AC))) == QByteArrayLiteral("\342\202\254"); +#endif +} + +#ifdef QT_WIDGETS_LIB +static inline void centerOnScreen(QWidget *w, const QSize &size) +{ + const QPoint offset = QPoint(size.width() / 2, size.height() / 2); + w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset); +} + +static inline void centerOnScreen(QWidget *w) +{ + centerOnScreen(w, w->geometry().size()); +} + +/*! \internal + + Make a widget frameless to prevent size constraints of title bars from interfering (Windows). +*/ +static inline void setFrameless(QWidget *w) +{ + Qt::WindowFlags flags = w->windowFlags(); + flags |= Qt::FramelessWindowHint; + flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint + | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); + w->setWindowFlags(flags); +} +#endif // QT_WIDGETS_LIB + +} // namespace QTestPrivate + +QT_END_NAMESPACE + +#endif // QTESTHELPERS_P_H diff --git a/src/testlib/testlib.pro b/src/testlib/testlib.pro index e11e25e1da..f99f28ca84 100644 --- a/src/testlib/testlib.pro +++ b/src/testlib/testlib.pro @@ -37,7 +37,8 @@ HEADERS = qbenchmark.h \ qtestspontaneevent.h \ qtestsystem.h \ qtesttouch.h \ - qtestblacklist_p.h + qtestblacklist_p.h \ + qtesthelpers_p.h SOURCES = qtestcase.cpp \ qtestlog.cpp \ diff --git a/tests/auto/corelib/io/qtemporarydir/qtemporarydir.pro b/tests/auto/corelib/io/qtemporarydir/qtemporarydir.pro index 351e263093..5908648378 100644 --- a/tests/auto/corelib/io/qtemporarydir/qtemporarydir.pro +++ b/tests/auto/corelib/io/qtemporarydir/qtemporarydir.pro @@ -4,4 +4,4 @@ SOURCES += tst_qtemporarydir.cpp INCLUDEPATH += ../../../../shared/ HEADERS += ../../../../shared/emulationdetector.h -QT = core testlib +QT = core testlib testlib-private diff --git a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp index 4bed8d0fd6..4cb3bfe549 100644 --- a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp +++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef Q_OS_WIN # include #endif @@ -112,16 +113,6 @@ void tst_QTemporaryDir::getSetCheck() QCOMPARE(true, obj1.autoRemove()); } -static inline bool canHandleUnicodeFileNames() -{ -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) - return true; -#else - // Check for UTF-8 by converting the Euro symbol (see tst_utf8) - return QFile::encodeName(QString(QChar(0x20AC))) == QByteArrayLiteral("\342\202\254"); -#endif -} - static QString hanTestText() { QString text; @@ -160,7 +151,7 @@ void tst_QTemporaryDir::fileTemplate_data() QTest::newRow("constructor with XXXX suffix") << "qt_XXXXXX_XXXX" << "qt_"; QTest::newRow("constructor with XXXX prefix") << "qt_XXXX" << "qt_"; QTest::newRow("constructor with XXXXX prefix") << "qt_XXXXX" << "qt_"; - if (canHandleUnicodeFileNames()) { + if (QTestPrivate::canHandleUnicodeFileNames()) { // Test Umlauts (contained in Latin1) QString prefix = "qt_" + umlautTestText(); QTest::newRow("Umlauts") << (prefix + "XXXXXX") << prefix; diff --git a/tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.pro b/tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.pro index a89e5c66ff..e17cb05cd8 100644 --- a/tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.pro +++ b/tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qtemporaryfile -QT = core testlib +QT = core testlib testlib-private SOURCES = tst_qtemporaryfile.cpp TESTDATA += tst_qtemporaryfile.cpp RESOURCES += qtemporaryfile.qrc diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp index ab6b435125..64b61839c1 100644 --- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp +++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp @@ -36,6 +36,8 @@ #include #include +#include + #if defined(Q_OS_WIN) # include #endif @@ -141,16 +143,6 @@ void tst_QTemporaryFile::getSetCheck() QCOMPARE(true, obj1.autoRemove()); } -static inline bool canHandleUnicodeFileNames() -{ -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) - return true; -#else - // Check for UTF-8 by converting the Euro symbol (see tst_utf8) - return QFile::encodeName(QString(QChar(0x20AC))) == QByteArrayLiteral("\342\202\254"); -#endif -} - static QString hanTestText() { QString text; @@ -199,7 +191,7 @@ void tst_QTemporaryFile::fileTemplate_data() QTest::newRow("set template, with xxx") << "" << "qt_" << ".xxx" << "qt_XXXXXX.xxx"; QTest::newRow("set template, with >6 X's") << "" << "qt_" << ".xxx" << "qt_XXXXXXXXXXXXXX.xxx"; QTest::newRow("set template, with >6 X's, no suffix") << "" << "qt_" << "" << "qt_XXXXXXXXXXXXXX"; - if (canHandleUnicodeFileNames()) { + if (QTestPrivate::canHandleUnicodeFileNames()) { // Test Umlauts (contained in Latin1) QString prefix = "qt_" + umlautTestText(); QTest::newRow("Umlauts") << (prefix + "XXXXXX") << prefix << QString() << QString(); @@ -761,7 +753,7 @@ void tst_QTemporaryFile::QTBUG_4796_data() QTest::newRow("XXXXXXbla") << QString() << QString("bla") << true; QTest::newRow("does-not-exist/qt_temp.XXXXXX") << QString("does-not-exist/qt_temp") << QString() << false; - if (canHandleUnicodeFileNames()) { + if (QTestPrivate::canHandleUnicodeFileNames()) { QTest::newRow("XXXXXX") << QString() << unicode << true; QTest::newRow("XXXXXX") << unicode << QString() << true; QTest::newRow("XXXXXX") << unicode << unicode << true; diff --git a/tests/auto/other/qaccessibility/qaccessibility.pro b/tests/auto/other/qaccessibility/qaccessibility.pro index 727d5fe0d7..bfe652d25a 100644 --- a/tests/auto/other/qaccessibility/qaccessibility.pro +++ b/tests/auto/other/qaccessibility/qaccessibility.pro @@ -1,7 +1,7 @@ CONFIG += testcase TARGET = tst_qaccessibility requires(qtConfig(accessibility)) -QT += testlib core-private gui-private widgets-private +QT += testlib core-private gui-private widgets-private testlib-private SOURCES += tst_qaccessibility.cpp HEADERS += accessiblewidgets.h diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index b857501e8f..d98bbe28b7 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -59,15 +59,9 @@ #include "accessiblewidgets.h" -// Make a widget frameless to prevent size constraints of title bars -// from interfering (Windows). -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} +#include + +using namespace QTestPrivate; static inline bool verifyChild(QWidget *child, QAccessibleInterface *interface, int index, const QRect &domain) diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro b/tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro index 88526144fc..ae6de48195 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qgraphicsitem -QT += widgets widgets-private testlib +QT += widgets widgets-private testlib testlib-private QT += core-private gui-private SOURCES += tst_qgraphicsitem.cpp DEFINES += QT_NO_CAST_TO_ASCII diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index 96827022a8..0fc1a643b4 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -28,6 +28,7 @@ #include +#include #include #include @@ -127,17 +128,6 @@ static void sendKeyClick(QGraphicsScene *scene, Qt::Key key) sendKeyRelease(scene, key); } -static inline void centerOnScreen(QWidget *w, const QSize &size) -{ - const QPoint offset = QPoint(size.width() / 2, size.height() / 2); - w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset); -} - -static inline void centerOnScreen(QWidget *w) -{ - centerOnScreen(w, w->geometry().size()); -} - class EventSpy : public QGraphicsWidget { Q_OBJECT @@ -4211,7 +4201,7 @@ void tst_QGraphicsItem::cursor() QWidget topLevel; topLevel.resize(250, 150); - centerOnScreen(&topLevel); + QTestPrivate::centerOnScreen(&topLevel); QGraphicsView view(&scene,&topLevel); view.setFixedSize(200, 100); topLevel.show(); diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/qgraphicsview.pro b/tests/auto/widgets/graphicsview/qgraphicsview/qgraphicsview.pro index 258b5e0e14..8ed19697a4 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/qgraphicsview.pro +++ b/tests/auto/widgets/graphicsview/qgraphicsview/qgraphicsview.pro @@ -3,7 +3,7 @@ testcase.timeout = 500 # this test is slow TARGET = tst_qgraphicsview QT += widgets widgets-private testlib -QT += core-private gui-private +QT += core-private gui-private testlib-private SOURCES += tst_qgraphicsview.cpp tst_qgraphicsview_2.cpp HEADERS += tst_qgraphicsview.h diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index 5900c85627..5b557dba58 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -61,6 +61,10 @@ #include "tst_qgraphicsview.h" +#include + +using namespace QTestPrivate; + Q_DECLARE_METATYPE(ExpectedValueDescription) Q_DECLARE_METATYPE(QList) Q_DECLARE_METATYPE(QList) @@ -130,14 +134,6 @@ class FriendlyGraphicsScene : public QGraphicsScene }; #endif -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} - class tst_QGraphicsView : public QObject { Q_OBJECT diff --git a/tests/auto/widgets/itemviews/qabstractitemview/qabstractitemview.pro b/tests/auto/widgets/itemviews/qabstractitemview/qabstractitemview.pro index 2f0ca73265..4ee7f28af6 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/qabstractitemview.pro +++ b/tests/auto/widgets/itemviews/qabstractitemview/qabstractitemview.pro @@ -1,4 +1,4 @@ CONFIG += testcase TARGET = tst_qabstractitemview -QT += widgets testlib +QT += widgets testlib testlib-private SOURCES += tst_qabstractitemview.cpp diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp index 2234b2b488..165c4b079e 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp @@ -28,6 +28,7 @@ #include +#include #include #include @@ -57,19 +58,7 @@ Q_DECLARE_METATYPE(Qt::ItemFlags); -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} - -static inline void centerOnScreen(QWidget *w) -{ - const QPoint offset = QPoint(w->width() / 2, w->height() / 2); - w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset); -} +using namespace QTestPrivate; // Move cursor out of widget area to avoid undesired interaction on Mac. static inline void moveCursorAway(const QWidget *topLevel) diff --git a/tests/auto/widgets/itemviews/qcolumnview/qcolumnview.pro b/tests/auto/widgets/itemviews/qcolumnview/qcolumnview.pro index 5096cc691a..0b3dcd9e80 100644 --- a/tests/auto/widgets/itemviews/qcolumnview/qcolumnview.pro +++ b/tests/auto/widgets/itemviews/qcolumnview/qcolumnview.pro @@ -1,6 +1,6 @@ CONFIG += testcase QT += widgets widgets-private -QT += gui-private core-private testlib +QT += gui-private core-private testlib testlib-private SOURCES += tst_qcolumnview.cpp HEADERS += ../../../../shared/fakedirmodel.h diff --git a/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp b/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp index 62acf49f4a..38e6d95ba4 100644 --- a/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp +++ b/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp @@ -28,6 +28,7 @@ #include "../../../../shared/fakedirmodel.h" #include +#include #include #include #include @@ -369,12 +370,6 @@ void tst_QColumnView::scrollTo_data() QTest::newRow("reverse") << true << false; } -static inline void centerOnScreen(QWidget *w) -{ - const QPoint offset = QPoint(w->width() / 2, w->height() / 2); - w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset); -} - void tst_QColumnView::scrollTo() { QFETCH(bool, reverse); @@ -386,7 +381,7 @@ void tst_QColumnView::scrollTo() view.resize(200, 200); topLevel.show(); topLevel.activateWindow(); - centerOnScreen(&topLevel); + QTestPrivate::centerOnScreen(&topLevel); QVERIFY(QTest::qWaitForWindowActive(&topLevel)); view.scrollTo(QModelIndex(), QAbstractItemView::EnsureVisible); @@ -1004,7 +999,7 @@ void tst_QColumnView::dynamicModelChanges() ColumnView view; view.setModel(&model); view.setItemDelegate(&delegate); - centerOnScreen(&view); + QTestPrivate::centerOnScreen(&view); view.show(); QStandardItem *item = new QStandardItem(QLatin1String("item")); diff --git a/tests/auto/widgets/itemviews/qlistview/qlistview.pro b/tests/auto/widgets/itemviews/qlistview/qlistview.pro index 44e25ded66..e49a0c5fbf 100644 --- a/tests/auto/widgets/itemviews/qlistview/qlistview.pro +++ b/tests/auto/widgets/itemviews/qlistview/qlistview.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qlistview -QT += widgets gui-private widgets-private core-private testlib +QT += widgets gui-private widgets-private core-private testlib testlib-private SOURCES += tst_qlistview.cpp win32:!winrt: LIBS += -luser32 linux*: CONFIG += insignificant_test # Crashes diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index b9785c35ac..d8b8546d86 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -46,6 +46,10 @@ #include #include +#include + +using namespace QTestPrivate; + #if defined(Q_OS_WIN) # include # include @@ -64,16 +68,6 @@ Q_DECLARE_METATYPE(QAbstractItemView::ScrollMode) Q_DECLARE_METATYPE(QMargins) Q_DECLARE_METATYPE(QSize) -// Make a widget frameless to prevent size constraints of title bars -// from interfering (Windows). -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} - static QStringList generateList(const QString &prefix, int size) { QStringList result; diff --git a/tests/auto/widgets/itemviews/qtableview/qtableview.pro b/tests/auto/widgets/itemviews/qtableview/qtableview.pro index e02da95ab9..a02f96eb99 100644 --- a/tests/auto/widgets/itemviews/qtableview/qtableview.pro +++ b/tests/auto/widgets/itemviews/qtableview/qtableview.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qtableview QT += widgets widgets-private testlib -QT += core-private gui-private +QT += core-private gui-private testlib-private SOURCES += tst_qtableview.cpp diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index a27e0b6048..4e401ddd86 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -35,6 +35,10 @@ #include +#include + +using namespace QTestPrivate; + #ifdef QT_BUILD_INTERNAL #define VERIFY_SPANS_CONSISTENCY(TEST_VIEW_) \ QVERIFY(static_cast(QObjectPrivate::get(TEST_VIEW_))->spans.checkConsistency()) @@ -46,16 +50,6 @@ typedef QList IntList; typedef QList BoolList; -// Make a widget frameless to prevent size constraints of title bars -// from interfering (Windows). -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} - class tst_QTableView : public QObject { Q_OBJECT diff --git a/tests/auto/widgets/itemviews/qtreeview/qtreeview.pro b/tests/auto/widgets/itemviews/qtreeview/qtreeview.pro index 3abd58e73d..2530b44935 100644 --- a/tests/auto/widgets/itemviews/qtreeview/qtreeview.pro +++ b/tests/auto/widgets/itemviews/qtreeview/qtreeview.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qtreeview QT += widgets testlib -QT += widgets-private gui-private core-private +QT += widgets-private gui-private core-private testlib-private SOURCES += tst_qtreeview.cpp HEADERS += ../../../../shared/fakedirmodel.h diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index e2886cfcfe..6ee0e50cce 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -33,6 +33,10 @@ #include #include +#include + +using namespace QTestPrivate; + #ifndef QT_NO_DRAGANDDROP Q_DECLARE_METATYPE(QAbstractItemView::DragDropMode) #endif @@ -57,16 +61,6 @@ static void initStandardTreeModel(QStandardItemModel *model) model->insertRow(2, item); } -// Make a widget frameless to prevent size constraints of title bars -// from interfering (Windows). -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} - class tst_QTreeView : public QObject { Q_OBJECT diff --git a/tests/auto/widgets/kernel/qboxlayout/qboxlayout.pro b/tests/auto/widgets/kernel/qboxlayout/qboxlayout.pro index 90e83f5285..1a2c6d6f66 100644 --- a/tests/auto/widgets/kernel/qboxlayout/qboxlayout.pro +++ b/tests/auto/widgets/kernel/qboxlayout/qboxlayout.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qboxlayout -QT += widgets testlib +QT += widgets testlib testlib-private SOURCES += tst_qboxlayout.cpp diff --git a/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp b/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp index 0b35db1b5f..1dac242114 100644 --- a/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp +++ b/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp @@ -31,13 +31,9 @@ #include #include -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} +#include + +using namespace QTestPrivate; class tst_QBoxLayout : public QObject { diff --git a/tests/auto/widgets/kernel/qformlayout/qformlayout.pro b/tests/auto/widgets/kernel/qformlayout/qformlayout.pro index be944605a3..617183fee6 100644 --- a/tests/auto/widgets/kernel/qformlayout/qformlayout.pro +++ b/tests/auto/widgets/kernel/qformlayout/qformlayout.pro @@ -1,4 +1,4 @@ CONFIG += testcase TARGET = tst_qformlayout -QT += widgets testlib +QT += widgets testlib testlib-private SOURCES += tst_qformlayout.cpp diff --git a/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp b/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp index c324a4bd56..1ccda25339 100644 --- a/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp +++ b/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp @@ -41,20 +41,16 @@ #include #include +#include + +using namespace QTestPrivate; + #include // ItemRole has enumerators for numerical values 0..2, thus the only // valid numerical values for storing into an ItemRole variable are 0..3: Q_CONSTEXPR QFormLayout::ItemRole invalidRole = QFormLayout::ItemRole(3); -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} - struct QFormLayoutTakeRowResultHolder { QFormLayoutTakeRowResultHolder(QFormLayout::TakeRowResult result) Q_DECL_NOTHROW : labelItem(result.labelItem), diff --git a/tests/auto/widgets/kernel/qgridlayout/qgridlayout.pro b/tests/auto/widgets/kernel/qgridlayout/qgridlayout.pro index ee64f8538f..8947658e8c 100644 --- a/tests/auto/widgets/kernel/qgridlayout/qgridlayout.pro +++ b/tests/auto/widgets/kernel/qgridlayout/qgridlayout.pro @@ -2,7 +2,7 @@ CONFIG += testcase TARGET = tst_qgridlayout QT += widgets widgets-private testlib -QT += core-private gui-private +QT += core-private gui-private testlib-private SOURCES += tst_qgridlayout.cpp FORMS += sortdialog.ui diff --git a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp index c1ab5f51be..37e2bdb069 100644 --- a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp +++ b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp @@ -41,15 +41,9 @@ #include #include -// Make a widget frameless to prevent size constraints of title bars -// from interfering (Windows). -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} +#include + +using namespace QTestPrivate; class tst_QGridLayout : public QObject { diff --git a/tests/auto/widgets/kernel/qlayout/qlayout.pro b/tests/auto/widgets/kernel/qlayout/qlayout.pro index d460785158..8e0ea1bfdb 100644 --- a/tests/auto/widgets/kernel/qlayout/qlayout.pro +++ b/tests/auto/widgets/kernel/qlayout/qlayout.pro @@ -1,7 +1,7 @@ CONFIG += testcase TARGET = tst_qlayout -QT += widgets widgets-private testlib +QT += widgets widgets-private testlib testlib-private SOURCES += tst_qlayout.cpp TESTDATA += baseline/* diff --git a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp index 829d0ea098..a55693bb6c 100644 --- a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp +++ b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp @@ -44,13 +44,9 @@ #include #include -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} +#include + +using namespace QTestPrivate; class tst_QLayout : public QObject { diff --git a/tests/auto/widgets/kernel/qwidget/qwidget.pro b/tests/auto/widgets/kernel/qwidget/qwidget.pro index 499ca65516..3e4e96760b 100644 --- a/tests/auto/widgets/kernel/qwidget/qwidget.pro +++ b/tests/auto/widgets/kernel/qwidget/qwidget.pro @@ -2,7 +2,7 @@ CONFIG += testcase testcase.timeout = 600 # this test is slow TARGET = tst_qwidget -QT += widgets core-private gui-private widgets-private testlib +QT += widgets core-private gui-private widgets-private testlib testlib-private SOURCES += tst_qwidget.cpp RESOURCES = qwidget.qrc diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index baecc43f2c..a7aa99d2a8 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -72,6 +72,9 @@ #endif #include +#include + +using namespace QTestPrivate; #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) # include @@ -108,22 +111,6 @@ bool macHasAccessToWindowsServer() } #endif -// Make a widget frameless to prevent size constraints of title bars -// from interfering (Windows). -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} - -static inline void centerOnScreen(QWidget *w) -{ - const QPoint offset = QPoint(w->width() / 2, w->height() / 2); - w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset); -} - #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) static inline void setWindowsAnimationsEnabled(bool enabled) { diff --git a/tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro b/tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro index a6248dfd16..00bf763c35 100644 --- a/tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro +++ b/tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro @@ -1,4 +1,4 @@ CONFIG += testcase TARGET = tst_qwidget_window -QT += widgets testlib core-private gui-private +QT += widgets testlib core-private gui-private testlib-private SOURCES += tst_qwidget_window.cpp diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp index f20978c295..e4564a8640 100644 --- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp +++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp @@ -45,13 +45,9 @@ #include #include -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} +#include + +using namespace QTestPrivate; class tst_QWidget_window : public QObject { diff --git a/tests/auto/widgets/kernel/qwidgetaction/qwidgetaction.pro b/tests/auto/widgets/kernel/qwidgetaction/qwidgetaction.pro index e4158559a9..f443758eea 100644 --- a/tests/auto/widgets/kernel/qwidgetaction/qwidgetaction.pro +++ b/tests/auto/widgets/kernel/qwidgetaction/qwidgetaction.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qwidgetaction -QT += widgets testlib +QT += widgets testlib testlib-private SOURCES += tst_qwidgetaction.cpp diff --git a/tests/auto/widgets/kernel/qwidgetaction/tst_qwidgetaction.cpp b/tests/auto/widgets/kernel/qwidgetaction/tst_qwidgetaction.cpp index 1824285f05..28731223a9 100644 --- a/tests/auto/widgets/kernel/qwidgetaction/tst_qwidgetaction.cpp +++ b/tests/auto/widgets/kernel/qwidgetaction/tst_qwidgetaction.cpp @@ -38,13 +38,9 @@ #include #include -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} +#include + +using namespace QTestPrivate; class tst_QWidgetAction : public QObject { diff --git a/tests/auto/widgets/styles/qstyle/qstyle.pro b/tests/auto/widgets/styles/qstyle/qstyle.pro index a1e5a70a08..0fb7499946 100644 --- a/tests/auto/widgets/styles/qstyle/qstyle.pro +++ b/tests/auto/widgets/styles/qstyle/qstyle.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qstyle -QT += widgets testlib +QT += widgets testlib testlib-private SOURCES += tst_qstyle.cpp android { diff --git a/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp b/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp index fcb05f6b74..5369101dae 100644 --- a/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp +++ b/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp @@ -60,15 +60,9 @@ #include -// Make a widget frameless to prevent size constraints of title bars -// from interfering (Windows). -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} +#include + +using namespace QTestPrivate; class tst_QStyle : public QObject { diff --git a/tests/auto/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro b/tests/auto/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro index 7d9a8576d3..3bf1b94050 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro +++ b/tests/auto/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qstylesheetstyle -QT += widgets widgets-private gui-private testlib +QT += widgets widgets-private gui-private testlib testlib-private SOURCES += tst_qstylesheetstyle.cpp RESOURCES += resources.qrc diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp index 693b0b8aee..7953077152 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -33,12 +33,9 @@ #include #include +#include -static inline void centerOnScreen(QWidget *w) -{ - const QPoint offset = QPoint(w->width() / 2, w->height() / 2); - w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset); -} +using namespace QTestPrivate; class tst_QStyleSheetStyle : public QObject { diff --git a/tests/auto/widgets/util/qcompleter/qcompleter.pro b/tests/auto/widgets/util/qcompleter/qcompleter.pro index 19d8d500b8..fcdce93079 100644 --- a/tests/auto/widgets/util/qcompleter/qcompleter.pro +++ b/tests/auto/widgets/util/qcompleter/qcompleter.pro @@ -1,6 +1,6 @@ CONFIG += testcase TEMPLATE = app TARGET = tst_qcompleter -QT += widgets testlib +QT += widgets testlib testlib-private SOURCES += tst_qcompleter.cpp diff --git a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp index 3818b83584..92bcd5c350 100644 --- a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp @@ -34,15 +34,11 @@ #include #include +#include + #include "../../../../shared/filesystem.h" -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} +using namespace QTestPrivate; class CsvCompleter : public QCompleter { diff --git a/tests/auto/widgets/widgets/qabstractslider/qabstractslider.pro b/tests/auto/widgets/widgets/qabstractslider/qabstractslider.pro index 6453999786..95385e2172 100644 --- a/tests/auto/widgets/widgets/qabstractslider/qabstractslider.pro +++ b/tests/auto/widgets/widgets/qabstractslider/qabstractslider.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qabstractslider -QT += widgets testlib +QT += widgets testlib testlib-private SOURCES += tst_qabstractslider.cpp diff --git a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp index f0d74e7797..70ae453896 100644 --- a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp +++ b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp @@ -36,17 +36,13 @@ #include #include +#include + +using namespace QTestPrivate; + // defined to be 120 by the wheel mouse vendors according to the docs #define WHEEL_DELTA 120 -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} - class Slider : public QAbstractSlider { public: diff --git a/tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro b/tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro index be758a8bdd..a4a6f84ee4 100644 --- a/tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro +++ b/tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro @@ -4,7 +4,7 @@ CONFIG += testcase TARGET = tst_qabstractspinbox -QT += widgets gui-private core-private testlib +QT += widgets gui-private core-private testlib testlib-private SOURCES += tst_qabstractspinbox.cpp diff --git a/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp b/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp index 3fb4863b0e..0ce3b4cefe 100644 --- a/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp +++ b/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp @@ -28,6 +28,7 @@ #include +#include #include #include @@ -38,16 +39,6 @@ #include "../../../shared/platforminputcontext.h" #include -static inline void centerOnScreen(QWidget *w, const QSize &size) -{ - const QPoint offset = QPoint(size.width() / 2, size.height() / 2); - w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset); -} - -static inline void centerOnScreen(QWidget *w) -{ - centerOnScreen(w, w->geometry().size()); -} class tst_QAbstractSpinBox : public QObject { @@ -182,7 +173,7 @@ void tst_QAbstractSpinBox::inputMethodUpdate() QSpinBox *testWidget = &box; testWidget->setRange(0, 1); - centerOnScreen(testWidget); + QTestPrivate::centerOnScreen(testWidget); testWidget->clear(); testWidget->show(); QVERIFY(QTest::qWaitForWindowExposed(testWidget)); diff --git a/tests/auto/widgets/widgets/qcombobox/qcombobox.pro b/tests/auto/widgets/widgets/qcombobox/qcombobox.pro index 88b9d08557..939153dc88 100644 --- a/tests/auto/widgets/widgets/qcombobox/qcombobox.pro +++ b/tests/auto/widgets/widgets/qcombobox/qcombobox.pro @@ -1,4 +1,4 @@ CONFIG += testcase TARGET = tst_qcombobox -QT += widgets widgets-private gui-private core-private testlib +QT += widgets widgets-private gui-private core-private testlib testlib-private SOURCES += tst_qcombobox.cpp diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index bf190cf60a..2195f43ef1 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -67,13 +67,9 @@ #include "../../../shared/platforminputcontext.h" #include -static inline void setFrameless(QWidget *w) -{ - Qt::WindowFlags flags = w->windowFlags(); - flags |= Qt::FramelessWindowHint; - flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - w->setWindowFlags(flags); -} +#include + +using namespace QTestPrivate; class tst_QComboBox : public QObject { diff --git a/tests/auto/widgets/widgets/qlineedit/qlineedit.pro b/tests/auto/widgets/widgets/qlineedit/qlineedit.pro index 636208d67a..cb24a80afd 100644 --- a/tests/auto/widgets/widgets/qlineedit/qlineedit.pro +++ b/tests/auto/widgets/widgets/qlineedit/qlineedit.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qlineedit -QT += gui-private core-private widgets widgets-private testlib +QT += gui-private core-private widgets widgets-private testlib testlib-private SOURCES += tst_qlineedit.cpp osx: LIBS += -framework AppKit diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index cf1e19d598..2c6599631e 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -28,6 +28,7 @@ #include +#include #include "qlineedit.h" #include "qapplication.h" #include "qstringlist.h" @@ -74,16 +75,7 @@ QT_BEGIN_NAMESPACE class QPainter; QT_END_NAMESPACE -static inline void centerOnScreen(QWidget *w, const QSize &size) -{ - const QPoint offset = QPoint(size.width() / 2, size.height() / 2); - w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset); -} - -static inline void centerOnScreen(QWidget *w) -{ - centerOnScreen(w, w->geometry().size()); -} +using namespace QTestPrivate; class StyleOptionTestStyle : public QCommonStyle { diff --git a/tests/auto/widgets/widgets/qmenu/qmenu.pro b/tests/auto/widgets/widgets/qmenu/qmenu.pro index 55fff01138..84b6530184 100644 --- a/tests/auto/widgets/widgets/qmenu/qmenu.pro +++ b/tests/auto/widgets/widgets/qmenu/qmenu.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qmenu -QT += gui-private widgets testlib +QT += gui-private widgets testlib testlib-private SOURCES += tst_qmenu.cpp macx:{ OBJECTIVE_SOURCES += tst_qmenu_mac.mm diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index ad30db501a..99d29d487d 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -27,6 +27,7 @@ ****************************************************************************/ #include +#include #include #include #include @@ -48,15 +49,11 @@ #include +using namespace QTestPrivate; + Q_DECLARE_METATYPE(Qt::Key); Q_DECLARE_METATYPE(Qt::KeyboardModifiers); -static inline void centerOnScreen(QWidget *w, const QSize &size) -{ - const QPoint offset = QPoint(size.width() / 2, size.height() / 2); - w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset); -} - struct MenuMetrics { int fw; int hmargin; @@ -71,11 +68,6 @@ struct MenuMetrics { } }; -static inline void centerOnScreen(QWidget *w) -{ - centerOnScreen(w, w->geometry().size()); -} - class tst_QMenu : public QObject { Q_OBJECT diff --git a/tests/auto/widgets/widgets/qmenubar/qmenubar.pro b/tests/auto/widgets/widgets/qmenubar/qmenubar.pro index e680cf4d7d..bde0026517 100644 --- a/tests/auto/widgets/widgets/qmenubar/qmenubar.pro +++ b/tests/auto/widgets/widgets/qmenubar/qmenubar.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qmenubar -QT += widgets testlib +QT += widgets testlib testlib-private SOURCES += tst_qmenubar.cpp macos: { diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp index 65181a9516..417fa9befa 100644 --- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp @@ -48,6 +48,10 @@ QT_FORWARD_DECLARE_CLASS(QMainWindow) #include +#include + +using namespace QTestPrivate; + // Helper to calculate the action position in window coordinates static inline QPoint widgetToWindowPos(const QWidget *w, const QPoint &pos) { @@ -73,12 +77,6 @@ class Menu : public QMenu } }; -static inline void centerOnScreen(QWidget *w) -{ - const QPoint offset = QPoint(w->width() / 2, w->height() / 2); - w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset); -} - struct TestMenu { QList menus; diff --git a/tests/auto/widgets/widgets/qscrollbar/qscrollbar.pro b/tests/auto/widgets/widgets/qscrollbar/qscrollbar.pro index 2863dd2034..51f955200b 100644 --- a/tests/auto/widgets/widgets/qscrollbar/qscrollbar.pro +++ b/tests/auto/widgets/widgets/qscrollbar/qscrollbar.pro @@ -1,4 +1,4 @@ CONFIG += testcase TARGET = tst_qscrollbar -QT += widgets testlib +QT += widgets testlib testlib-private SOURCES += tst_qscrollbar.cpp diff --git a/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp b/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp index 5238eea592..f9a3e51977 100644 --- a/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp +++ b/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp @@ -33,16 +33,9 @@ #include #include -static inline void centerOnScreen(QWidget *w, const QSize &size) -{ - const QPoint offset = QPoint(size.width() / 2, size.height() / 2); - w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset); -} +#include -static inline void centerOnScreen(QWidget *w) -{ - centerOnScreen(w, w->geometry().size()); -} +using namespace QTestPrivate; class tst_QScrollBar : public QObject { -- cgit v1.2.3 From 435c4b2ccbbb7284918dd2d4a14f8e44c3977d98 Mon Sep 17 00:00:00 2001 From: Robert Szefner Date: Fri, 20 Oct 2017 22:51:07 +0200 Subject: QPSQL: Fix detection of PostreSQL version 9.x and later Fixed parsing version string for PostgreSQL. PostgreSQL versioning changed since version 10, see link: https://www.postgresql.org/support/versioning Extended QPSQLDriver::Protocol enum for PostreSQL 9.x and later, added underscore to item names to separate major and minor version. Changed long switch-case statements to if-else. Change-Id: Ib19ae7ba426f262e80c52670e7ecb3532ff460a0 Reviewed-by: Andy Shaw --- src/plugins/sqldrivers/psql/qsql_psql.cpp | 182 +++++++++++++++--------------- src/plugins/sqldrivers/psql/qsql_psql_p.h | 24 ++-- 2 files changed, 108 insertions(+), 98 deletions(-) diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp index acadc830b2..f650e4cca8 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql.cpp +++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp @@ -187,7 +187,7 @@ public: void QPSQLDriverPrivate::appendTables(QStringList &tl, QSqlQuery &t, QChar type) { QString query; - if (pro >= QPSQLDriver::Version73) { + if (pro >= QPSQLDriver::Version7_3) { query = QString::fromLatin1("select pg_class.relname, pg_namespace.nspname from pg_class " "left join pg_namespace on (pg_class.relnamespace = pg_namespace.oid) " "where (pg_class.relkind = '%1') and (pg_class.relname !~ '^Inv') " @@ -525,7 +525,7 @@ int QPSQLResult::numRowsAffected() QVariant QPSQLResult::lastInsertId() const { Q_D(const QPSQLResult); - if (d->drv_d_func()->pro >= QPSQLDriver::Version81) { + if (d->drv_d_func()->pro >= QPSQLDriver::Version8_1) { QSqlQuery qry(driver()->createResult()); // Most recent sequence value obtained from nextval if (qry.exec(QLatin1String("SELECT lastval();")) && qry.next()) @@ -697,7 +697,7 @@ void QPSQLDriverPrivate::detectBackslashEscape() { // standard_conforming_strings option introduced in 8.2 // http://www.postgresql.org/docs/8.2/static/runtime-config-compatible.html - if (pro < QPSQLDriver::Version82) { + if (pro < QPSQLDriver::Version8_2) { hasBackslashEscape = true; } else { hasBackslashEscape = false; @@ -719,11 +719,11 @@ static QPSQLDriver::Protocol qMakePSQLVersion(int vMaj, int vMin) { switch (vMin) { case 1: - return QPSQLDriver::Version71; + return QPSQLDriver::Version7_1; case 3: - return QPSQLDriver::Version73; + return QPSQLDriver::Version7_3; case 4: - return QPSQLDriver::Version74; + return QPSQLDriver::Version7_4; default: return QPSQLDriver::Version7; } @@ -733,76 +733,109 @@ static QPSQLDriver::Protocol qMakePSQLVersion(int vMaj, int vMin) { switch (vMin) { case 1: - return QPSQLDriver::Version81; + return QPSQLDriver::Version8_1; case 2: - return QPSQLDriver::Version82; + return QPSQLDriver::Version8_2; case 3: - return QPSQLDriver::Version83; + return QPSQLDriver::Version8_3; case 4: - return QPSQLDriver::Version84; + return QPSQLDriver::Version8_4; default: return QPSQLDriver::Version8; } break; } case 9: - return QPSQLDriver::Version9; + { + switch (vMin) { + case 1: + return QPSQLDriver::Version9_1; + case 2: + return QPSQLDriver::Version9_2; + case 3: + return QPSQLDriver::Version9_3; + case 4: + return QPSQLDriver::Version9_4; + case 5: + return QPSQLDriver::Version9_5; + case 6: + return QPSQLDriver::Version9_6; + default: + return QPSQLDriver::Version9; + } break; + } + case 10: + return QPSQLDriver::Version10; default: + if (vMaj > 10) + return QPSQLDriver::UnknownLaterVersion; break; } return QPSQLDriver::VersionUnknown; } +static QPSQLDriver::Protocol qFindPSQLVersion(const QString &versionString) +{ + const QRegExp rx(QStringLiteral("(\\d+)(?:\\.(\\d+))?")); + if (rx.indexIn(versionString) != -1) { + // Beginning with PostgreSQL version 10, a major release is indicated by + // increasing the first part of the version, e.g. 10 to 11. + // Before version 10, a major release was indicated by increasing either + // the first or second part of the version number, e.g. 9.5 to 9.6. + int vMaj = rx.cap(1).toInt(); + int vMin; + if (vMaj >= 10) { + vMin = 0; + } else { + if (rx.cap(2).isEmpty()) + return QPSQLDriver::VersionUnknown; + vMin = rx.cap(2).toInt(); + } + return qMakePSQLVersion(vMaj, vMin); + } + + return QPSQLDriver::VersionUnknown; +} + QPSQLDriver::Protocol QPSQLDriverPrivate::getPSQLVersion() { QPSQLDriver::Protocol serverVersion = QPSQLDriver::Version6; PGresult* result = exec("select version()"); int status = PQresultStatus(result); if (status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK) { - QString val = QString::fromLatin1(PQgetvalue(result, 0, 0)); - - QRegExp rx(QLatin1String("(\\d+)\\.(\\d+)")); - rx.setMinimal(true); // enforce non-greedy RegExp + serverVersion = qFindPSQLVersion( + QString::fromLatin1(PQgetvalue(result, 0, 0))); + } + PQclear(result); - if (rx.indexIn(val) != -1) { - int vMaj = rx.cap(1).toInt(); - int vMin = rx.cap(2).toInt(); - serverVersion = qMakePSQLVersion(vMaj, vMin); + QPSQLDriver::Protocol clientVersion = #if defined(PG_MAJORVERSION) - if (rx.indexIn(QLatin1String(PG_MAJORVERSION)) != -1) + qFindPSQLVersion(QLatin1String(PG_MAJORVERSION)); #elif defined(PG_VERSION) - if (rx.indexIn(QLatin1String(PG_VERSION)) != -1) + qFindPSQLVersion(QLatin1String(PG_VERSION)); #else - if (0) + QPSQLDriver::VersionUnknown; #endif - { - vMaj = rx.cap(1).toInt(); - vMin = rx.cap(2).toInt(); - QPSQLDriver::Protocol clientVersion = qMakePSQLVersion(vMaj, vMin); - - if (serverVersion >= QPSQLDriver::Version9 && clientVersion < QPSQLDriver::Version9) { - //Client version before QPSQLDriver::Version9 only supports escape mode for bytea type, - //but bytea format is set to hex by default in PSQL 9 and above. So need to force the - //server use the old escape mode when connects to the new server with old client library. - PQclear(result); - result = exec("SET bytea_output=escape; "); - status = PQresultStatus(result); - } else if (serverVersion == QPSQLDriver::VersionUnknown) { - serverVersion = clientVersion; - if (serverVersion != QPSQLDriver::VersionUnknown) - qWarning("The server version of this PostgreSQL is unknown, falling back to the client version."); - } - } - } + + if (serverVersion >= QPSQLDriver::Version9 && clientVersion < QPSQLDriver::Version9) { + // Client version before QPSQLDriver::Version9 only supports escape mode for bytea type, + // but bytea format is set to hex by default in PSQL 9 and above. So need to force the + // server use the old escape mode when connects to the new server with old client library. + result = exec("SET bytea_output=escape; "); + status = PQresultStatus(result); + PQclear(result); + } else if (serverVersion == QPSQLDriver::VersionUnknown) { + serverVersion = clientVersion; + if (serverVersion != QPSQLDriver::VersionUnknown) + qWarning("The server version of this PostgreSQL is unknown, falling back to the client version."); } - PQclear(result); - //keep the old behavior unchanged + // Keep the old behavior unchanged if (serverVersion == QPSQLDriver::VersionUnknown) serverVersion = QPSQLDriver::Version6; - if (serverVersion < QPSQLDriver::Version71) { + if (serverVersion < QPSQLDriver::Version7_1) { qWarning("This version of PostgreSQL is not supported and may not work."); } @@ -852,7 +885,7 @@ bool QPSQLDriver::hasFeature(DriverFeature f) const return true; case PreparedQueries: case PositionalPlaceholders: - return d->pro >= QPSQLDriver::Version82; + return d->pro >= QPSQLDriver::Version8_2; case BatchOperations: case NamedPlaceholders: case SimpleLocking: @@ -861,7 +894,7 @@ bool QPSQLDriver::hasFeature(DriverFeature f) const case CancelQuery: return false; case BLOB: - return d->pro >= QPSQLDriver::Version71; + return d->pro >= QPSQLDriver::Version7_1; case Unicode: return d->isUtf8; } @@ -988,12 +1021,7 @@ bool QPSQLDriver::commitTransaction() // This hack is used to tell if the transaction has succeeded for the protocol versions of // PostgreSQL below. For 7.x and other protocol versions we are left in the dark. // This hack can dissapear once there is an API to query this sort of information. - if (d->pro == QPSQLDriver::Version8 || - d->pro == QPSQLDriver::Version81 || - d->pro == QPSQLDriver::Version82 || - d->pro == QPSQLDriver::Version83 || - d->pro == QPSQLDriver::Version84 || - d->pro == QPSQLDriver::Version9) { + if (d->pro >= QPSQLDriver::Version8) { transaction_failed = qstrcmp(PQcmdStatus(res), "ROLLBACK") == 0; } @@ -1080,8 +1108,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const else schema = std::move(schema).toLower(); - switch(d->pro) { - case QPSQLDriver::Version6: + if (d->pro == QPSQLDriver::Version6) { stmt = QLatin1String("select pg_att1.attname, int(pg_att1.atttypid), pg_cl.relname " "from pg_attribute pg_att1, pg_attribute pg_att2, pg_class pg_cl, pg_index pg_ind " "where pg_cl.relname = '%1_pkey' " @@ -1090,9 +1117,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const "and pg_att1.attrelid = pg_ind.indrelid " "and pg_att1.attnum = pg_ind.indkey[pg_att2.attnum-1] " "order by pg_att2.attnum"); - break; - case QPSQLDriver::Version7: - case QPSQLDriver::Version71: + } else if (d->pro == QPSQLDriver::Version7 || d->pro == QPSQLDriver::Version7_1) { stmt = QLatin1String("select pg_att1.attname, pg_att1.atttypid::int, pg_cl.relname " "from pg_attribute pg_att1, pg_attribute pg_att2, pg_class pg_cl, pg_index pg_ind " "where pg_cl.relname = '%1_pkey' " @@ -1101,15 +1126,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const "and pg_att1.attrelid = pg_ind.indrelid " "and pg_att1.attnum = pg_ind.indkey[pg_att2.attnum-1] " "order by pg_att2.attnum"); - break; - case QPSQLDriver::Version73: - case QPSQLDriver::Version74: - case QPSQLDriver::Version8: - case QPSQLDriver::Version81: - case QPSQLDriver::Version82: - case QPSQLDriver::Version83: - case QPSQLDriver::Version84: - case QPSQLDriver::Version9: + } else if (d->pro >= QPSQLDriver::Version7_3) { stmt = QLatin1String("SELECT pg_attribute.attname, pg_attribute.atttypid::int, " "pg_class.relname " "FROM pg_attribute, pg_class " @@ -1124,10 +1141,8 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const else stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from " "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema)); - break; - case QPSQLDriver::VersionUnknown: - qFatal("PSQL version is unknown"); - break; + } else { + qFatal("QPSQLDriver::primaryIndex(tablename): unknown PSQL version, query statement not set"); } i.exec(stmt.arg(tbl)); @@ -1161,8 +1176,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const schema = std::move(schema).toLower(); QString stmt; - switch(d->pro) { - case QPSQLDriver::Version6: + if (d->pro == QPSQLDriver::Version6) { stmt = QLatin1String("select pg_attribute.attname, int(pg_attribute.atttypid), " "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, " "int(pg_attribute.attrelid), pg_attribute.attnum " @@ -1170,8 +1184,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const "where pg_class.relname = '%1' " "and pg_attribute.attnum > 0 " "and pg_attribute.attrelid = pg_class.oid "); - break; - case QPSQLDriver::Version7: + } else if (d->pro == QPSQLDriver::Version7) { stmt = QLatin1String("select pg_attribute.attname, pg_attribute.atttypid::int, " "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, " "pg_attribute.attrelid::int, pg_attribute.attnum " @@ -1179,8 +1192,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const "where pg_class.relname = '%1' " "and pg_attribute.attnum > 0 " "and pg_attribute.attrelid = pg_class.oid "); - break; - case QPSQLDriver::Version71: + } else if (d->pro == QPSQLDriver::Version7_1) { stmt = QLatin1String("select pg_attribute.attname, pg_attribute.atttypid::int, " "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, " "pg_attrdef.adsrc " @@ -1191,15 +1203,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const "and pg_attribute.attnum > 0 " "and pg_attribute.attrelid = pg_class.oid " "order by pg_attribute.attnum "); - break; - case QPSQLDriver::Version73: - case QPSQLDriver::Version74: - case QPSQLDriver::Version8: - case QPSQLDriver::Version81: - case QPSQLDriver::Version82: - case QPSQLDriver::Version83: - case QPSQLDriver::Version84: - case QPSQLDriver::Version9: + } else if (d->pro >= QPSQLDriver::Version7_3) { stmt = QLatin1String("select pg_attribute.attname, pg_attribute.atttypid::int, " "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, " "pg_attrdef.adsrc " @@ -1217,15 +1221,13 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const else stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from " "pg_namespace where pg_namespace.nspname = '%1')").arg(schema)); - break; - case QPSQLDriver::VersionUnknown: - qFatal("PSQL version is unknown"); - break; + } else { + qFatal("QPSQLDriver::record(tablename): unknown PSQL version, query statement not set"); } QSqlQuery query(createResult()); query.exec(stmt.arg(tbl)); - if (d->pro >= QPSQLDriver::Version71) { + if (d->pro >= QPSQLDriver::Version7_1) { while (query.next()) { int len = query.value(3).toInt(); int precision = query.value(4).toInt(); diff --git a/src/plugins/sqldrivers/psql/qsql_psql_p.h b/src/plugins/sqldrivers/psql/qsql_psql_p.h index 8468b9af93..f5cb2e9bd0 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql_p.h +++ b/src/plugins/sqldrivers/psql/qsql_psql_p.h @@ -76,15 +76,23 @@ public: VersionUnknown = -1, Version6 = 6, Version7 = 7, - Version71 = 8, - Version73 = 9, - Version74 = 10, + Version7_1 = 8, + Version7_3 = 9, + Version7_4 = 10, Version8 = 11, - Version81 = 12, - Version82 = 13, - Version83 = 14, - Version84 = 15, - Version9 = 16 + Version8_1 = 12, + Version8_2 = 13, + Version8_3 = 14, + Version8_4 = 15, + Version9 = 16, + Version9_1 = 17, + Version9_2 = 18, + Version9_3 = 19, + Version9_4 = 20, + Version9_5 = 21, + Version9_6 = 22, + Version10 = 23, + UnknownLaterVersion = 100000 }; explicit QPSQLDriver(QObject *parent=0); -- cgit v1.2.3 From ff914ea59c3788b2359ddb8d607299576b7a1296 Mon Sep 17 00:00:00 2001 From: Robert Szefner Date: Fri, 20 Oct 2017 23:31:12 +0200 Subject: QPSQL: Fix handling binary data for PostgreSQL 9.x and later Set byte_output to 'escape' mode for server version 9 and later, no matter what version of client library we use. Since setting byte_output doesn't depend on client version anymore, we can move it to separate function. This fixes qtbase\tests\auto\sql\kernel\qsqldatabase tst_QSqlDatabase::psql_escapeBytea() test (before this change test did not pass on PostgreSQL 9.6) Change-Id: I37aaa18267d7e6459c00010ed899536c01e8124e Reviewed-by: Andy Shaw --- src/plugins/sqldrivers/psql/qsql_psql.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp index f650e4cca8..aac9a1fa13 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql.cpp +++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp @@ -181,6 +181,7 @@ public: QPSQLDriver::Protocol getPSQLVersion(); bool setEncodingUtf8(); void setDatestyle(); + void setByteaOutput(); void detectBackslashEscape(); }; @@ -693,6 +694,20 @@ void QPSQLDriverPrivate::setDatestyle() PQclear(result); } +void QPSQLDriverPrivate::setByteaOutput() +{ + if (pro >= QPSQLDriver::Version9) { + // Server version before QPSQLDriver::Version9 only supports escape mode for bytea type, + // but bytea format is set to hex by default in PSQL 9 and above. So need to force the + // server to use the old escape mode when connects to the new server. + PGresult *result = exec("SET bytea_output TO escape"); + int status = PQresultStatus(result); + if (status != PGRES_COMMAND_OK) + qWarning("%s", PQerrorMessage(connection)); + PQclear(result); + } +} + void QPSQLDriverPrivate::detectBackslashEscape() { // standard_conforming_strings option introduced in 8.2 @@ -818,14 +833,7 @@ QPSQLDriver::Protocol QPSQLDriverPrivate::getPSQLVersion() QPSQLDriver::VersionUnknown; #endif - if (serverVersion >= QPSQLDriver::Version9 && clientVersion < QPSQLDriver::Version9) { - // Client version before QPSQLDriver::Version9 only supports escape mode for bytea type, - // but bytea format is set to hex by default in PSQL 9 and above. So need to force the - // server use the old escape mode when connects to the new server with old client library. - result = exec("SET bytea_output=escape; "); - status = PQresultStatus(result); - PQclear(result); - } else if (serverVersion == QPSQLDriver::VersionUnknown) { + if (serverVersion == QPSQLDriver::VersionUnknown) { serverVersion = clientVersion; if (serverVersion != QPSQLDriver::VersionUnknown) qWarning("The server version of this PostgreSQL is unknown, falling back to the client version."); @@ -957,6 +965,7 @@ bool QPSQLDriver::open(const QString & db, d->detectBackslashEscape(); d->isUtf8 = d->setEncodingUtf8(); d->setDatestyle(); + d->setByteaOutput(); setOpen(true); setOpenError(false); -- cgit v1.2.3 From b35a27676bec7f79761be83b2a7764ac0470e789 Mon Sep 17 00:00:00 2001 From: Robert Szefner Date: Fri, 20 Oct 2017 23:55:16 +0200 Subject: QPSQL: Fix check for minimum supported PostgreSQL version According to Qt documentation http://doc.qt.io/qt-5/sql-driver.html#qpsql minimum supported version of PostgreSQL is 7.3 Change-Id: I30cffaddc29fd56b534bfd259cc235ea1204a21f Reviewed-by: Andy Shaw --- src/plugins/sqldrivers/psql/qsql_psql.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp index aac9a1fa13..8f7d261bdc 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql.cpp +++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp @@ -843,7 +843,7 @@ QPSQLDriver::Protocol QPSQLDriverPrivate::getPSQLVersion() if (serverVersion == QPSQLDriver::VersionUnknown) serverVersion = QPSQLDriver::Version6; - if (serverVersion < QPSQLDriver::Version7_1) { + if (serverVersion < QPSQLDriver::Version7_3) { qWarning("This version of PostgreSQL is not supported and may not work."); } -- cgit v1.2.3 From 385589ef458715fcaa533bbd01ca421dc1040eba Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 20 Oct 2017 17:39:08 +0700 Subject: QCocoaMenu: Attach menu items when updating the menubar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of waiting for the menu delegate to update each item, we can attach an NSMenu to its NSMenuItem as soon as we update the current window's menubar. This is safe to do because we know that this is going to be the main menubar right after, so we're not orphaning any NSMenuItem from its NSMenu at the wrong moment. By doing this, we also ensure that all menus from the active menubar are reachable by the key-equivalent dispatching logic, even before we display the actual menu. This was shown in BigMenuCreator where, under the menubar's ASP and SAP menus, all A*S submenus would be disabled. Furthermore, on the same menus, SAP would show the same issue. Added test in Menurama as well. Change-Id: If6e7311072e6b53ad1cbced73623d1832aa0df8e Task-number: QTBUG-57076 Task-number: QTBUG-63712 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoamenu.h | 2 ++ src/plugins/platforms/cocoa/qcocoamenu.mm | 16 +++++++++++++++- src/plugins/platforms/cocoa/qcocoamenubar.h | 2 ++ src/plugins/platforms/cocoa/qcocoamenubar.mm | 11 ++++++++--- tests/manual/cocoa/menurama/mainwindow.cpp | 5 +++++ tests/manual/cocoa/menurama/mainwindow.ui | 1 + 6 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index 06688dbf3d..7baaf971f4 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -98,6 +98,8 @@ public: void timerEvent(QTimerEvent *e) Q_DECL_OVERRIDE; + void syncMenuItem_helper(QPlatformMenuItem *menuItem, bool menubarUpdate); + private: QCocoaMenuItem *itemOrNull(int index) const; void insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem); diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 3a11023a4d..8bdd0512de 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -434,6 +434,11 @@ void QCocoaMenu::timerEvent(QTimerEvent *e) } void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem) +{ + syncMenuItem_helper(menuItem, false /*menubarUpdate*/); +} + +void QCocoaMenu::syncMenuItem_helper(QPlatformMenuItem *menuItem, bool menubarUpdate) { QMacAutoReleasePool pool; QCocoaMenuItem *cocoaItem = static_cast(menuItem); @@ -444,8 +449,9 @@ void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem) const bool wasMerged = cocoaItem->isMerged(); NSMenuItem *oldItem = cocoaItem->nsItem(); + NSMenuItem *syncedItem = cocoaItem->sync(); - if (cocoaItem->sync() != oldItem) { + if (syncedItem != oldItem) { // native item was changed for some reason if (oldItem) { if (wasMerged) { @@ -463,6 +469,14 @@ void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem) // when an item's enabled state changes after menuWillOpen: scheduleUpdate(); } + + // This may be a good moment to attach this item's eventual submenu to the + // synced item, but only on the condition we're all currently hooked to the + // menunbar. A good indicator of this being the right moment is knowing that + // we got called from QCocoaMenuBar::updateMenuBarImmediately(). + if (menubarUpdate) + if (QCocoaMenu *submenu = cocoaItem->menu()) + submenu->setAttachedItem(syncedItem); } void QCocoaMenu::syncSeparatorsCollapsible(bool enable) diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h index 0725e9db68..a4ee531e91 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.h +++ b/src/plugins/platforms/cocoa/qcocoamenubar.h @@ -72,6 +72,8 @@ public: QList merged() const; NSMenuItem *itemForRole(QPlatformMenuItem::MenuRole r); + void syncMenu_helper(QPlatformMenu *menu, bool menubarUpdate); + private: static QCocoaWindow *findWindowForMenubar(); static QCocoaMenuBar *findGlobalMenubar(); diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index 3e466c9587..a4cd465dae 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -155,7 +155,7 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor } } - syncMenu(menu); + syncMenu_helper(menu, false /*internaCall*/); if (needsImmediateUpdate()) updateMenuBarImmediately(); @@ -182,12 +182,17 @@ void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu) } void QCocoaMenuBar::syncMenu(QPlatformMenu *menu) +{ + syncMenu_helper(menu, false /*internaCall*/); +} + +void QCocoaMenuBar::syncMenu_helper(QPlatformMenu *menu, bool menubarUpdate) { QMacAutoReleasePool pool; QCocoaMenu *cocoaMenu = static_cast(menu); Q_FOREACH (QCocoaMenuItem *item, cocoaMenu->items()) - cocoaMenu->syncMenuItem(item); + cocoaMenu->syncMenuItem_helper(item, menubarUpdate); BOOL shouldHide = YES; if (cocoaMenu->isVisible()) { @@ -357,7 +362,7 @@ void QCocoaMenuBar::updateMenuBarImmediately() menu->setAttachedItem(item); menu->setMenuParent(mb); // force a sync? - mb->syncMenu(menu); + mb->syncMenu_helper(menu, true /*menubarUpdate*/); menu->propagateEnabledState(!disableForModal); } diff --git a/tests/manual/cocoa/menurama/mainwindow.cpp b/tests/manual/cocoa/menurama/mainwindow.cpp index 06867bd7c9..086fc1e2fa 100644 --- a/tests/manual/cocoa/menurama/mainwindow.cpp +++ b/tests/manual/cocoa/menurama/mainwindow.cpp @@ -37,6 +37,11 @@ MainWindow::MainWindow(QWidget *parent) : { ui->setupUi(this); + auto *a = ui->menuStuff->addAction("Enabled Submenu (QTBUG-63172)"); + auto *qtbug63172_Menu = new QMenu; + qtbug63172_Menu->addAction("We're Good!"); + a->setMenu(qtbug63172_Menu); + startTimer(1000); connect(ui->menuAfter_aboutToShow, &QMenu::aboutToShow, [=] { diff --git a/tests/manual/cocoa/menurama/mainwindow.ui b/tests/manual/cocoa/menurama/mainwindow.ui index 18cded70d2..4fb3e3420e 100644 --- a/tests/manual/cocoa/menurama/mainwindow.ui +++ b/tests/manual/cocoa/menurama/mainwindow.ui @@ -131,6 +131,7 @@ Click on "Dynamic Stuff" then move left and right to other menus. Disa + -- cgit v1.2.3 From d2b8a01ab0670337bd29f6f9b76069cc2599cc75 Mon Sep 17 00:00:00 2001 From: Jesus Fernandez Date: Wed, 1 Nov 2017 22:21:35 +0100 Subject: Fix indentation Tabs and white spaces were mixed. Change-Id: I498944334b68b5c23a61e6f4ba6a0e8df77799c6 Reviewed-by: Timur Pocheptsov --- src/network/kernel/kernel.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index 00c115da84..1b62892c9f 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -6,7 +6,7 @@ INCLUDEPATH += $$PWD HEADERS += kernel/qtnetworkglobal.h \ kernel/qtnetworkglobal_p.h \ kernel/qauthenticator.h \ - kernel/qauthenticator_p.h \ + kernel/qauthenticator_p.h \ kernel/qdnslookup.h \ kernel/qdnslookup_p.h \ kernel/qhostaddress.h \ -- cgit v1.2.3 From e45ffd7bf6b05062590da039e0de64707d2fb536 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Thu, 26 Oct 2017 13:26:56 +0200 Subject: Xinput: Avoid misdetecting certain trackballs as tablets The algorithm triggers on the word "cursor" in the device name, which would also happen for devices from the manufacturer Cursor Controls. Task-number: QTBUG-48034 Change-Id: I9645c0d0bc1fa951d0ea00480572fd0df0220eb5 Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 6f20ec25e3..26a9ba8d26 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -220,7 +220,7 @@ void QXcbConnection::xi2SetupDevices() isTablet = true; tabletData.pointerType = QTabletEvent::Eraser; dbgType = QLatin1String("eraser"); - } else if (name.contains("cursor")) { + } else if (name.contains("cursor") && !(name.contains("cursor controls") && name.contains("trackball"))) { isTablet = true; tabletData.pointerType = QTabletEvent::Cursor; dbgType = QLatin1String("cursor"); -- cgit v1.2.3 From b5b1e1036ff59b584719b8af7b3be8223a662233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= Date: Sun, 5 Nov 2017 14:08:56 +0200 Subject: Extend blacklisting in qnetworkreply While removing insignificant flag in commit 38a0909d4ed39b49e0463bd780d20a82ea672d35 and blacklisting autotests that still failed, qtbase builds didn't verify VS2017. That broke qt5 builds which do build VS2017. Task-number: QTBUG-64264 Change-Id: I5fdfa5dac6192f449a05146a9a422e428a710c84 Reviewed-by: Liang Qi --- tests/auto/network/access/qnetworkreply/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index 091ec28bea..4785c5b650 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -32,3 +32,5 @@ linux windows [qtbug28035browserDoesNotLoadQtProjectOrgCorrectly] windows +[getFromUnreachableIp] +windows msvc-2017 -- cgit v1.2.3 From 3e5dde4766780665c1030003e3af3aefb75c5dbf Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Fri, 3 Nov 2017 18:20:45 +0100 Subject: Testlib: Fix developer-build with clang 4 "implicit conversion increases floating-point precision: 'float' to 'double'" Change-Id: Id6f4315316e63c849f1a5ddb6c77abc2bab0b2a9 Reviewed-by: Friedemann Kleint --- src/testlib/qtest_gui.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/testlib/qtest_gui.h b/src/testlib/qtest_gui.h index 2b486aae5d..d4b2de2214 100644 --- a/src/testlib/qtest_gui.h +++ b/src/testlib/qtest_gui.h @@ -122,25 +122,25 @@ template<> inline char *toString(const QRegion ®ion) #ifndef QT_NO_VECTOR2D template<> inline char *toString(const QVector2D &v) { - QByteArray result = "QVector2D(" + QByteArray::number(v.x()) + ", " - + QByteArray::number(v.y()) + ')'; + QByteArray result = "QVector2D(" + QByteArray::number(double(v.x())) + ", " + + QByteArray::number(double(v.y())) + ')'; return qstrdup(result.constData()); } #endif // !QT_NO_VECTOR2D #ifndef QT_NO_VECTOR3D template<> inline char *toString(const QVector3D &v) { - QByteArray result = "QVector3D(" + QByteArray::number(v.x()) + ", " - + QByteArray::number(v.y()) + ", " + QByteArray::number(v.z()) + ')'; + QByteArray result = "QVector3D(" + QByteArray::number(double(v.x())) + ", " + + QByteArray::number(double(v.y())) + ", " + QByteArray::number(double(v.z())) + ')'; return qstrdup(result.constData()); } #endif // !QT_NO_VECTOR3D #ifndef QT_NO_VECTOR4D template<> inline char *toString(const QVector4D &v) { - QByteArray result = "QVector4D(" + QByteArray::number(v.x()) + ", " - + QByteArray::number(v.y()) + ", " + QByteArray::number(v.z()) - + ", " + QByteArray::number(v.w()) + ')'; + QByteArray result = "QVector4D(" + QByteArray::number(double(v.x())) + ", " + + QByteArray::number(double(v.y())) + ", " + QByteArray::number(double(v.z())) + + ", " + QByteArray::number(double(v.w())) + ')'; return qstrdup(result.constData()); } #endif // !QT_NO_VECTOR4D -- cgit v1.2.3 From c8fa698e9928783ee7257134e72c3c5927fe5698 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 6 Nov 2017 13:45:23 +0100 Subject: tst_QNetworkReply: Blacklist ioHttpRedirectPolicy for Linux Task-number: QTBUG-62583 Change-Id: I9723a465f1d36aec823ce3459fd03b9492a3b778 Reviewed-by: Timur Pocheptsov --- tests/auto/network/access/qnetworkreply/BLACKLIST | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index 4785c5b650..9ae424943d 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -25,7 +25,7 @@ windows [ioHttpRedirectMultipartPost] linux [ioHttpRedirectPolicy] -b2qt 64bit +b2qt linux 64bit [ioHttpRedirectPostPut] linux [putWithServerClosingConnectionImmediately] -- cgit v1.2.3 From 7df4dcff2cafcd9b57eb7a4812be871d956f0ec8 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 3 Nov 2017 14:40:46 +0100 Subject: Fix memory corruption on scaled emojis Bitmap glyphs are returned prescaled, which means we should include the transform in their bounding box. Additionally painting them should stick the smallest rect to avoid writing outside the allocated area, and assert in debug builds. Task-number: QTBUG-64239 Change-Id: I5f877d36566891323f528018f910798344ba4ce2 Reviewed-by: Konstantin Ritt Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/painting/qtextureglyphcache.cpp | 3 ++- .../fontdatabases/freetype/qfontengine_ft.cpp | 30 ++++++++++++++-------- .../fontdatabases/freetype/qfontengine_ft_p.h | 2 +- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 86a53c21a3..2a7e0eaa0c 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -318,11 +318,12 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subP return; } #endif + Q_ASSERT(mask.width() <= c.w && mask.height() <= c.h); if (m_format == QFontEngine::Format_A32 || m_format == QFontEngine::Format_ARGB) { QImage ref(m_image.bits() + (c.x * 4 + c.y * m_image.bytesPerLine()), - qMax(mask.width(), c.w), qMax(mask.height(), c.h), m_image.bytesPerLine(), + qMin(mask.width(), c.w), qMin(mask.height(), c.h), m_image.bytesPerLine(), m_image.format()); QPainter p(&ref); p.setCompositionMode(QPainter::CompositionMode_Source); diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp index 64a0ef6fe8..85bedff5e6 100644 --- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp +++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp @@ -1776,15 +1776,25 @@ QFixed QFontEngineFT::scaledBitmapMetrics(QFixed m) const return m * scalableBitmapScaleFactor; } -glyph_metrics_t QFontEngineFT::scaledBitmapMetrics(const glyph_metrics_t &m) const +glyph_metrics_t QFontEngineFT::scaledBitmapMetrics(const glyph_metrics_t &m, const QTransform &t) const { + QTransform trans(t); + const qreal scaleFactor = scalableBitmapScaleFactor.toReal(); + trans.scale(scaleFactor, scaleFactor); + + QRectF rect(m.x.toReal(), m.y.toReal(), m.width.toReal(), m.height.toReal()); + QPointF offset(m.xoff.toReal(), m.yoff.toReal()); + + rect = trans.mapRect(rect); + offset = trans.map(offset); + glyph_metrics_t metrics; - metrics.x = scaledBitmapMetrics(m.x); - metrics.y = scaledBitmapMetrics(m.y); - metrics.width = scaledBitmapMetrics(m.width); - metrics.height = scaledBitmapMetrics(m.height); - metrics.xoff = scaledBitmapMetrics(m.xoff); - metrics.yoff = scaledBitmapMetrics(m.yoff); + metrics.x = QFixed::fromReal(rect.x()); + metrics.y = QFixed::fromReal(rect.y()); + metrics.width = QFixed::fromReal(rect.width()); + metrics.height = QFixed::fromReal(rect.height()); + metrics.xoff = QFixed::fromReal(offset.x()); + metrics.yoff = QFixed::fromReal(offset.y()); return metrics; } @@ -1878,7 +1888,7 @@ glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs) unlockFace(); if (isScalableBitmap()) - overall = scaledBitmapMetrics(overall); + overall = scaledBitmapMetrics(overall, QTransform()); return overall; } @@ -1917,7 +1927,7 @@ glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph) unlockFace(); if (isScalableBitmap()) - overall = scaledBitmapMetrics(overall); + overall = scaledBitmapMetrics(overall, QTransform()); return overall; } @@ -1955,7 +1965,7 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe } if (isScalableBitmap()) - overall = scaledBitmapMetrics(overall); + overall = scaledBitmapMetrics(overall, matrix); return overall; } diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h b/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h index 2993e3b616..c063f5df30 100644 --- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h +++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h @@ -321,7 +321,7 @@ private: int loadFlags(QGlyphSet *set, GlyphFormat format, int flags, bool &hsubpixel, int &vfactor) const; bool shouldUseDesignMetrics(ShaperFlags flags) const; QFixed scaledBitmapMetrics(QFixed m) const; - glyph_metrics_t scaledBitmapMetrics(const glyph_metrics_t &m) const; + glyph_metrics_t scaledBitmapMetrics(const glyph_metrics_t &m, const QTransform &matrix) const; GlyphFormat defaultFormat; FT_Matrix matrix; -- cgit v1.2.3 From 5194817941985c766bbc7f80039a58e0cf504b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 6 Nov 2017 15:08:37 +0100 Subject: Cocoa: optimize backingstore flush on 10-bit displays MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qt draws the backing store to the window using CoreGrahics, which will trigger a slow RGB32 -> RGB64 conversion when the output display is a deep color display. Disable NSWindow dynamicDepthLimit and force the depthLimit to WindowDepthTwentyforBitRGB for the common case of 8-bit-per-component raster surfaces. This was benchmarked by resizing a simple QRasterWindow test case which fills the window area using QPainter::fillRect(). Before: 67.1% rgba64_image_mark_rgb32 10.8% __vImageCopyBuffer_block_invoke 6.0% madvise 5.0% _kernelrpc_mach_vm_deallocate_trap 4.1% qt_memfill32(unsigned int*, unsigned int, int) After: 30.7% __vImageCopyBuffer_block_invoke 20.3% madvise 12.3% __vOverwriteChannelsWithScalar_ARGB8888_block_invoke 12.2% qt_memfill32(unsigned int*, unsigned int, int) 4.6% _kernelrpc_mach_vm_deallocate_trap The test program now spends significantly more of its time allocating/deallocating the backing store (madvise), and running the Qt paint event (qt_memfill32). Task-number: QTBUG-47660 Change-Id: I878be7a0e6eee4ad798f7a53f7f9f79b7950af26 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoawindow.mm | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index c6fa6795c1..5cd4beb4f0 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1887,6 +1887,21 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBeChildNSWindow, bool sh applyContentBorderThickness(window); + // Prevent CoreGraphics RGB32 -> RGB64 backing store conversions on deep color + // displays by forcing 8-bit components, unless a deep color format has been + // requested. This conversion uses significant CPU time. + QSurface::SurfaceType surfaceType = QPlatformWindow::window()->surfaceType(); + bool usesCoreGraphics = surfaceType == QSurface::RasterSurface || surfaceType == QSurface::RasterGLSurface; + QSurfaceFormat surfaceFormat = QPlatformWindow::window()->format(); + bool usesDeepColor = surfaceFormat.redBufferSize() > 8 || + surfaceFormat.greenBufferSize() > 8 || + surfaceFormat.blueBufferSize() > 8; + bool usesLayer = view().layer; + if (usesCoreGraphics && !usesDeepColor && !usesLayer) { + [window setDynamicDepthLimit:NO]; + [window setDepthLimit:NSWindowDepthTwentyfourBitRGB]; + } + return window; } -- cgit v1.2.3 From eb5994df1307b2e17e729374e1f7ab1c8fe82750 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 3 Nov 2017 13:40:17 +0100 Subject: tst_QWidget::multipleToplevelFocusCheck(): Avoid overlapping The test showed flakyness on Linux. It has been observed that its windows overlap. Position the windows beside each other. Change-Id: I4ff1b9cafaf753a6844b3dfabb576a07f74b396a Reviewed-by: Gatis Paeglis --- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index a7aa99d2a8..c1bff5b00a 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -5176,19 +5176,22 @@ void tst_QWidget::multipleToplevelFocusCheck() TopLevelFocusCheck w1; TopLevelFocusCheck w2; + const QString title = QLatin1String(QTest::currentTestFunction()); + w1.setWindowTitle(title + QLatin1String("_W1")); + w1.move(m_availableTopLeft + QPoint(20, 20)); w1.resize(200, 200); w1.show(); QVERIFY(QTest::qWaitForWindowExposed(&w1)); + w2.setWindowTitle(title + QLatin1String("_W2")); + w2.move(w1.frameGeometry().topRight() + QPoint(20, 0)); w2.resize(200,200); w2.show(); QVERIFY(QTest::qWaitForWindowExposed(&w2)); - QTest::qWait(50); QApplication::setActiveWindow(&w1); w1.activateWindow(); QVERIFY(QTest::qWaitForWindowActive(&w1)); QCOMPARE(QApplication::activeWindow(), static_cast(&w1)); - QTest::qWait(50); QTest::mouseDClick(&w1, Qt::LeftButton); QTRY_COMPARE(QApplication::focusWidget(), static_cast(w1.edit)); -- cgit v1.2.3 From 0445065645daab1dd9c328e52313646dcfcc80c2 Mon Sep 17 00:00:00 2001 From: Robert Szefner Date: Sun, 5 Nov 2017 12:56:50 +0100 Subject: Run oraArrayBind() test only for Oracle DBMS This test contains Oracle specific queries and will fail for other DBMS. Currently it doesn't fail, because it is skipped for drivers that doesn't support BatchOperations and only QOCI supports batch operations. Change-Id: I8f1e7c7244726fa11c841023dec186553747a6b5 Reviewed-by: Friedemann Kleint Reviewed-by: Andy Shaw --- tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index 35f86772e2..dc304513e2 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -146,7 +146,7 @@ private slots: void batchExec(); void QTBUG_43874_data() { generic_data(); } void QTBUG_43874(); - void oraArrayBind_data() { generic_data(); } + void oraArrayBind_data() { generic_data("QOCI"); } void oraArrayBind(); void lastInsertId_data() { generic_data(); } void lastInsertId(); -- cgit v1.2.3 From b4f4c384d9ee7cf93cc3db289a7d4275ac10a618 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 28 Oct 2017 13:20:53 +0200 Subject: QHeaderView: Honor maximumSectionSize property during resizeSections() Resizing a QTreeeView section with double click or resizeColumnToContents() does not respect the maximumSectionSize when the resize mode is Interactive or Fixed. Since the documentation of maximumSectionSize states that it should honor this property for those cases either the documentation or implementation is incorrect. This patch fixes the latter. Task-number: QTBUG-64036 Change-Id: Ic14c8e444d50b9c50a117efed19d0bca7ec1cf82 Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qheaderview.cpp | 2 +- tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 213cc96b03..3af191b06c 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -3364,7 +3364,7 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool // because it isn't stretch, determine its width and remove that from lengthToStretch int sectionSize = 0; if (resizeMode == QHeaderView::Interactive || resizeMode == QHeaderView::Fixed) { - sectionSize = headerSectionSize(i); + sectionSize = qBound(q->minimumSectionSize(), headerSectionSize(i), q->maximumSectionSize()); } else { // resizeMode == QHeaderView::ResizeToContents int logicalIndex = q->logicalIndex(i); sectionSize = qMax(viewSectionSizeHint(logicalIndex), diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index b13e7b2f33..fa543ae2c3 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -3006,6 +3006,7 @@ void tst_QHeaderView::stretchAndRestoreLastSection() tv.setModel(&m); tv.showMaximized(); + const int minimumSectionSize = 20; const int defaultSectionSize = 30; const int someOtherSectionSize = 40; const int biggerSizeThanAnySection = 50; @@ -3013,6 +3014,9 @@ void tst_QHeaderView::stretchAndRestoreLastSection() QVERIFY(QTest::qWaitForWindowExposed(&tv)); QHeaderView &header = *tv.horizontalHeader(); + // set minimum size before resizeSections() is called + // which is done inside setStretchLastSection + header.setMinimumSectionSize(minimumSectionSize); header.setDefaultSectionSize(defaultSectionSize); header.resizeSection(9, someOtherSectionSize); header.setStretchLastSection(true); -- cgit v1.2.3 From 2937ab9e320ea04fdfda8e3a252559d4762e811e Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Tue, 31 Oct 2017 19:47:12 +0100 Subject: QHeaderView: Skip hidden sections on cascading resize When a section is hidden, QHeaderViewPrivate::cascadingResize() does resize a section even it is hidden. This leads to space between the neighbor sections and also some unneeded calculations. Task-number: QTBUG-54601 Change-Id: Ie139417ae2c77ef25e66cf628bfe400185f88ee8 Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qheaderview.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 3af191b06c..298270a785 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -3539,6 +3539,8 @@ void QHeaderViewPrivate::cascadingResize(int visual, int newSize) // cascade the section size change for (int i = visual + 1; i < sectionCount(); ++i) { + if (isVisualIndexHidden(i)) + continue; if (!sectionIsCascadable(i)) continue; int currentSectionSize = headerSectionSize(i); @@ -3581,6 +3583,8 @@ void QHeaderViewPrivate::cascadingResize(int visual, int newSize) // cascade the section size change if (delta < 0 && newSize < minimumSize) { for (int i = visual - 1; i >= 0; --i) { + if (isVisualIndexHidden(i)) + continue; if (!sectionIsCascadable(i)) continue; int sectionSize = headerSectionSize(i); @@ -3595,6 +3599,8 @@ void QHeaderViewPrivate::cascadingResize(int visual, int newSize) // let the next section get the space from the resized section if (!sectionResized) { for (int i = visual + 1; i < sectionCount(); ++i) { + if (isVisualIndexHidden(i)) + continue; if (!sectionIsCascadable(i)) continue; int currentSectionSize = headerSectionSize(i); -- cgit v1.2.3 From 28937559b1e03f959cd012c6b42ca988311893f5 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 3 Nov 2017 12:02:12 +0100 Subject: tst_qxmlsimplereader::inputFromSocket - fix race condition(s) This test was failing recently on Windows 7, mingw, x86. It's not failing now and attempts to reproduce the failure on CI's VM were unsuccessful. Anyway, just reading the code is enough to spot race-conditions: two threads are accessing two shared boolean variables without any protection. It's unclear if these races were the reason why the test was failing, but we fix them for good anyway. Also, a failure to start a thread or to start listening on a TCP socket is not treated as XML-related failure anymore and QSKIPped instead. Change-Id: I5115ce6c33cafc91485f8cf6e7e268d954976556 Reviewed-by: Timur Pocheptsov --- .../sax/qxmlsimplereader/tst_qxmlsimplereader.cpp | 32 ++++++++++++++++------ 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp b/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp index f77fd2ebab..8c4c6c7179 100644 --- a/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp +++ b/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include #include #include @@ -47,10 +49,11 @@ class XmlServer : public QThread { Q_OBJECT public: - XmlServer(QObject *parent = 0) : QThread(parent), quit_soon(false), listening(false) {} + XmlServer(QObject *parent = 0) : QThread(parent) {} - bool quit_soon; - bool listening; + QSemaphore threadStarted; + bool listening = false; + QAtomicInt quitSoon; protected: virtual void run(); @@ -63,6 +66,8 @@ void XmlServer::run() QTcpServer srv; listening = srv.listen(QHostAddress::Any, TEST_PORT); + threadStarted.release(); + if (!listening) { qWarning() << "Failed to listen on" << TEST_PORT << srv.errorString(); return; @@ -95,14 +100,13 @@ void XmlServer::run() QByteArray data = file.readAll(); for (int i = 0; i < data.size();) { -// sock->putChar(data.at(i)); int cnt = qMin(CHUNK_SIZE, data.size() - i); sock->write(data.constData() + i, cnt); i += cnt; sock->flush(); QTest::qSleep(1); - if (quit_soon) { + if (quitSoon.loadAcquire()) { sock->abort(); break; } @@ -112,7 +116,7 @@ void XmlServer::run() delete sock; } - if (quit_soon) + if (quitSoon.loadAcquire()) break; } @@ -162,7 +166,7 @@ tst_QXmlSimpleReader::tst_QXmlSimpleReader() : server(new XmlServer(this)) tst_QXmlSimpleReader::~tst_QXmlSimpleReader() { - server->quit_soon = true; + server->quitSoon.storeRelease(1); server->wait(); } @@ -562,7 +566,19 @@ void tst_QXmlSimpleReader::inputFromSocket() QSKIP("WinRT does not support connecting to localhost"); #endif - QTRY_VERIFY_WITH_TIMEOUT(server->listening, 15000); + if (!server->threadStarted.tryAcquire(1, 15000)) { + // If something is wrong with QThreads, it's not a reason to fail + // XML-test, we are not testing QThread here after all! + QSKIP("XmlServer/thread has not started yet"); + } + + // Subsequent runs should be able to acquire the semaphore. + server->threadStarted.release(1); + + if (!server->listening) { + // Again, QTcpServer is not the subject of this test! + QSKIP("QTcpServer::listen failed, bailing out"); + } QTcpSocket sock; sock.connectToHost(QHostAddress::LocalHost, TEST_PORT); -- cgit v1.2.3 From 28c1e17aef520abfa051c7d9a9fe0f45ec6a5db8 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 6 Nov 2017 14:31:29 +0100 Subject: QWinEventNotifier: Fix exit crash Make sure the wait handle is unregistered even though there is no event dispatcher in QWinEventNotifier::setEnabled(). Task-number: QTBUG-64152 Task-number: QTCREATORBUG-19175 Change-Id: I608b95adc7cb874bc52dc5bf0e9f51b443b54ebc Reviewed-by: Orgad Shaneh Reviewed-by: Joerg Bornemann --- src/corelib/kernel/qwineventnotifier.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp index 362111a2c8..24de491326 100644 --- a/src/corelib/kernel/qwineventnotifier.cpp +++ b/src/corelib/kernel/qwineventnotifier.cpp @@ -199,8 +199,11 @@ void QWinEventNotifier::setEnabled(bool enable) d->enabled = enable; QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher.load(); - if (!eventDispatcher) // perhaps application is shutting down + if (!eventDispatcher) { // perhaps application is shutting down + if (!enable && d->waitHandle != nullptr) + d->unregisterWaitObject(); return; + } if (Q_UNLIKELY(thread() != QThread::currentThread())) { qWarning("QWinEventNotifier: Event notifiers cannot be enabled or disabled from another thread"); return; -- cgit v1.2.3 From b084837ffc34439710552cb6ed31054c60f6b2d4 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Wed, 1 Nov 2017 15:19:45 +0100 Subject: Update bundled libpng to version 1.6.34 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes an upstream bug in the existing version 1.6.32 which would cause certain valid png files to be rejected. The remaining diff to clean 1.6.34 is archived in the qtpatches.diff file. [ChangeLog][Third-Party Code] libpng was updated to version 1.6.34 Task-number: QTBUG-63950 Change-Id: Ie6f2a09c78a93b6e5623848776b75650bb5bca66 Reviewed-by: André Klitzing Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/3rdparty/libpng/ANNOUNCE | 77 +++++---------------------------- src/3rdparty/libpng/CHANGES | 51 +++++++++++++++++++++- src/3rdparty/libpng/LICENSE | 4 +- src/3rdparty/libpng/README | 2 +- src/3rdparty/libpng/libpng-manual.txt | 21 ++++++--- src/3rdparty/libpng/png.c | 32 +++++++------- src/3rdparty/libpng/png.h | 28 ++++++------ src/3rdparty/libpng/pngconf.h | 2 +- src/3rdparty/libpng/pnglibconf.h | 4 +- src/3rdparty/libpng/pngread.c | 14 +++++- src/3rdparty/libpng/pngrtran.c | 22 +++++----- src/3rdparty/libpng/pngrutil.c | 47 +++++++++----------- src/3rdparty/libpng/pngtrans.c | 6 +-- src/3rdparty/libpng/pngwrite.c | 2 +- src/3rdparty/libpng/qt_attribution.json | 2 +- 15 files changed, 161 insertions(+), 153 deletions(-) diff --git a/src/3rdparty/libpng/ANNOUNCE b/src/3rdparty/libpng/ANNOUNCE index 3cbe5a926e..0f66c0d1da 100644 --- a/src/3rdparty/libpng/ANNOUNCE +++ b/src/3rdparty/libpng/ANNOUNCE @@ -1,4 +1,4 @@ -Libpng 1.6.32 - August 24, 2017 +Libpng 1.6.34 - September 29, 2017 This is a public release of libpng, intended for use in production codes. @@ -7,79 +7,24 @@ Files available for download: Source files with LF line endings (for Unix/Linux) and with a "configure" script - libpng-1.6.32.tar.xz (LZMA-compressed, recommended) - libpng-1.6.32.tar.gz + libpng-1.6.34.tar.xz (LZMA-compressed, recommended) + libpng-1.6.34.tar.gz Source files with CRLF line endings (for Windows), without the "configure" script - lpng1632.7z (LZMA-compressed, recommended) - lpng1632.zip + lpng1634.7z (LZMA-compressed, recommended) + lpng1634.zip Other information: - libpng-1.6.32-README.txt - libpng-1.6.32-LICENSE.txt - libpng-1.6.32-*.asc (armored detached GPG signatures) + libpng-1.6.34-README.txt + libpng-1.6.34-LICENSE.txt + libpng-1.6.34-*.asc (armored detached GPG signatures) -Changes since the last public release (1.6.31): - Avoid possible NULL dereference in png_handle_eXIf when benign_errors - are allowed. Avoid leaking the input buffer "eXIf_buf". - Eliminated png_ptr->num_exif member from pngstruct.h and added num_exif - to arguments for png_get_eXIf() and png_set_eXIf(). - Added calls to png_handle_eXIf(() in pngread.c and png_write_eXIf() in - pngwrite.c, and made various other fixes to png_write_eXIf(). - Changed name of png_get_eXIF and png_set_eXIf() to png_get_eXIf_1() and - png_set_eXIf_1(), respectively, to avoid breaking API compatibility - with libpng-1.6.31. - Updated contrib/libtests/pngunknown.c with eXIf chunk. - Initialized btoa[] in pngstest.c - Stop memory leak when returning from png_handle_eXIf() with an error - (Bug report from the OSS-fuzz project). - Replaced local eXIf_buf with info_ptr-eXIf_buf in png_handle_eXIf(). - Update libpng.3 and libpng-manual.txt about eXIf functions. - Restored png_get_eXIf() and png_set_eXIf() to maintain API compatability. - Removed png_get_eXIf_1() and png_set_eXIf_1(). - Check length of all chunks except IDAT against user limit to fix an - OSS-fuzz issue. - Check length of IDAT against maximum possible IDAT size, accounting - for height, rowbytes, interlacing and zlib/deflate overhead. - Restored png_get_eXIf_1() and png_set_eXIf_1(), because strlen(eXIf_buf) - does not work (the eXIf chunk data can contain zeroes). - Require cmake-2.8.8 in CMakeLists.txt. Revised symlink creation, - no longer using deprecated cmake LOCATION feature (Clifford Yapp). - Fixed five-byte error in the calculation of IDAT maximum possible size. - Moved chunk-length check into a png_check_chunk_length() private - function (Suggested by Max Stepin). - Moved bad pngs from tests to contrib/libtests/crashers - Moved testing of bad pngs into a separate tests/pngtest-badpngs script - Added the --xfail (expected FAIL) option to pngtest.c. It writes XFAIL - in the output but PASS for the libpng test. - Require cmake-3.0.2 in CMakeLists.txt (Clifford Yapp). - Fix "const" declaration info_ptr argument to png_get_eXIf_1() and the - num_exif argument to png_get_eXIf_1() (Github Issue 171). - Added "eXIf" to "chunks_to_ignore[]" in png_set_keep_unknown_chunks(). - Added huge_IDAT.png and empty_ancillary_chunks.png to testpngs/crashers. - Make pngtest --strict, --relax, --xfail options imply -m (multiple). - Removed unused chunk_name parameter from png_check_chunk_length(). - Relocated setting free_me for eXIf data, to stop an OSS-fuzz leak. - Initialize profile_header[] in png_handle_iCCP() to fix OSS-fuzz issue. - Initialize png_ptr->row_buf[0] to 255 in png_read_row() to fix OSS-fuzz UMR. - Attempt to fix a UMR in png_set_text_2() to fix OSS-fuzz issue. - Increase minimum zlib stream from 9 to 14 in png_handle_iCCP(), to account - for the minimum 'deflate' stream, and relocate the test to a point - after the keyword has been read. - Check that the eXIf chunk has at least 2 bytes and begins with "II" or "MM". - Added a set of "huge_xxxx_chunk.png" files to contrib/testpngs/crashers, - one for each known chunk type, with length = 2GB-1. - Check for 0 return from png_get_rowbytes() and added some (size_t) typecasts - in contrib/pngminus/*.c to stop some Coverity issues (162705, 162706, - and 162707). - Renamed chunks in contrib/testpngs/crashers to avoid having files whose - names differ only in case; this causes problems with some platforms - (github issue #172). - Added contrib/oss-fuzz directory which contains files used by the oss-fuzz - project (https://github.com/google/oss-fuzz/tree/master/projects/libpng). +Changes since the last public release (1.6.33): + Removed contrib/pngsuite/i*.png; some of these were incorrect and caused + test failures. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/src/3rdparty/libpng/CHANGES b/src/3rdparty/libpng/CHANGES index 14e60dd269..4b82118910 100644 --- a/src/3rdparty/libpng/CHANGES +++ b/src/3rdparty/libpng/CHANGES @@ -833,7 +833,7 @@ Version 1.0.7beta11 [May 7, 2000] Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes which are no longer used. Eliminated the three new members of png_text when PNG_LEGACY_SUPPORTED is - defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXT_SUPPORTED + defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXt_SUPPORTED is defined. Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory overrun when old applications fill the info_ptr->text structure directly. @@ -5939,7 +5939,7 @@ Version 1.6.32beta06 [August 2, 2017] Version 1.6.32beta07 [August 3, 2017] Check length of all chunks except IDAT against user limit to fix an - OSS-fuzz issue. + OSS-fuzz issue (Fixes CVE-2017-12652). Version 1.6.32beta08 [August 3, 2017] Check length of IDAT against maximum possible IDAT size, accounting @@ -5994,6 +5994,53 @@ Version 1.6.32rc02 [August 22, 2017] Version 1.6.32 [August 24, 2017] No changes. +Version 1.6.33beta01 [August 28, 2017] + Added PNGMINUS_UNUSED macro to contrib/pngminus/p*.c and added missing + parenthesis in contrib/pngminus/pnm2png.c (bug report by Christian Hesse). + Fixed off-by-one error in png_do_check_palette_indexes() (Bug report + by Mick P., Source Forge Issue #269). + +Version 1.6.33beta02 [September 3, 2017] + Initialize png_handler.row_ptr in contrib/oss-fuzz/libpng_read_fuzzer.cc + to fix shortlived oss-fuzz issue 3234. + Compute a larger limit on IDAT because some applications write a deflate + buffer for each row (Bug report by Andrew Church). + Use current date (DATE) instead of release-date (RDATE) in last + changed date of contrib/oss-fuzz files. + Enabled ARM support in CMakeLists.txt (Bernd Kuhls). + +Version 1.6.33beta03 [September 14, 2017] + Fixed incorrect typecast of some arguments to png_malloc() and + png_calloc() that were png_uint_32 instead of png_alloc_size_t + (Bug report by "irwir" in Github libpng issue #175). + Use pnglibconf.h.prebuilt when building for ANDROID with cmake (Github + issue 162, by rcdailey). + +Version 1.6.33rc01 [September 20, 2017] + Initialize memory allocated by png_inflate to zero, using memset, to + stop an oss-fuzz "use of uninitialized value" detection in png_set_text_2() + due to truncated iTXt or zTXt chunk. + Initialize memory allocated by png_read_buffer to zero, using memset, to + stop an oss-fuzz "use of uninitialized value" detection in + png_icc_check_tag_table() due to truncated iCCP chunk. + Removed a redundant test (suggested by "irwir" in Github issue #180). + +Version 1.6.33rc02 [September 23, 2017] + Added an interlaced version of each file in contrib/pngsuite. + Relocate new memset() call in pngrutil.c. + Removed more redundant tests (suggested by "irwir" in Github issue #180). + Add support for loading images with associated alpha in the Simplified + API (Samuel Williams). + +Version 1.6.33 [September 28, 2017] + Revert contrib/oss-fuzz/libpng_read_fuzzer.cc to libpng-1.6.32 state. + Initialize png_handler.row_ptr in contrib/oss-fuzz/libpng_read_fuzzer.cc + Add end_info structure and png_read_end() to the libpng fuzzer. + +Version 1.6.34 [September 29, 2017] + Removed contrib/pngsuite/i*.png; some of these were incorrect and caused + test failures. + Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement diff --git a/src/3rdparty/libpng/LICENSE b/src/3rdparty/libpng/LICENSE index e803911d37..4cda4fa0ad 100644 --- a/src/3rdparty/libpng/LICENSE +++ b/src/3rdparty/libpng/LICENSE @@ -10,7 +10,7 @@ this sentence. This code is released under the libpng license. -libpng versions 1.0.7, July 1, 2000 through 1.6.32, August 24, 2017 are +libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are derived from libpng-1.0.6, and are distributed according to the same disclaimer and license as libpng-1.0.6 with the following individuals @@ -130,4 +130,4 @@ any encryption software. See the EAR, paragraphs 734.3(b)(3) and Glenn Randers-Pehrson glennrp at users.sourceforge.net -April 1, 2017 +September 29, 2017 diff --git a/src/3rdparty/libpng/README b/src/3rdparty/libpng/README index 71292715eb..0da5a5ef83 100644 --- a/src/3rdparty/libpng/README +++ b/src/3rdparty/libpng/README @@ -1,4 +1,4 @@ -README for libpng version 1.6.32 - August 24, 2017 (shared library 16.0) +README for libpng version 1.6.34 - September 29, 2017 (shared library 16.0) See the note about version numbers near the top of png.h See INSTALL for instructions on how to install libpng. diff --git a/src/3rdparty/libpng/libpng-manual.txt b/src/3rdparty/libpng/libpng-manual.txt index e34b1436f5..d4407ef2ea 100644 --- a/src/3rdparty/libpng/libpng-manual.txt +++ b/src/3rdparty/libpng/libpng-manual.txt @@ -1,6 +1,6 @@ libpng-manual.txt - A description on how to use and modify libpng - libpng version 1.6.32 - August 24, 2017 + libpng version 1.6.34 - September 29, 2017 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2017 Glenn Randers-Pehrson @@ -11,7 +11,7 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng versions 0.97, January 1998, through 1.6.32 - August 24, 2017 + libpng versions 0.97, January 1998, through 1.6.34 - September 29, 2017 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2017 Glenn Randers-Pehrson @@ -986,8 +986,17 @@ premultiplication. png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); -This is the default libpng handling of the alpha channel - it is not -pre-multiplied into the color components. In addition the call states +Choices for the alpha_mode are + + PNG_ALPHA_PNG 0 /* according to the PNG standard */ + PNG_ALPHA_STANDARD 1 /* according to Porter/Duff */ + PNG_ALPHA_ASSOCIATED 1 /* as above; this is the normal practice */ + PNG_ALPHA_PREMULTIPLIED 1 /* as above */ + PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */ + PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */ + +PNG_ALPHA_PNG is the default libpng handling of the alpha channel. It is not +pre-multiplied into the color components. In addition the call states that the output is for a sRGB system and causes all PNG files without gAMA chunks to be assumed to be encoded using sRGB. @@ -1002,7 +1011,7 @@ early Mac systems behaved. This is the classic Jim Blinn approach and will work in academic environments where everything is done by the book. It has the shortcoming of assuming that input PNG data with no gamma information is linear - this -is unlikely to be correct unless the PNG files where generated locally. +is unlikely to be correct unless the PNG files were generated locally. Most of the time the output precision will be so low as to show significant banding in dark areas of the image. @@ -5405,7 +5414,7 @@ Since the PNG Development group is an ad-hoc body, we can't make an official declaration. This is your unofficial assurance that libpng from version 0.71 and -upward through 1.6.32 are Y2K compliant. It is my belief that earlier +upward through 1.6.34 are Y2K compliant. It is my belief that earlier versions were also Y2K compliant. Libpng only has two year fields. One is a 2-byte unsigned integer diff --git a/src/3rdparty/libpng/png.c b/src/3rdparty/libpng/png.c index 2352df13cb..ff02c56518 100644 --- a/src/3rdparty/libpng/png.c +++ b/src/3rdparty/libpng/png.c @@ -1,7 +1,7 @@ /* png.c - location for general purpose libpng functions * - * Last changed in libpng 1.6.32 [August 24, 2017] + * Last changed in libpng 1.6.33 [September 28, 2017] * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) @@ -14,7 +14,7 @@ #include "pngpriv.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_32 Your_png_h_is_not_version_1_6_32; +typedef png_libpng_version_1_6_34 Your_png_h_is_not_version_1_6_34; #ifdef __GNUC__ /* The version tests may need to be added to, but the problem warning has @@ -816,14 +816,14 @@ png_get_copyright(png_const_structrp png_ptr) #else # ifdef __STDC__ return PNG_STRING_NEWLINE \ - "libpng version 1.6.32 - August 24, 2017" PNG_STRING_NEWLINE \ + "libpng version 1.6.34 - September 29, 2017" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson" \ PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ PNG_STRING_NEWLINE; # else - return "libpng version 1.6.32 - August 24, 2017\ + return "libpng version 1.6.34 - September 29, 2017\ Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson\ Copyright (c) 1996-1997 Andreas Dilger\ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; @@ -1913,12 +1913,12 @@ png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, */ if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST) return png_icc_profile_error(png_ptr, colorspace, "sRGB", - (unsigned)intent, "invalid sRGB rendering intent"); + (png_alloc_size_t)intent, "invalid sRGB rendering intent"); if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 && colorspace->rendering_intent != intent) return png_icc_profile_error(png_ptr, colorspace, "sRGB", - (unsigned)intent, "inconsistent rendering intents"); + (png_alloc_size_t)intent, "inconsistent rendering intents"); if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0) { @@ -1979,7 +1979,6 @@ icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, if (profile_length < 132) return png_icc_profile_error(png_ptr, colorspace, name, profile_length, "too short"); - return 1; } @@ -2224,22 +2223,23 @@ png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace, * being in range. All defined tag types have an 8 byte header - a 4 byte * type signature then 0. */ + + /* This is a hard error; potentially it can cause read outside the + * profile. + */ + if (tag_start > profile_length || tag_length > profile_length - tag_start) + return png_icc_profile_error(png_ptr, colorspace, name, tag_id, + "ICC profile tag outside profile"); + if ((tag_start & 3) != 0) { - /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is + /* CNHP730S.icc shipped with Microsoft Windows 64 violates this; it is * only a warning here because libpng does not care about the * alignment. */ (void)png_icc_profile_error(png_ptr, NULL, name, tag_id, "ICC profile tag start not a multiple of 4"); } - - /* This is a hard error; potentially it can cause read outside the - * profile. - */ - if (tag_start > profile_length || tag_length > profile_length - tag_start) - return png_icc_profile_error(png_ptr, colorspace, name, tag_id, - "ICC profile tag outside profile"); } return 1; /* success, maybe with warnings */ @@ -3761,7 +3761,7 @@ png_log16bit(png_uint_32 x) * of getting this accuracy in practice. * * To deal with this the following exp() function works out the exponent of the - * frational part of the logarithm by using an accurate 32-bit value from the + * fractional part of the logarithm by using an accurate 32-bit value from the * top four fractional bits then multiplying in the remaining bits. */ static const png_uint_32 diff --git a/src/3rdparty/libpng/png.h b/src/3rdparty/libpng/png.h index 51ac8abe74..4c873f5c22 100644 --- a/src/3rdparty/libpng/png.h +++ b/src/3rdparty/libpng/png.h @@ -1,7 +1,7 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.32, August 24, 2017 + * libpng version 1.6.34, September 29, 2017 * * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -12,7 +12,7 @@ * Authors and maintainers: * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger - * libpng versions 0.97, January 1998, through 1.6.32, August 24, 2017: + * libpng versions 0.97, January 1998, through 1.6.34, September 29, 2017: * Glenn Randers-Pehrson. * See also "Contributing Authors", below. */ @@ -25,7 +25,7 @@ * * This code is released under the libpng license. * - * libpng versions 1.0.7, July 1, 2000 through 1.6.32, August 24, 2017 are + * libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are * Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are * derived from libpng-1.0.6, and are distributed according to the same * disclaimer and license as libpng-1.0.6 with the following individuals @@ -209,11 +209,11 @@ * ... * 1.0.19 10 10019 10.so.0.19[.0] * ... - * 1.2.57 13 10257 12.so.0.57[.0] + * 1.2.59 13 10257 12.so.0.59[.0] * ... - * 1.5.28 15 10527 15.so.15.28[.0] + * 1.5.30 15 10527 15.so.15.30[.0] * ... - * 1.6.32 16 10632 16.so.16.32[.0] + * 1.6.34 16 10633 16.so.16.34[.0] * * Henceforth the source version will match the shared-library major * and minor numbers; the shared-library major version number will be @@ -241,13 +241,13 @@ * Y2K compliance in libpng: * ========================= * - * August 24, 2017 + * September 29, 2017 * * Since the PNG Development group is an ad-hoc body, we can't make * an official declaration. * * This is your unofficial assurance that libpng from version 0.71 and - * upward through 1.6.32 are Y2K compliant. It is my belief that + * upward through 1.6.34 are Y2K compliant. It is my belief that * earlier versions were also Y2K compliant. * * Libpng only has two year fields. One is a 2-byte unsigned integer @@ -309,8 +309,8 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.32" -#define PNG_HEADER_VERSION_STRING " libpng version 1.6.32 - August 24, 2017\n" +#define PNG_LIBPNG_VER_STRING "1.6.34" +#define PNG_HEADER_VERSION_STRING " libpng version 1.6.34 - September 29, 2017\n" #define PNG_LIBPNG_VER_SONUM 16 #define PNG_LIBPNG_VER_DLLNUM 16 @@ -318,7 +318,7 @@ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MINOR 6 -#define PNG_LIBPNG_VER_RELEASE 32 +#define PNG_LIBPNG_VER_RELEASE 34 /* This should match the numeric part of the final component of * PNG_LIBPNG_VER_STRING, omitting any leading zero: @@ -349,7 +349,7 @@ * version 1.0.0 was mis-numbered 100 instead of 10000). From * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release */ -#define PNG_LIBPNG_VER 10632 /* 1.6.32 */ +#define PNG_LIBPNG_VER 10634 /* 1.6.34 */ /* Library configuration: these options cannot be changed after * the library has been built. @@ -459,7 +459,7 @@ extern "C" { /* This triggers a compiler error in png.c, if png.c and png.h * do not agree upon the version number. */ -typedef char* png_libpng_version_1_6_32; +typedef char* png_libpng_version_1_6_34; /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. * @@ -2819,6 +2819,8 @@ typedef struct # define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */ #endif +#define PNG_FORMAT_FLAG_ASSOCIATED_ALPHA 0x40U /* alpha channel is associated */ + /* Commonly used formats have predefined macros. * * First the single byte (sRGB) formats: diff --git a/src/3rdparty/libpng/pngconf.h b/src/3rdparty/libpng/pngconf.h index c0f15547be..d13b13e57a 100644 --- a/src/3rdparty/libpng/pngconf.h +++ b/src/3rdparty/libpng/pngconf.h @@ -1,7 +1,7 @@ /* pngconf.h - machine configurable file for libpng * - * libpng version 1.6.32, August 24, 2017 + * libpng version 1.6.34, September 29, 2017 * * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) diff --git a/src/3rdparty/libpng/pnglibconf.h b/src/3rdparty/libpng/pnglibconf.h index 9e45f73129..53b5e442c4 100644 --- a/src/3rdparty/libpng/pnglibconf.h +++ b/src/3rdparty/libpng/pnglibconf.h @@ -1,8 +1,8 @@ -/* libpng 1.6.32 STANDARD API DEFINITION */ +/* libpng 1.6.34 STANDARD API DEFINITION */ /* pnglibconf.h - library build configuration */ -/* Libpng version 1.6.32 - August 24, 2017 */ +/* Libpng version 1.6.34 - September 29, 2017 */ /* Copyright (c) 1998-2017 Glenn Randers-Pehrson */ diff --git a/src/3rdparty/libpng/pngread.c b/src/3rdparty/libpng/pngread.c index e34ddd99a0..da32e9ad9c 100644 --- a/src/3rdparty/libpng/pngread.c +++ b/src/3rdparty/libpng/pngread.c @@ -1,7 +1,7 @@ /* pngread.c - read a PNG file * - * Last changed in libpng 1.6.32 [August 24, 2017] + * Last changed in libpng 1.6.33 [September 28, 2017] * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) @@ -3759,7 +3759,13 @@ png_image_read_direct(png_voidp argument) mode = PNG_ALPHA_PNG; output_gamma = PNG_DEFAULT_sRGB; } - + + if ((change & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) + { + mode = PNG_ALPHA_OPTIMIZED; + change &= ~PNG_FORMAT_FLAG_ASSOCIATED_ALPHA; + } + /* If 'do_local_background' is set check for the presence of gamma * correction; this is part of the work-round for the libpng bug * described above. @@ -3985,6 +3991,10 @@ png_image_read_direct(png_voidp argument) else if (do_local_compose != 0) /* internal error */ png_error(png_ptr, "png_image_read: alpha channel lost"); + if ((format & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) { + info_format |= PNG_FORMAT_FLAG_ASSOCIATED_ALPHA; + } + if (info_ptr->bit_depth == 16) info_format |= PNG_FORMAT_FLAG_LINEAR; diff --git a/src/3rdparty/libpng/pngrtran.c b/src/3rdparty/libpng/pngrtran.c index 9a30ddf22b..c189650313 100644 --- a/src/3rdparty/libpng/pngrtran.c +++ b/src/3rdparty/libpng/pngrtran.c @@ -1,7 +1,7 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * Last changed in libpng 1.6.31 [July 27, 2017] + * Last changed in libpng 1.6.33 [September 28, 2017] * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) @@ -430,7 +430,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, int i; png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, - (png_uint_32)((png_uint_32)num_palette * (sizeof (png_byte)))); + (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte)))); for (i = 0; i < num_palette; i++) png_ptr->quantize_index[i] = (png_byte)i; } @@ -447,7 +447,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, /* Initialize an array to sort colors */ png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, - (png_uint_32)((png_uint_32)num_palette * (sizeof (png_byte)))); + (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte)))); /* Initialize the quantize_sort array */ for (i = 0; i < num_palette; i++) @@ -581,9 +581,11 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, /* Initialize palette index arrays */ png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, - (png_uint_32)((png_uint_32)num_palette * (sizeof (png_byte)))); + (png_alloc_size_t)((png_uint_32)num_palette * + (sizeof (png_byte)))); png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, - (png_uint_32)((png_uint_32)num_palette * (sizeof (png_byte)))); + (png_alloc_size_t)((png_uint_32)num_palette * + (sizeof (png_byte)))); /* Initialize the sort array */ for (i = 0; i < num_palette; i++) @@ -592,7 +594,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, png_ptr->palette_to_index[i] = (png_byte)i; } - hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * + hash = (png_dsortpp)png_calloc(png_ptr, (png_alloc_size_t)(769 * (sizeof (png_dsortp)))); num_new_palette = num_palette; @@ -623,7 +625,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, { t = (png_dsortp)png_malloc_warn(png_ptr, - (png_uint_32)(sizeof (png_dsort))); + (png_alloc_size_t)(sizeof (png_dsort))); if (t == NULL) break; @@ -748,9 +750,9 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, png_size_t num_entries = ((png_size_t)1 << total_bits); png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, - (png_uint_32)(num_entries * (sizeof (png_byte)))); + (png_alloc_size_t)(num_entries * (sizeof (png_byte)))); - distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * + distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)(num_entries * (sizeof (png_byte)))); memset(distance, 0xff, num_entries * (sizeof (png_byte))); @@ -3322,7 +3324,7 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) == png_ptr->trans_color.gray) { unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); - tmp |= + tmp |= (unsigned int)(png_ptr->background.gray << shift); *sp = (png_byte)(tmp & 0xff); } diff --git a/src/3rdparty/libpng/pngrutil.c b/src/3rdparty/libpng/pngrutil.c index a4fa71457b..8692933bd8 100644 --- a/src/3rdparty/libpng/pngrutil.c +++ b/src/3rdparty/libpng/pngrutil.c @@ -1,7 +1,7 @@ /* pngrutil.c - utilities to read a PNG file * - * Last changed in libpng 1.6.32 [August 24, 2017] + * Last changed in libpng 1.6.33 [September 28, 2017] * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) @@ -314,6 +314,7 @@ png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn) if (buffer != NULL) { + memset(buffer, 0, new_size); /* just in case */ png_ptr->read_buffer = buffer; png_ptr->read_buffer_size = new_size; } @@ -673,6 +674,8 @@ png_decompress_chunk(png_structrp png_ptr, if (text != NULL) { + memset(text, 0, buffer_size); + ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, png_ptr->read_buffer + prefix_size, &lzsize, text + prefix_size, newlength); @@ -736,9 +739,7 @@ png_decompress_chunk(png_structrp png_ptr, { /* inflateReset failed, store the error message */ png_zstream_error(png_ptr, ret); - - if (ret == Z_STREAM_END) - ret = PNG_UNEXPECTED_ZLIB_RETURN; + ret = PNG_UNEXPECTED_ZLIB_RETURN; } } @@ -1476,7 +1477,7 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) /* Now read the tag table; a variable size buffer is * needed at this point, allocate one for the whole * profile. The header check has already validated - * that none of these stuff will overflow. + * that none of this stuff will overflow. */ const png_uint_32 tag_count = png_get_uint_32( profile_header+128); @@ -1583,19 +1584,11 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) return; } } - - else if (size > 0) - errmsg = "truncated"; - -#ifndef __COVERITY__ - else + if (errmsg == NULL) errmsg = png_ptr->zstream.msg; -#endif } - /* else png_icc_check_tag_table output an error */ } - else /* profile truncated */ errmsg = png_ptr->zstream.msg; } @@ -3144,28 +3137,28 @@ png_check_chunk_length(png_const_structrp png_ptr, const png_uint_32 length) { png_alloc_size_t limit = PNG_UINT_31_MAX; - if (png_ptr->chunk_name != png_IDAT) - { # ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_malloc_max > 0 && - png_ptr->user_chunk_malloc_max < limit) - limit = png_ptr->user_chunk_malloc_max; + if (png_ptr->user_chunk_malloc_max > 0 && + png_ptr->user_chunk_malloc_max < limit) + limit = png_ptr->user_chunk_malloc_max; # elif PNG_USER_CHUNK_MALLOC_MAX > 0 - if (PNG_USER_CHUNK_MALLOC_MAX < limit) - limit = PNG_USER_CHUNK_MALLOC_MAX; + if (PNG_USER_CHUNK_MALLOC_MAX < limit) + limit = PNG_USER_CHUNK_MALLOC_MAX; # endif - } - else + if (png_ptr->chunk_name == png_IDAT) { + png_alloc_size_t idat_limit = PNG_UINT_31_MAX; size_t row_factor = (png_ptr->width * png_ptr->channels * (png_ptr->bit_depth > 8? 2: 1) + 1 + (png_ptr->interlaced? 6: 0)); if (png_ptr->height > PNG_UINT_32_MAX/row_factor) - limit=PNG_UINT_31_MAX; + idat_limit=PNG_UINT_31_MAX; else - limit = png_ptr->height * row_factor; - limit += 6 + 5*(limit/32566+1); /* zlib+deflate overhead */ - limit=limit < PNG_UINT_31_MAX? limit : PNG_UINT_31_MAX; + idat_limit = png_ptr->height * row_factor; + row_factor = row_factor > 32566? 32566 : row_factor; + idat_limit += 6 + 5*(idat_limit/row_factor+1); /* zlib+deflate overhead */ + idat_limit=idat_limit < PNG_UINT_31_MAX? idat_limit : PNG_UINT_31_MAX; + limit = limit < idat_limit? idat_limit : limit; } if (length > limit) diff --git a/src/3rdparty/libpng/pngtrans.c b/src/3rdparty/libpng/pngtrans.c index 326ac33f0e..6882f0fd7b 100644 --- a/src/3rdparty/libpng/pngtrans.c +++ b/src/3rdparty/libpng/pngtrans.c @@ -1,7 +1,7 @@ /* pngtrans.c - transforms the data in a row (used by both readers and writers) * - * Last changed in libpng 1.6.30 [June 28, 2017] + * Last changed in libpng 1.6.33 [September 28, 2017] * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) @@ -609,7 +609,7 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) return; /* The filler channel has gone already */ /* Fix the rowbytes value. */ - row_info->rowbytes = (unsigned int)(dp-row); + row_info->rowbytes = (png_size_t)(dp-row); } #endif @@ -708,7 +708,7 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) * forms produced on either GCC or MSVC. */ int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width); - png_bytep rp = png_ptr->row_buf + row_info->rowbytes; + png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1; switch (row_info->bit_depth) { diff --git a/src/3rdparty/libpng/pngwrite.c b/src/3rdparty/libpng/pngwrite.c index a7662acb71..a16d77ce00 100644 --- a/src/3rdparty/libpng/pngwrite.c +++ b/src/3rdparty/libpng/pngwrite.c @@ -1940,7 +1940,7 @@ png_image_write_main(png_voidp argument) int colormap = (format & PNG_FORMAT_FLAG_COLORMAP); int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */ int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA); - int write_16bit = linear && !colormap && (display->convert_to_8bit == 0); + int write_16bit = linear && (display->convert_to_8bit == 0); # ifdef PNG_BENIGN_ERRORS_SUPPORTED /* Make sure we error out on any bad situation */ diff --git a/src/3rdparty/libpng/qt_attribution.json b/src/3rdparty/libpng/qt_attribution.json index 7b2d776978..23fb903bdd 100644 --- a/src/3rdparty/libpng/qt_attribution.json +++ b/src/3rdparty/libpng/qt_attribution.json @@ -6,7 +6,7 @@ "Description": "libpng is the official PNG reference library.", "Homepage": "http://www.libpng.org/pub/png/libpng.html", - "Version": "1.6.32", + "Version": "1.6.34", "License": "libpng License", "LicenseId": "Libpng", "LicenseFile": "LICENSE", -- cgit v1.2.3 From d4b3ce9a287b81eb9d7c6750ccca89e362343261 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 1 Nov 2017 15:38:31 +0100 Subject: qudpsocket.pro - fix dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to the problem found in QTcpSocket auto-test recently. While the failure on CI looks differently (apparently, server process starts but does not print anything), fixing the dependency does not hurt and at least fixes the 'make check' scenario. Change-Id: I8f29f3e492d22410533407a527f5fc8f664e7f5c Reviewed-by: Gatis Paeglis Reviewed-by: MÃ¥rten Nordheim --- tests/auto/network/socket/qudpsocket/qudpsocket.pro | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/auto/network/socket/qudpsocket/qudpsocket.pro b/tests/auto/network/socket/qudpsocket/qudpsocket.pro index 4ddb7178a4..b267d5f249 100644 --- a/tests/auto/network/socket/qudpsocket/qudpsocket.pro +++ b/tests/auto/network/socket/qudpsocket/qudpsocket.pro @@ -1,4 +1,3 @@ TEMPLATE = subdirs SUBDIRS = test clientserver - - +test.depends = clientserver -- cgit v1.2.3 From ab9f4d5db6a4e183b9a26366e659ba642dedcbdd Mon Sep 17 00:00:00 2001 From: Michael Winkelmann Date: Thu, 3 Aug 2017 15:43:26 +0200 Subject: Revamp QtConcurrent examples to C++11 I updated signals and slots and for each loops to the new syntax and replaced most free functions with std::function. Task-number: QTBUG-60641 Change-Id: I7693f81f71c7f53fcbe83189a0de2fb76ddf99a8 Reviewed-by: Edward Welbourne --- .../qtconcurrent/imagescaling/imagescaling.cpp | 28 +++++++++--------- examples/qtconcurrent/imagescaling/imagescaling.h | 4 +-- examples/qtconcurrent/map/main.cpp | 12 ++++---- examples/qtconcurrent/progressdialog/main.cpp | 34 ++++++++++++---------- examples/qtconcurrent/wordcount/main.cpp | 27 +++++++++-------- 5 files changed, 57 insertions(+), 48 deletions(-) diff --git a/examples/qtconcurrent/imagescaling/imagescaling.cpp b/examples/qtconcurrent/imagescaling/imagescaling.cpp index 0a230c1194..6d22bb9598 100644 --- a/examples/qtconcurrent/imagescaling/imagescaling.cpp +++ b/examples/qtconcurrent/imagescaling/imagescaling.cpp @@ -48,15 +48,10 @@ ** ****************************************************************************/ #include "imagescaling.h" -#include -const int imageSize = 100; +#include -QImage scale(const QString &imageFileName) -{ - QImage image(imageFileName); - return image.scaled(QSize(imageSize, imageSize), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); -} +#include Images::Images(QWidget *parent) : QWidget(parent) @@ -65,19 +60,19 @@ Images::Images(QWidget *parent) resize(800, 600); imageScaling = new QFutureWatcher(this); - connect(imageScaling, SIGNAL(resultReadyAt(int)), SLOT(showImage(int))); - connect(imageScaling, SIGNAL(finished()), SLOT(finished())); + connect(imageScaling, &QFutureWatcher::resultReadyAt, this, &Images::showImage); + connect(imageScaling, &QFutureWatcher::finished, this, &Images::finished); openButton = new QPushButton(tr("Open Images")); - connect(openButton, SIGNAL(clicked()), SLOT(open())); + connect(openButton, &QPushButton::clicked, this, &Images::open); cancelButton = new QPushButton(tr("Cancel")); cancelButton->setEnabled(false); - connect(cancelButton, SIGNAL(clicked()), imageScaling, SLOT(cancel())); + connect(cancelButton, &QPushButton::clicked, imageScaling, &QFutureWatcher::cancel); pauseButton = new QPushButton(tr("Pause/Resume")); pauseButton->setEnabled(false); - connect(pauseButton, SIGNAL(clicked()), imageScaling, SLOT(togglePaused())); + connect(pauseButton, &QPushButton::clicked, imageScaling, &QFutureWatcher::togglePaused); QHBoxLayout *buttonLayout = new QHBoxLayout(); buttonLayout->addWidget(openButton); @@ -113,9 +108,11 @@ void Images::open() QStandardPaths::writableLocation(QStandardPaths::PicturesLocation), "*.jpg *.png"); - if (files.count() == 0) + if (files.isEmpty()) return; + const int imageSize = 100; + // Do a simple layout. qDeleteAll(labels); labels.clear(); @@ -130,6 +127,11 @@ void Images::open() } } + std::function scale = [imageSize](const QString &imageFileName) { + QImage image(imageFileName); + return image.scaled(QSize(imageSize, imageSize), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + }; + // Use mapped to run the thread safe scale function on the files. imageScaling->setFuture(QtConcurrent::mapped(files, scale)); diff --git a/examples/qtconcurrent/imagescaling/imagescaling.h b/examples/qtconcurrent/imagescaling/imagescaling.h index e2168e4b02..fe9c801387 100644 --- a/examples/qtconcurrent/imagescaling/imagescaling.h +++ b/examples/qtconcurrent/imagescaling/imagescaling.h @@ -57,9 +57,9 @@ class Images : public QWidget { Q_OBJECT public: - Images(QWidget *parent = 0); + Images(QWidget *parent = nullptr); ~Images(); -public Q_SLOTS: +public slots: void open(); void showImage(int num); void finished(); diff --git a/examples/qtconcurrent/map/main.cpp b/examples/qtconcurrent/map/main.cpp index d01b91fe55..8fc670b64b 100644 --- a/examples/qtconcurrent/map/main.cpp +++ b/examples/qtconcurrent/map/main.cpp @@ -55,11 +55,7 @@ #include #include -QImage scale(const QImage &image) -{ - qDebug() << "Scaling image in thread" << QThread::currentThread(); - return image.scaled(QSize(100, 100), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); -} +#include int main(int argc, char *argv[]) { @@ -72,6 +68,12 @@ int main(int argc, char *argv[]) for (int i = 0; i < imageCount; ++i) images.append(QImage(1600, 1200, QImage::Format_ARGB32_Premultiplied)); + std::function scale = [](const QImage &image) -> QImage + { + qDebug() << "Scaling image in thread" << QThread::currentThread(); + return image.scaled(QSize(100, 100), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + }; + // Use QtConcurrentBlocking::mapped to apply the scale function to all the // images in the list. QList thumbnails = QtConcurrent::blockingMapped(images, scale); diff --git a/examples/qtconcurrent/progressdialog/main.cpp b/examples/qtconcurrent/progressdialog/main.cpp index 0f251c00f1..c277111813 100644 --- a/examples/qtconcurrent/progressdialog/main.cpp +++ b/examples/qtconcurrent/progressdialog/main.cpp @@ -51,24 +51,16 @@ #include #include -using namespace QtConcurrent; - -const int iterations = 20; +#include -void spin(int &iteration) -{ - const int work = 1000 * 1000 * 40; - volatile int v = 0; - for (int j = 0; j < work; ++j) - ++v; - - qDebug() << "iteration" << iteration << "in thread" << QThread::currentThreadId(); -} +using namespace QtConcurrent; int main(int argc, char **argv) { QApplication app(argc, argv); + const int iterations = 20; + // Prepare the vector. QVector vector; for (int i = 0; i < iterations; ++i) @@ -80,10 +72,20 @@ int main(int argc, char **argv) // Create a QFutureWatcher and connect signals and slots. QFutureWatcher futureWatcher; - QObject::connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset())); - QObject::connect(&dialog, SIGNAL(canceled()), &futureWatcher, SLOT(cancel())); - QObject::connect(&futureWatcher, SIGNAL(progressRangeChanged(int,int)), &dialog, SLOT(setRange(int,int))); - QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int))); + QObject::connect(&futureWatcher, &QFutureWatcher::finished, &dialog, &QProgressDialog::reset); + QObject::connect(&dialog, &QProgressDialog::canceled, &futureWatcher, &QFutureWatcher::cancel); + QObject::connect(&futureWatcher, &QFutureWatcher::progressRangeChanged, &dialog, &QProgressDialog::setRange); + QObject::connect(&futureWatcher, &QFutureWatcher::progressValueChanged, &dialog, &QProgressDialog::setValue); + + // Our function to compute + std::function spin = [](int &iteration) { + const int work = 1000 * 1000 * 40; + volatile int v = 0; + for (int j = 0; j < work; ++j) + ++v; + + qDebug() << "iteration" << iteration << "in thread" << QThread::currentThreadId(); + }; // Start the computation. futureWatcher.setFuture(QtConcurrent::map(vector, spin)); diff --git a/examples/qtconcurrent/wordcount/main.cpp b/examples/qtconcurrent/wordcount/main.cpp index a5f8909f34..ff7ea24ee7 100644 --- a/examples/qtconcurrent/wordcount/main.cpp +++ b/examples/qtconcurrent/wordcount/main.cpp @@ -65,15 +65,17 @@ using namespace QtConcurrent; /* Utility function that recursivily searches for files. */ -QStringList findFiles(const QString &startDir, QStringList filters) +QStringList findFiles(const QString &startDir, const QStringList &filters) { QStringList names; QDir dir(startDir); - foreach (QString file, dir.entryList(filters, QDir::Files)) + const auto files = dir.entryList(filters, QDir::Files); + for (const QString &file : files) names += startDir + '/' + file; - foreach (QString subdir, dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot)) + const auto subdirs = dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot); + for (const QString &subdir : subdirs) names += findFiles(startDir + '/' + subdir, filters); return names; } @@ -83,17 +85,18 @@ typedef QMap WordCount; /* Single threaded word counter function. */ -WordCount singleThreadedWordCount(QStringList files) +WordCount singleThreadedWordCount(const QStringList &files) { WordCount wordCount; - foreach (QString file, files) { + for (const QString &file : files) { QFile f(file); f.open(QIODevice::ReadOnly); QTextStream textStream(&f); - while (textStream.atEnd() == false) - foreach (const QString &word, textStream.readLine().split(' ')) + while (!textStream.atEnd()) { + const auto words = textStream.readLine().split(' '); + for (const QString &word : words) wordCount[word] += 1; - + } } return wordCount; } @@ -109,9 +112,11 @@ WordCount countWords(const QString &file) QTextStream textStream(&f); WordCount wordCount; - while (textStream.atEnd() == false) - foreach (const QString &word, textStream.readLine().split(' ')) + while (!textStream.atEnd()) { + const auto words = textStream.readLine().split(' '); + for (const QString &word : words) wordCount[word] += 1; + } return wordCount; } @@ -137,8 +142,6 @@ int main(int argc, char** argv) qDebug() << "warmup"; { - QTime time; - time.start(); WordCount total = singleThreadedWordCount(files); } -- cgit v1.2.3 From 75bbbfdc6cadf8572651bd021de616148154c39a Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 25 Oct 2017 10:31:47 +0200 Subject: Remove BSD-OLD, FDL-OLD license headers All code should be using the license header in header.BSD or header.FDL now. If modules still use outdated headers, they should be fixed or as a stop-gap measure add header.BSD-OLD, header.FDL-OLD files locally. Change-Id: If462f1646ab413c18d2d3c61197773dca2a036ec Reviewed-by: Jani Heikkinen --- header.BSD-OLD | 40 ---------------------------------------- header.FDL-OLD | 27 --------------------------- 2 files changed, 67 deletions(-) delete mode 100644 header.BSD-OLD delete mode 100644 header.FDL-OLD diff --git a/header.BSD-OLD b/header.BSD-OLD deleted file mode 100644 index 5d73a99e9f..0000000000 --- a/header.BSD-OLD +++ /dev/null @@ -1,40 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the FOO module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD-OLD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - diff --git a/header.FDL-OLD b/header.FDL-OLD deleted file mode 100644 index 58436c482a..0000000000 --- a/header.FDL-OLD +++ /dev/null @@ -1,27 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL-OLD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -- cgit v1.2.3 From 421df7570b80ad7073d1af9b636ad42b8eb79ee8 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 7 Nov 2017 10:15:57 +0100 Subject: Enable glyph cache workaround for GC2000 as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The glyph cache resize is clearly doing something that is not actually legal with OpenGL ES. Until this gets investigated properly, add the Vivante GC2000 (found in the commonly used i.MX6 quad) to the list since reports show that the issue occurs there as well. Task-number: QTBUG-49490 Change-Id: Ia890346d8dbb1691bc113e2ef522713ba6709393 Reviewed-by: Louis Kröger Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/kernel/qopenglcontext.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 3dc06ae60e..cd6f011fcb 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -1008,6 +1008,7 @@ bool QOpenGLContext::makeCurrent(QSurface *surface) || qstrncmp(rendererString, "Adreno 4xx", 8) == 0 // Same as above but without the '(TM)' || qstrcmp(rendererString, "GC800 core") == 0 || qstrcmp(rendererString, "GC1000 core") == 0 + || strstr(rendererString, "GC2000") != 0 || qstrcmp(rendererString, "Immersion.16") == 0; } needsWorkaroundSet = true; -- cgit v1.2.3 From 59c5f7bd9da63621887260fc45e6669282d71ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 6 Nov 2017 14:52:13 +0100 Subject: macOS: Fall back to QWindow::icon for application icon if not set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are three ways to set the application (Dock/task switcher) icon: 1. By setting an ICON in the project file 2. By calling QGuiApplication::setWindowIcon 3. By calling QWindow::setIcon The third one was not working on macOS, despite being documented as such: "The window icon might be used by the windowing system for example to decorate the window, and/or in the task switcher." We now update the application icon based on the active window, unless a global application icon has been set using ICON, or via QGuiApplication::setWindowIcon. The reason for not allowing the window's icon to override a global application icon is that the developer may have intended to set the document icon for a window (to represent QWindow::filePath), and we don't want that to affect the Dock icon of the application. The role of QGuiApplication::setWindowIcon is a bit dubious in this, as it's documented as "This property holds the default window icon", which would indicate it should follow the same logic as above by not letting it override the global ICON set in the project file, but this would not allow runtime switching of the application icon, so the QGuiApplication property is left as is. The property should probably have been named QGuiApplication::applicationIcon initially. Task-number: QTBUG-63340 Change-Id: I94d3710a8586bb729af42f59a915b8f49dded101 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoaintegration.h | 6 ++++- src/plugins/platforms/cocoa/qcocoaintegration.mm | 32 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index dc7c5916a3..2fc5156d24 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -60,8 +60,9 @@ QT_BEGIN_NAMESPACE class QCocoaScreen; -class QCocoaIntegration : public QPlatformIntegration +class QCocoaIntegration : public QObject, public QPlatformIntegration { + Q_OBJECT public: enum Option { UseFreeTypeFontEngine = 0x1 @@ -120,6 +121,9 @@ public: void beep() const Q_DECL_OVERRIDE; +private Q_SLOTS: + void focusWindowChanged(QWindow *); + private: static QCocoaIntegration *mInstance; Options mOptions; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index d185905782..55b3805df3 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -179,6 +179,9 @@ QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList) QMacInternalPasteboardMime::initializeMimeTypes(); QCocoaMimeTypes::initializeMimeTypes(); QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false); + + connect(qGuiApp, &QGuiApplication::focusWindowChanged, + this, &QCocoaIntegration::focusWindowChanged); } QCocoaIntegration::~QCocoaIntegration() @@ -510,4 +513,33 @@ void QCocoaIntegration::beep() const NSBeep(); } +void QCocoaIntegration::focusWindowChanged(QWindow *focusWindow) +{ + // Don't revert icon just because we lost focus + if (!focusWindow) + return; + + static bool hasDefaultApplicationIcon = [](){ + NSImage *genericApplicationIcon = [[NSWorkspace sharedWorkspace] + iconForFileType:NSFileTypeForHFSTypeCode(kGenericApplicationIcon)]; + NSImage *applicationIcon = [NSImage imageNamed:NSImageNameApplicationIcon]; + + NSRect rect = NSMakeRect(0, 0, 32, 32); + return [applicationIcon CGImageForProposedRect:&rect context:nil hints:nil] + == [genericApplicationIcon CGImageForProposedRect:&rect context:nil hints:nil]; + }(); + + // Don't let the window icon override an explicit application icon set in the Info.plist + if (!hasDefaultApplicationIcon) + return; + + // Or an explicit application icon set on QGuiApplication + if (!qGuiApp->windowIcon().isNull()) + return; + + setApplicationIcon(focusWindow->icon()); +} + +#include "moc_qcocoaintegration.cpp" + QT_END_NAMESPACE -- cgit v1.2.3 From c3aa422df6e3eb4af7bd75c7255586e9e5f79197 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 6 Nov 2017 15:18:14 +0100 Subject: QWidget: Propagate window file path after create MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-63340 Change-Id: Ic21964a33ee2910200627fe8a8c8ec2454e2e20c Reviewed-by: Morten Johan Sørvig --- src/widgets/kernel/qwidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 9b6c3df828..de734b6f51 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1372,6 +1372,8 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) d->setWindowIconText_helper(d->topData()->iconText); if (isWindow() && !d->topData()->caption.isEmpty()) d->setWindowTitle_helper(d->topData()->caption); + if (isWindow() && !d->topData()->filePath.isEmpty()) + d->setWindowFilePath_helper(d->topData()->filePath); if (windowType() != Qt::Desktop) { d->updateSystemBackground(); -- cgit v1.2.3 From 31cc29e9be22a5c09cb90d004d967d524a02408f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 26 Oct 2017 09:32:13 +0200 Subject: Disable Xcode main thread checker by default Xcode 9 introduced the main thread checker, which detects invalid use of AppKit, UIKit, and other APIs from background threads. https://developer.apple.com/documentation/code_diagnostics/main_thread_checker In our case these are accesses to e.g. [UIView layer] and [UIScreen scaleFactor] from the render thread of QtQuick, things we should look at, but that might not be easily solvable. In any case, these are not warnings the user can do anything about, so in lack of a per-library disable of the checker, we have to globally disable it for the whole Xcode project. Task-number: QTBUG-63822 Change-Id: Ibfcdf23891cf6bfbbc9b9b3349e4c256c273c7de Reviewed-by: Eskil Abrahamsen Blomfeldt --- mkspecs/macx-xcode/default.xcscheme | 1 + 1 file changed, 1 insertion(+) diff --git a/mkspecs/macx-xcode/default.xcscheme b/mkspecs/macx-xcode/default.xcscheme index 6beb0d8280..bda2b8c1c0 100644 --- a/mkspecs/macx-xcode/default.xcscheme +++ b/mkspecs/macx-xcode/default.xcscheme @@ -62,6 +62,7 @@ useCustomWorkingDirectory = "NO" buildConfiguration = "Debug" ignoresPersistentStateOnLaunch = "NO" + disableMainThreadChecker = "YES" debugDocumentVersioning = "NO" allowLocationSimulation = "YES"> -- cgit v1.2.3 From b02bd4bbad9f80154307d06ad95a6f96c30858f0 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 15 Aug 2017 11:19:32 +0700 Subject: QMenuPrivate: Rearrange member variables This saves 32 bytes per instance on 64-bit macOS, from 888 down to 856 bytes. Change-Id: I2592631aa3566d2eab72bad338aacfe76bee8ef3 Reviewed-by: Thiago Macieira Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/widgets/qmenu_p.h | 129 +++++++++++++++++++++++++----------------- 1 file changed, 76 insertions(+), 53 deletions(-) diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index 4b7ce05169..8adfc82ef5 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -92,18 +92,18 @@ class QMenuSloppyState public: QMenuSloppyState() : m_menu(Q_NULLPTR) + , m_reset_action(Q_NULLPTR) + , m_origin_action(Q_NULLPTR) + , m_parent(Q_NULLPTR) + , m_uni_dir_discarded_count(0) + , m_uni_dir_fail_at_count(0) + , m_timeout(0) + , m_init_guard(false) + , m_first_mouse(true) , m_enabled(false) , m_uni_directional(false) , m_select_other_actions(false) - , m_first_mouse(true) - , m_init_guard(false) , m_use_reset_action(true) - , m_uni_dir_discarded_count(0) - , m_uni_dir_fail_at_count(0) - , m_timeout(0) - , m_reset_action(Q_NULLPTR) - , m_origin_action(Q_NULLPTR) - , m_parent(Q_NULLPTR) { } ~QMenuSloppyState() { reset(); } @@ -253,43 +253,59 @@ public: private: QMenu *m_menu; - bool m_enabled; - bool m_uni_directional; - bool m_select_other_actions; - bool m_first_mouse; - bool m_init_guard; - bool m_discard_state_when_entering_parent; - bool m_dont_start_time_on_leave; - bool m_use_reset_action; - short m_uni_dir_discarded_count; - short m_uni_dir_fail_at_count; - short m_timeout; - QBasicTimer m_time; QAction *m_reset_action; QAction *m_origin_action; QRectF m_action_rect; QPointF m_previous_point; QPointer m_sub_menu; QMenuSloppyState *m_parent; + QBasicTimer m_time; + short m_uni_dir_discarded_count; + short m_uni_dir_fail_at_count; + short m_timeout; + bool m_init_guard; + bool m_first_mouse; + + bool m_enabled : 1; + bool m_uni_directional : 1; + bool m_select_other_actions : 1; + bool m_discard_state_when_entering_parent : 1; + bool m_dont_start_time_on_leave : 1; + bool m_use_reset_action : 1; }; class QMenuPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QMenu) public: - QMenuPrivate() : itemsDirty(0), maxIconWidth(0), tabWidth(0), ncols(0), - collapsibleSeparators(true), toolTipsVisible(false), - activationRecursionGuard(false), delayedPopupGuard(false), - hasReceievedEnter(false), - hasHadMouse(0), aboutToHide(0), motions(0), - currentAction(0), + QMenuPrivate() : + currentAction(nullptr), #ifdef QT_KEYPAD_NAVIGATION - selectAction(0), - cancelAction(0), + selectAction(nullptr), + cancelAction(nullptr), #endif - scroll(0), eventLoop(0), tearoff(0), tornoff(0), tearoffHighlighted(0), - hasCheckableItems(0), doChildEffects(false), platformMenu(0), - scrollUpTearOffItem(nullptr), scrollDownItem(nullptr) + scroll(nullptr), + eventLoop(nullptr), + platformMenu(nullptr), + scrollUpTearOffItem(nullptr), + scrollDownItem(nullptr), + maxIconWidth(0), + tabWidth(0), + motions(0), + activationRecursionGuard(false), + ncols(0), + itemsDirty(false), + hasCheckableItems(false), + collapsibleSeparators(true), + toolTipsVisible(false), + delayedPopupGuard(false), + hasReceievedEnter(false), + hasHadMouse(false), + aboutToHide(false), + tearoff(false), + tornoff(false), + tearoffHighlighted(false), + doChildEffects(false) { } ~QMenuPrivate() @@ -310,8 +326,6 @@ public: int scrollerHeight() const; //item calculations - mutable uint itemsDirty : 1; - mutable uint maxIconWidth, tabWidth; QRect actionRect(QAction *) const; mutable QVector actionRects; @@ -320,22 +334,12 @@ public: void updateActionRects(const QRect &screen) const; QRect popupGeometry() const; QRect popupGeometry(int screen) const; - mutable uint ncols : 4; //4 bits is probably plenty - uint collapsibleSeparators : 1; - uint toolTipsVisible : 1; int getLastVisibleAction() const; - bool activationRecursionGuard; - bool delayedPopupGuard; - bool hasReceievedEnter; - //selection static QMenu *mouseDown; QPoint mousePopupPos; - uint hasHadMouse : 1; - uint aboutToHide : 1; - int motions; - int mousePopupDelay; + QAction *currentAction; #ifdef QT_KEYPAD_NAVIGATION QAction *selectAction; @@ -365,8 +369,8 @@ public: } QMenu *parent; - QBasicTimer timer; QAction *action; + QBasicTimer timer; } delayState; enum SelectionReason { SelectedFromKeyboard, @@ -383,11 +387,12 @@ public: struct QMenuScroller { enum ScrollLocation { ScrollStay, ScrollBottom, ScrollTop, ScrollCenter }; enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 }; - uint scrollFlags : 2, scrollDirection : 2; int scrollOffset; QBasicTimer scrollTimer; + quint8 scrollFlags; + quint8 scrollDirection; - QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { } + QMenuScroller() : scrollOffset(0), scrollFlags(ScrollNone), scrollDirection(ScrollNone) { } ~QMenuScroller() { } } *scroll; void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false); @@ -421,11 +426,8 @@ public: inline int indexOf(QAction *act) const { return q_func()->actions().indexOf(act); } //tear off support - uint tearoff : 1, tornoff : 1, tearoffHighlighted : 1; QPointer tornPopup; - mutable bool hasCheckableItems; - QMenuSloppyState sloppyState; //default action @@ -450,9 +452,6 @@ public: void adjustMenuScreen(const QPoint &p); void updateLayoutDirection(); - //menu fading/scrolling effects - bool doChildEffects; - QPointer platformMenu; QPointer actionAboutToTrigger; @@ -477,6 +476,30 @@ public: void drawScroller(QPainter *painter, ScrollerTearOffItem::Type type, const QRect &rect); void drawTearOff(QPainter *painter, const QRect &rect); QRect rect() const; + + mutable uint maxIconWidth, tabWidth; + int motions; + int mousePopupDelay; + + bool activationRecursionGuard; + + mutable quint8 ncols; // "255cols ought to be enough for anybody." + + mutable bool itemsDirty : 1; + mutable bool hasCheckableItems : 1; + bool collapsibleSeparators : 1; + bool toolTipsVisible : 1; + bool delayedPopupGuard : 1; + bool hasReceievedEnter : 1; + // Selection + bool hasHadMouse : 1; + bool aboutToHide : 1; + // Tear-off menus + bool tearoff : 1; + bool tornoff : 1; + bool tearoffHighlighted : 1; + //menu fading/scrolling effects + bool doChildEffects : 1; }; QT_END_NAMESPACE -- cgit v1.2.3 From 237b1c1d689fabf1680a8cf3d9226da5f712302d Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Sat, 26 Aug 2017 11:26:45 +0700 Subject: QMenuPrivate: Use in-class initializers where possible Change-Id: I5347cb41443baf96e28bd399c84983a801b10fcd Reviewed-by: Thiago Macieira Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/widgets/qmenu_p.h | 87 +++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 56 deletions(-) diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index 8adfc82ef5..64d22087e3 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -91,16 +91,7 @@ class QMenuSloppyState Q_DISABLE_COPY(QMenuSloppyState) public: QMenuSloppyState() - : m_menu(Q_NULLPTR) - , m_reset_action(Q_NULLPTR) - , m_origin_action(Q_NULLPTR) - , m_parent(Q_NULLPTR) - , m_uni_dir_discarded_count(0) - , m_uni_dir_fail_at_count(0) - , m_timeout(0) - , m_init_guard(false) - , m_first_mouse(true) - , m_enabled(false) + : m_enabled(false) , m_uni_directional(false) , m_select_other_actions(false) , m_use_reset_action(true) @@ -252,19 +243,19 @@ public: QMenu *subMenu() const { return m_sub_menu; } private: - QMenu *m_menu; - QAction *m_reset_action; - QAction *m_origin_action; + QMenu *m_menu = nullptr; + QAction *m_reset_action = nullptr; + QAction *m_origin_action = nullptr; QRectF m_action_rect; QPointF m_previous_point; QPointer m_sub_menu; - QMenuSloppyState *m_parent; + QMenuSloppyState *m_parent = nullptr; QBasicTimer m_time; - short m_uni_dir_discarded_count; - short m_uni_dir_fail_at_count; - short m_timeout; - bool m_init_guard; - bool m_first_mouse; + short m_uni_dir_discarded_count = 0; + short m_uni_dir_fail_at_count = 0; + short m_timeout = 0; + bool m_init_guard = false; + bool m_first_mouse = true; bool m_enabled : 1; bool m_uni_directional : 1; @@ -279,21 +270,6 @@ class QMenuPrivate : public QWidgetPrivate Q_DECLARE_PUBLIC(QMenu) public: QMenuPrivate() : - currentAction(nullptr), -#ifdef QT_KEYPAD_NAVIGATION - selectAction(nullptr), - cancelAction(nullptr), -#endif - scroll(nullptr), - eventLoop(nullptr), - platformMenu(nullptr), - scrollUpTearOffItem(nullptr), - scrollDownItem(nullptr), - maxIconWidth(0), - tabWidth(0), - motions(0), - activationRecursionGuard(false), - ncols(0), itemsDirty(false), hasCheckableItems(false), collapsibleSeparators(true), @@ -340,15 +316,13 @@ public: static QMenu *mouseDown; QPoint mousePopupPos; - QAction *currentAction; + QAction *currentAction = nullptr; #ifdef QT_KEYPAD_NAVIGATION - QAction *selectAction; - QAction *cancelAction; + QAction *selectAction = nullptr; + QAction *cancelAction = nullptr; #endif struct DelayState { DelayState() - : parent(0) - , action(0) { } void initialize(QMenu *parent) { @@ -368,8 +342,8 @@ public: timer.stop(); } - QMenu *parent; - QAction *action; + QMenu *parent = nullptr; + QAction *action = nullptr; QBasicTimer timer; } delayState; enum SelectionReason { @@ -387,20 +361,20 @@ public: struct QMenuScroller { enum ScrollLocation { ScrollStay, ScrollBottom, ScrollTop, ScrollCenter }; enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 }; - int scrollOffset; + int scrollOffset = 0; QBasicTimer scrollTimer; - quint8 scrollFlags; - quint8 scrollDirection; + quint8 scrollFlags = ScrollNone; + quint8 scrollDirection = ScrollNone; - QMenuScroller() : scrollOffset(0), scrollFlags(ScrollNone), scrollDirection(ScrollNone) { } + QMenuScroller() { } ~QMenuScroller() { } - } *scroll; + } *scroll = nullptr; void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false); void scrollMenu(QMenuScroller::ScrollDirection direction, bool page=false, bool active=false); void scrollMenu(QAction *action, QMenuScroller::ScrollLocation location, bool active=false); //synchronous operation (ie exec()) - QEventLoop *eventLoop; + QEventLoop *eventLoop = nullptr; QPointer syncAction; //search buffer @@ -433,8 +407,8 @@ public: //default action QPointer defaultAction; - QAction *menuAction; - QAction *defaultMenuAction; + QAction *menuAction = nullptr; + QAction *defaultMenuAction = nullptr; void setOverrideMenuAction(QAction *); void _q_overrideMenuActionDestroyed(); @@ -470,20 +444,21 @@ public: QMenuPrivate *menuPrivate; Type scrollType; }; - ScrollerTearOffItem *scrollUpTearOffItem; - ScrollerTearOffItem *scrollDownItem; + ScrollerTearOffItem *scrollUpTearOffItem = nullptr; + ScrollerTearOffItem *scrollDownItem = nullptr; void drawScroller(QPainter *painter, ScrollerTearOffItem::Type type, const QRect &rect); void drawTearOff(QPainter *painter, const QRect &rect); QRect rect() const; - mutable uint maxIconWidth, tabWidth; - int motions; - int mousePopupDelay; + mutable uint maxIconWidth = 0; + mutable uint tabWidth = 0; + int motions = 0; + int mousePopupDelay = 0; - bool activationRecursionGuard; + bool activationRecursionGuard = false; - mutable quint8 ncols; // "255cols ought to be enough for anybody." + mutable quint8 ncols = 0; // "255cols ought to be enough for anybody." mutable bool itemsDirty : 1; mutable bool hasCheckableItems : 1; -- cgit v1.2.3 From 7986e1e2f0c88ea305dd8a842884908ed4724fd7 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 20 Oct 2017 18:12:17 +0700 Subject: QMenuBar: Update title on change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When one of the menubar actions changed, we would omit to update several properties on the platform menu, most notably its title. Manual tested with BigMenuCreator, where the sequence menu->addAction(action); // A-operation action->setMenu(submenu); // S-operation would result in an "Untitled" menubar item on macOS, and this regardless of when the submenu is populated. Change-Id: I43989f36f6bf3f0b7056310ac986c06f8e02f128 Reviewed-by: Dmitry Shachnev Reviewed-by: Erik Verbruggen Reviewed-by: Morten Johan Sørvig --- src/widgets/widgets/qmenubar.cpp | 54 +++++++++++++++++++++++----------------- src/widgets/widgets/qmenubar_p.h | 4 ++- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 41b6bf49f8..6dfbb7c8a1 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -1187,7 +1187,7 @@ void QMenuBar::leaveEvent(QEvent *) d->setCurrentAction(0); } -QPlatformMenu *QMenuBarPrivate::getPlatformMenu(QAction *action) +QPlatformMenu *QMenuBarPrivate::getPlatformMenu(const QAction *action) { if (!action || !action->menu()) return 0; @@ -1202,6 +1202,29 @@ QPlatformMenu *QMenuBarPrivate::getPlatformMenu(QAction *action) return platformMenu; } +QPlatformMenu *QMenuBarPrivate::findInsertionPlatformMenu(const QAction *action) +{ + Q_Q(QMenuBar); + QPlatformMenu *beforeMenu = nullptr; + for (int beforeIndex = indexOf(const_cast(action)) + 1; + !beforeMenu && (beforeIndex < q->actions().size()); + ++beforeIndex) { + beforeMenu = getPlatformMenu(q->actions().at(beforeIndex)); + } + + return beforeMenu; +} + +void QMenuBarPrivate::copyActionToPlatformMenu(const QAction *action, QPlatformMenu *menu) +{ + const auto tag = reinterpret_cast(action); + if (menu->tag() != tag) + menu->setTag(tag); + menu->setText(action->text()); + menu->setVisible(action->isVisible()); + menu->setEnabled(action->isEnabled()); +} + /*! \reimp */ @@ -1218,16 +1241,9 @@ void QMenuBar::actionEvent(QActionEvent *e) if (e->type() == QEvent::ActionAdded) { QPlatformMenu *menu = d->getPlatformMenu(e->action()); if (menu) { - QPlatformMenu* beforeMenu = NULL; - for (int beforeIndex = d->indexOf(e->action()) + 1; - !beforeMenu && (beforeIndex < actions().size()); - ++beforeIndex) - { - beforeMenu = d->getPlatformMenu(actions().at(beforeIndex)); - } + d->copyActionToPlatformMenu(e->action(), menu); - menu->setTag(reinterpret_cast(e->action())); - menu->setText(e->action()->text()); + QPlatformMenu *beforeMenu = d->findInsertionPlatformMenu(e->action()); d->platformMenuBar->insertMenu(menu, beforeMenu); } } else if (e->type() == QEvent::ActionRemoved) { @@ -1235,7 +1251,7 @@ void QMenuBar::actionEvent(QActionEvent *e) if (menu) d->platformMenuBar->removeMenu(menu); } else if (e->type() == QEvent::ActionChanged) { - QPlatformMenu* cur = d->platformMenuBar->menuForTag(reinterpret_cast(e->action())); + QPlatformMenu *cur = d->platformMenuBar->menuForTag(reinterpret_cast(e->action())); QPlatformMenu *menu = d->getPlatformMenu(e->action()); // the menu associated with the action can change, need to @@ -1244,21 +1260,13 @@ void QMenuBar::actionEvent(QActionEvent *e) if (cur) d->platformMenuBar->removeMenu(cur); if (menu) { - menu->setTag(reinterpret_cast(e->action())); - - QPlatformMenu* beforeMenu = NULL; - for (int beforeIndex = d->indexOf(e->action()) + 1; - !beforeMenu && (beforeIndex < actions().size()); - ++beforeIndex) - { - beforeMenu = d->getPlatformMenu(actions().at(beforeIndex)); - } + d->copyActionToPlatformMenu(e->action(), menu); + + QPlatformMenu *beforeMenu = d->findInsertionPlatformMenu(e->action()); d->platformMenuBar->insertMenu(menu, beforeMenu); } } else if (menu) { - menu->setText(e->action()->text()); - menu->setVisible(e->action()->isVisible()); - menu->setEnabled(e->action()->isEnabled()); + d->copyActionToPlatformMenu(e->action(), menu); d->platformMenuBar->syncMenu(menu); } } diff --git a/src/widgets/widgets/qmenubar_p.h b/src/widgets/widgets/qmenubar_p.h index 01d8793a3a..c276a4512d 100644 --- a/src/widgets/widgets/qmenubar_p.h +++ b/src/widgets/widgets/qmenubar_p.h @@ -132,7 +132,9 @@ public: QBasicTimer autoReleaseTimer; QPlatformMenuBar *platformMenuBar; - QPlatformMenu *getPlatformMenu(QAction *action); + QPlatformMenu *getPlatformMenu(const QAction *action); + QPlatformMenu *findInsertionPlatformMenu(const QAction *action); + void copyActionToPlatformMenu(const QAction *e, QPlatformMenu *menu); inline int indexOf(QAction *act) const { return q_func()->actions().indexOf(act); } }; -- cgit v1.2.3 From 5d6878f234d1d8697bba43cb5140094dee722a86 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 24 Oct 2017 14:53:31 +0700 Subject: QMainWindow: Clear menubar parent when new one is set In QMainWindow::setMenuBar(), we hide and schedule the current menubar, if any, to be deleted later. However, it remains installed as its whole ancestry's event filter, which could conflict with the newly assigned menubar until the old menubar is destroyed. In our case, we have noticed issues with the Cocoa QPA plugin. We force uninstalling the old menubar as event filter by setting its parent to null, pending its deletion shortly after. This fixes BigMenuCreator's empty menubar when calling it with only the "--new-menubar" option. It also fixes QTBUG-34160 example which was not behaving as well as it should. Task-number: QTBUG-34160 Change-Id: Ifefb72affad01e7b7371005442074afd6a39a5b8 Reviewed-by: Dmitry Shachnev Reviewed-by: Shawn Rutledge --- src/widgets/widgets/qmainwindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp index 5c6f983149..ced7ec38ea 100644 --- a/src/widgets/widgets/qmainwindow.cpp +++ b/src/widgets/widgets/qmainwindow.cpp @@ -574,6 +574,7 @@ void QMainWindow::setMenuBar(QMenuBar *menuBar) menuBar->setCornerWidget(cornerWidget, Qt::TopRightCorner); } oldMenuBar->hide(); + oldMenuBar->setParent(nullptr); oldMenuBar->deleteLater(); } topLayout->setMenuBar(menuBar); -- cgit v1.2.3 From 3f519ffa150ce5a2d9e3ad3f147745b312d29afb Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 25 Oct 2017 09:32:48 +0700 Subject: QCocoaMenuItem: Don't clear NSMenuItem.action when setting submenu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Contrarily to what the comment stated, we actually rely on automatic menu validation, even for submenu items. This is visible in the menu delegate's validateMenuItem: and itemFired: methods. This solves the last visible issue in BigMenuCreator where, under ASP/ASP, ASP/SAP, SAP/ASP and SAP/SAP, all A*S submenus would be disabled. The cause was an incorrect target/action setup. Menurama still behaves as expected. Change-Id: I2599d6fb0d51f56f5d36f03b69647e35ff6c550a Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoamenuitem.mm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index ecbab38a83..394e0fb8e4 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -150,10 +150,6 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu) QMacAutoReleasePool pool; m_menu = static_cast(menu); if (m_menu) { - if (m_native) { - // Skip automatic menu item validation - m_native.action = nil; - } m_menu->setMenuParent(this); m_menu->propagateEnabledState(isEnabled()); } else { -- cgit v1.2.3 From 159b3306d66d91274feb9fd28fdc176cecf47755 Mon Sep 17 00:00:00 2001 From: Helio Chissini de Castro Date: Wed, 27 Sep 2017 10:11:50 +0200 Subject: Change fallthrough detection order to fix clang detection Clang compiler defines fallthrough, but wrongly detects QT_HAS_CPP_ATTRIBUTE(fallthrough). This makes compiler breaks compilation due clang be expecting clang::fallthrough. Change the order makes the exceptions. clang/gnu, been tested before the generic, setting then proper defines at end. LLVM-bug: https://bugs.llvm.org/show_bug.cgi?id=33518 Change-Id: Ic287e9028936af3bdade5c1ee319ca8914b36ea7 Reviewed-by: Thiago Macieira --- src/corelib/global/qcompilerdetection.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 2c58ff87e9..231ac2c9b0 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -1347,12 +1347,12 @@ } while (false) #if defined(__cplusplus) -#if QT_HAS_CPP_ATTRIBUTE(fallthrough) -# define Q_FALLTHROUGH() [[fallthrough]] -#elif QT_HAS_CPP_ATTRIBUTE(clang::fallthrough) +#if QT_HAS_CPP_ATTRIBUTE(clang::fallthrough) # define Q_FALLTHROUGH() [[clang::fallthrough]] #elif QT_HAS_CPP_ATTRIBUTE(gnu::fallthrough) # define Q_FALLTHROUGH() [[gnu::fallthrough]] +#elif QT_HAS_CPP_ATTRIBUTE(fallthrough) +# define Q_FALLTHROUGH() [[fallthrough]] #endif #endif #ifndef Q_FALLTHROUGH -- cgit v1.2.3 From fad8f340333f1c9ec7b6cebe521d53f4b1da4f8d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 7 Nov 2017 09:47:56 +0100 Subject: Extend blacklisting in qnetworkreply - Blacklist ioHttpRedirectPostPut for Windows - Amend 84396a3f938453b81e6ecc73bd54ff6b08960e8f: Keys need to be on subsequent lines Task-number: QTBUG-62583 Change-Id: I6360ec7bd87de65a3294a0d22148f13579fcd292 Reviewed-by: Timur Pocheptsov --- tests/auto/network/access/qnetworkreply/BLACKLIST | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index 9ae424943d..acea0a5aad 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -25,9 +25,11 @@ windows [ioHttpRedirectMultipartPost] linux [ioHttpRedirectPolicy] -b2qt linux 64bit +b2qt 64bit +linux [ioHttpRedirectPostPut] linux +windows [putWithServerClosingConnectionImmediately] windows [qtbug28035browserDoesNotLoadQtProjectOrgCorrectly] -- cgit v1.2.3 From 19b0ce5daa31e2ffebfcf2701143742302f1deb4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 13 Apr 2017 21:13:52 -0700 Subject: Change almost all other uses of qrand() to QRandomGenerator The vast majority is actually switched to QRandomGenerator::bounded(), which gives a mostly uniform distribution over the [0, bound) range. There are very few floating point cases left, as many of those that did use floating point did not need to, after all. (I did leave some that were too ugly for me to understand) This commit also found a couple of calls to rand() instead of qrand(). This commit does not include changes to SSL code that continues to use qrand() (job for someone else): src/network/ssl/qsslkey_qt.cpp src/network/ssl/qsslsocket_mac.cpp tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp Change-Id: Icd0e0d4b27cb4e5eb892fffd14b5285d43f4afbf Reviewed-by: Lars Knoll --- examples/corelib/ipc/localfortuneserver/server.cpp | 2 +- examples/corelib/json/savegame/game.cpp | 12 ++++----- examples/corelib/threads/queuedcustomtype/main.cpp | 1 - .../threads/queuedcustomtype/renderthread.cpp | 6 +++-- examples/corelib/threads/semaphores/semaphores.cpp | 3 +-- .../threads/waitconditions/waitconditions.cpp | 4 +-- .../tools/contiguouscache/randomlistmodel.cpp | 3 ++- examples/embedded/flickable/main.cpp | 2 +- examples/network/fortuneserver/server.cpp | 2 +- .../threadedfortuneserver/fortuneserver.cpp | 4 ++- examples/network/threadedfortuneserver/main.cpp | 1 - examples/network/torrent/main.cpp | 1 - examples/network/torrent/torrentclient.cpp | 22 ++++++++-------- examples/opengl/hellowindow/hellowindow.cpp | 7 ++--- examples/opengl/legacy/overpainting/bubble.cpp | 10 +++++--- examples/opengl/legacy/overpainting/glwidget.cpp | 12 ++++----- examples/opengl/qopenglwidget/bubble.cpp | 8 +++--- examples/opengl/qopenglwidget/glwidget.cpp | 11 ++++---- examples/opengl/qopenglwidget/mainwindow.cpp | 5 +++- examples/touch/pinchzoom/main.cpp | 1 - examples/touch/pinchzoom/mouse.cpp | 15 ++++++----- examples/widgets/animation/animatedtiles/main.cpp | 5 ++-- examples/widgets/animation/moveblocks/main.cpp | 4 +-- examples/widgets/animation/stickman/lifecycle.cpp | 3 +-- examples/widgets/animation/sub-attaq/main.cpp | 2 -- examples/widgets/animation/sub-attaq/states.cpp | 7 ++--- examples/widgets/animation/sub-attaq/submarine_p.h | 5 ++-- .../widgets/doc/src/collidingmice-example.qdoc | 10 ++------ examples/widgets/doc/src/dragdroprobot.qdoc | 2 +- examples/widgets/doc/src/elasticnodes.qdoc | 9 +++---- examples/widgets/draganddrop/puzzle/mainwindow.cpp | 4 +-- examples/widgets/graphicsview/boxes/qtbox.cpp | 2 +- examples/widgets/graphicsview/boxes/scene.cpp | 10 +++++--- .../widgets/graphicsview/collidingmice/main.cpp | 1 - .../widgets/graphicsview/collidingmice/mouse.cpp | 15 ++++++----- .../graphicsview/dragdroprobot/coloritem.cpp | 4 +-- .../widgets/graphicsview/dragdroprobot/main.cpp | 1 - .../graphicsview/elasticnodes/graphwidget.cpp | 3 ++- .../widgets/graphicsview/elasticnodes/main.cpp | 1 - examples/widgets/itemviews/puzzle/mainwindow.cpp | 2 -- examples/widgets/itemviews/puzzle/piecesmodel.cpp | 3 ++- .../widgets/mainwindows/mainwindow/toolbar.cpp | 4 ++- examples/widgets/statemachine/rogue/window.cpp | 4 +-- .../plugins/basictools/basictoolsplugin.cpp | 2 +- examples/widgets/tools/undo/mainwindow.cpp | 11 ++++---- .../widgets/tools/undoframework/diagramitem.cpp | 3 +-- examples/widgets/widgets/tetrix/main.cpp | 1 - examples/widgets/widgets/tetrix/tetrixpiece.cpp | 2 +- examples/widgets/widgets/tooltips/main.cpp | 1 - examples/widgets/widgets/tooltips/sortingbox.cpp | 4 +-- src/corelib/io/qprocess_win.cpp | 7 +++-- src/corelib/io/qtemporaryfile.cpp | 2 +- src/gui/image/qpixmap_blitter.cpp | 3 ++- src/gui/opengl/qopenglgradientcache.cpp | 3 ++- src/gui/painting/qpaintengine_raster.cpp | 3 ++- src/network/kernel/qdnslookup.cpp | 11 +++----- src/opengl/gl2paintengineex/qglgradientcache.cpp | 3 ++- .../qtconcurrentmap/tst_qtconcurrentmap.cpp | 4 +-- tests/auto/corelib/io/largefile/tst_largefile.cpp | 4 +-- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 4 +-- .../mimetypes/qmimedatabase/tst_qmimedatabase.cpp | 1 - .../plugin/quuid/testProcessUniqueness/main.cpp | 3 --- tests/auto/corelib/thread/qfuture/tst_qfuture.cpp | 3 ++- .../corelib/tools/qalgorithms/tst_qalgorithms.cpp | 11 ++++---- .../tools/qsharedpointer/tst_qsharedpointer.cpp | 5 ++-- tests/auto/gui/image/qimage/tst_qimage.cpp | 3 ++- tests/auto/gui/painting/qpainter/tst_qpainter.cpp | 3 ++- .../gui/painting/qpathclipper/tst_qpathclipper.cpp | 5 ++-- .../text/qtextpiecetable/tst_qtextpiecetable.cpp | 19 +++++++------- tests/auto/network/access/hpack/tst_hpack.cpp | 12 ++++----- tests/auto/network/access/http2/tst_http2.cpp | 2 +- tests/auto/network/access/qftp/tst_qftp.cpp | 3 +-- .../qnetworkdiskcache/tst_qnetworkdiskcache.cpp | 14 +++++----- .../access/qnetworkreply/tst_qnetworkreply.cpp | 10 ++++---- .../network/socket/qtcpsocket/tst_qtcpsocket.cpp | 8 +++--- tests/auto/opengl/qglthreads/tst_qglthreads.cpp | 20 +++++++-------- tests/auto/other/compiler/tst_compiler.cpp | 10 ++++---- .../other/networkselftest/tst_networkselftest.cpp | 3 ++- .../dialogs/qfiledialog2/tst_qfiledialog2.cpp | 3 ++- .../qgraphicsitem/tst_qgraphicsitem.cpp | 17 ++++++------ .../qgraphicsscene/tst_qgraphicsscene.cpp | 30 +++++++++++----------- .../widgets/itemviews/qitemview/tst_qitemview.cpp | 23 +++++------------ tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 3 ++- .../widgets/widgets/qlineedit/tst_qlineedit.cpp | 16 +----------- .../corelib/tools/qalgorithms/tst_qalgorithms.cpp | 2 +- .../corelib/tools/qcryptographichash/main.cpp | 6 ++--- .../GraphicsViewBenchmark/widgets/dummydatagen.cpp | 16 ++++++------ .../qgraphicsview/benchapps/moveItems/main.cpp | 2 +- .../qgraphicswidget/tst_qgraphicswidget.cpp | 5 +++- .../gui/painting/qtbench/benchmarktests.h | 9 ++++--- .../access/qnetworkreply/tst_qnetworkreply.cpp | 3 ++- tests/manual/cocoa/nativewidgets/main.cpp | 2 +- .../manual/textrendering/textperformance/main.cpp | 21 +++++++-------- .../windowchildgeometry/controllerwidget.cpp | 18 +++++-------- 94 files changed, 292 insertions(+), 320 deletions(-) diff --git a/examples/corelib/ipc/localfortuneserver/server.cpp b/examples/corelib/ipc/localfortuneserver/server.cpp index 9b8b08bd17..be8d4750d6 100644 --- a/examples/corelib/ipc/localfortuneserver/server.cpp +++ b/examples/corelib/ipc/localfortuneserver/server.cpp @@ -106,7 +106,7 @@ void Server::sendFortune() QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_5_10); - const int fortuneIndex = QRandomGenerator::bounded(0, fortunes.size()); + const int fortuneIndex = QRandomGenerator::global()->bounded(0, fortunes.size()); const QString &message = fortunes.at(fortuneIndex); out << quint32(message.size()); out << message; diff --git a/examples/corelib/json/savegame/game.cpp b/examples/corelib/json/savegame/game.cpp index c70a50121c..4caec71a03 100644 --- a/examples/corelib/json/savegame/game.cpp +++ b/examples/corelib/json/savegame/game.cpp @@ -72,7 +72,7 @@ void Game::newGame() mPlayer = Character(); mPlayer.setName(QStringLiteral("Hero")); mPlayer.setClassType(Character::Archer); - mPlayer.setLevel(QRandomGenerator::bounded(15, 21)); + mPlayer.setLevel(QRandomGenerator::global()->bounded(15, 21)); mLevels.clear(); mLevels.reserve(2); @@ -81,10 +81,10 @@ void Game::newGame() QVector villageNpcs; villageNpcs.reserve(2); villageNpcs.append(Character(QStringLiteral("Barry the Blacksmith"), - QRandomGenerator::bounded(8, 11), + QRandomGenerator::global()->bounded(8, 11), Character::Warrior)); villageNpcs.append(Character(QStringLiteral("Terry the Trader"), - QRandomGenerator::bounded(6, 8), + QRandomGenerator::global()->bounded(6, 8), Character::Warrior)); village.setNpcs(villageNpcs); mLevels.append(village); @@ -93,13 +93,13 @@ void Game::newGame() QVector dungeonNpcs; dungeonNpcs.reserve(3); dungeonNpcs.append(Character(QStringLiteral("Eric the Evil"), - QRandomGenerator::bounded(18, 26), + QRandomGenerator::global()->bounded(18, 26), Character::Mage)); dungeonNpcs.append(Character(QStringLiteral("Eric's Left Minion"), - QRandomGenerator::bounded(5, 7), + QRandomGenerator::global()->bounded(5, 7), Character::Warrior)); dungeonNpcs.append(Character(QStringLiteral("Eric's Right Minion"), - QRandomGenerator::bounded(4, 9), + QRandomGenerator::global()->bounded(4, 9), Character::Warrior)); dungeon.setNpcs(dungeonNpcs); mLevels.append(dungeon); diff --git a/examples/corelib/threads/queuedcustomtype/main.cpp b/examples/corelib/threads/queuedcustomtype/main.cpp index 7084b7538a..1f25fafa1b 100644 --- a/examples/corelib/threads/queuedcustomtype/main.cpp +++ b/examples/corelib/threads/queuedcustomtype/main.cpp @@ -126,7 +126,6 @@ int main(int argc, char *argv[]) //! [main start] //! [register meta-type for queued communications] qRegisterMetaType(); //! [register meta-type for queued communications] - qsrand(QTime::currentTime().elapsed()); Window window; window.show(); diff --git a/examples/corelib/threads/queuedcustomtype/renderthread.cpp b/examples/corelib/threads/queuedcustomtype/renderthread.cpp index f894dd587f..67cedf1e74 100644 --- a/examples/corelib/threads/queuedcustomtype/renderthread.cpp +++ b/examples/corelib/threads/queuedcustomtype/renderthread.cpp @@ -50,6 +50,8 @@ #include "renderthread.h" +#include + RenderThread::RenderThread(QObject *parent) : QThread(parent) { @@ -82,9 +84,9 @@ void RenderThread::run() for (int s = size; s > 0; --s) { for (int c = 0; c < 400; ++c) { //![processing the image (start)] - int x1 = qMax(0, (qrand() % m_image.width()) - s/2); + int x1 = qMax(0, QRandomGenerator::global()->bounded(m_image.width()) - s/2); int x2 = qMin(x1 + s/2 + 1, m_image.width()); - int y1 = qMax(0, (qrand() % m_image.height()) - s/2); + int y1 = qMax(0, QRandomGenerator::global()->bounded(m_image.height()) - s/2); int y2 = qMin(y1 + s/2 + 1, m_image.height()); int n = 0; int red = 0; diff --git a/examples/corelib/threads/semaphores/semaphores.cpp b/examples/corelib/threads/semaphores/semaphores.cpp index 37dd4cda20..145624bb0b 100644 --- a/examples/corelib/threads/semaphores/semaphores.cpp +++ b/examples/corelib/threads/semaphores/semaphores.cpp @@ -70,10 +70,9 @@ class Producer : public QThread public: void run() override { - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); for (int i = 0; i < DataSize; ++i) { freeBytes.acquire(); - buffer[i % BufferSize] = "ACGT"[(int)qrand() % 4]; + buffer[i % BufferSize] = "ACGT"[QRandomGenerator::global()->bounded(4)]; usedBytes.release(); } } diff --git a/examples/corelib/threads/waitconditions/waitconditions.cpp b/examples/corelib/threads/waitconditions/waitconditions.cpp index 9eab28f94c..963ee03a76 100644 --- a/examples/corelib/threads/waitconditions/waitconditions.cpp +++ b/examples/corelib/threads/waitconditions/waitconditions.cpp @@ -76,15 +76,13 @@ public: void run() override { - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); - for (int i = 0; i < DataSize; ++i) { mutex.lock(); if (numUsedBytes == BufferSize) bufferNotFull.wait(&mutex); mutex.unlock(); - buffer[i % BufferSize] = "ACGT"[(int)qrand() % 4]; + buffer[i % BufferSize] = "ACGT"[QRandomGenerator::global()->bounded(4)]; mutex.lock(); ++numUsedBytes; diff --git a/examples/corelib/tools/contiguouscache/randomlistmodel.cpp b/examples/corelib/tools/contiguouscache/randomlistmodel.cpp index f3d8f4b133..ccaa45a28b 100644 --- a/examples/corelib/tools/contiguouscache/randomlistmodel.cpp +++ b/examples/corelib/tools/contiguouscache/randomlistmodel.cpp @@ -48,6 +48,7 @@ ** ****************************************************************************/ #include "randomlistmodel.h" +#include #include static const int bufferSize(500); @@ -101,6 +102,6 @@ void RandomListModel::cacheRows(int from, int to) const //![1] QString RandomListModel::fetchRow(int position) const { - return QString::number(rand() % ++position); + return QString::number(QRandomGenerator::global()->bounded(++position)); } //![1] diff --git a/examples/embedded/flickable/main.cpp b/examples/embedded/flickable/main.cpp index 9772ba4f55..9367c8b4fe 100644 --- a/examples/embedded/flickable/main.cpp +++ b/examples/embedded/flickable/main.cpp @@ -72,7 +72,7 @@ static QStringList colorPairs(int max) // randomize it colors.clear(); while (combinedColors.count()) { - int i = qrand() % combinedColors.count(); + int i = QRandomGenerator::global()->bounded(combinedColors.count()); colors << combinedColors[i]; combinedColors.removeAt(i); if (colors.count() == max) diff --git a/examples/network/fortuneserver/server.cpp b/examples/network/fortuneserver/server.cpp index 3915a73bf0..7db81fe07a 100644 --- a/examples/network/fortuneserver/server.cpp +++ b/examples/network/fortuneserver/server.cpp @@ -182,7 +182,7 @@ void Server::sendFortune() QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_5_10); - out << fortunes[QRandomGenerator::bounded(fortunes.size())]; + out << fortunes[QRandomGenerator::global()->bounded(fortunes.size())]; //! [4] //! [7] QTcpSocket *clientConnection = tcpServer->nextPendingConnection(); diff --git a/examples/network/threadedfortuneserver/fortuneserver.cpp b/examples/network/threadedfortuneserver/fortuneserver.cpp index 01b77e2aba..791ffc71f4 100644 --- a/examples/network/threadedfortuneserver/fortuneserver.cpp +++ b/examples/network/threadedfortuneserver/fortuneserver.cpp @@ -51,6 +51,8 @@ #include "fortuneserver.h" #include "fortunethread.h" +#include + #include //! [0] @@ -70,7 +72,7 @@ FortuneServer::FortuneServer(QObject *parent) //! [1] void FortuneServer::incomingConnection(qintptr socketDescriptor) { - QString fortune = fortunes.at(qrand() % fortunes.size()); + QString fortune = fortunes.at(QRandomGenerator::global()->bounded(fortunes.size())); FortuneThread *thread = new FortuneThread(socketDescriptor, fortune, this); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); thread->start(); diff --git a/examples/network/threadedfortuneserver/main.cpp b/examples/network/threadedfortuneserver/main.cpp index 3a54585fbc..fdacb28945 100644 --- a/examples/network/threadedfortuneserver/main.cpp +++ b/examples/network/threadedfortuneserver/main.cpp @@ -60,6 +60,5 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); Dialog dialog; dialog.show(); - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); return app.exec(); } diff --git a/examples/network/torrent/main.cpp b/examples/network/torrent/main.cpp index de7516ed3f..6430d2e5f3 100644 --- a/examples/network/torrent/main.cpp +++ b/examples/network/torrent/main.cpp @@ -55,7 +55,6 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); Q_INIT_RESOURCE(icons); diff --git a/examples/network/torrent/torrentclient.cpp b/examples/network/torrent/torrentclient.cpp index ba87924ff9..95232646ab 100644 --- a/examples/network/torrent/torrentclient.cpp +++ b/examples/network/torrent/torrentclient.cpp @@ -692,7 +692,7 @@ void TorrentClient::connectToPeers() // Start as many connections as we can while (!weighedPeers.isEmpty() && ConnectionManager::instance()->canAddConnection() - && (qrand() % (ConnectionManager::instance()->maxConnections() / 2))) { + && (QRandomGenerator::global()->bounded(ConnectionManager::instance()->maxConnections() / 2))) { PeerWireClient *client = new PeerWireClient(ConnectionManager::instance()->clientId(), this); RateController::instance()->addSocket(client); ConnectionManager::instance()->addConnection(client); @@ -701,7 +701,7 @@ void TorrentClient::connectToPeers() d->connections << client; // Pick a random peer from the list of weighed peers. - TorrentPeer *peer = weighedPeers.takeAt(qrand() % weighedPeers.size()); + TorrentPeer *peer = weighedPeers.takeAt(QRandomGenerator::global()->bounded(weighedPeers.size())); weighedPeers.removeAll(peer); peer->connectStart = QDateTime::currentSecsSinceEpoch(); peer->lastVisited = peer->connectStart; @@ -1114,7 +1114,7 @@ void TorrentClient::scheduleUploads() } if ((client->peerWireState() & PeerWireClient::ChokingPeer) == 0) { - if ((qrand() % 10) == 0) + if ((QRandomGenerator::global()->bounded(10)) == 0) client->abort(); else client->chokePeer(); @@ -1128,7 +1128,7 @@ void TorrentClient::scheduleUploads() // random peer to allow it to compete for a position among the // downloaders. (This is known as an "optimistic unchoke".) if (!allClients.isEmpty()) { - PeerWireClient *client = allClients[qrand() % allClients.size()]; + PeerWireClient *client = allClients[QRandomGenerator::global()->bounded(allClients.size())]; if (client->peerWireState() & PeerWireClient::ChokingPeer) client->unchokePeer(); } @@ -1189,7 +1189,7 @@ void TorrentClient::schedulePieceForClient(PeerWireClient *client) piece = d->payloads.value(client); if (!piece) { QList values = d->pendingPieces.values(); - piece = values.value(qrand() % values.size()); + piece = values.value(QRandomGenerator::global()->bounded(values.size())); piece->inProgress = true; d->payloads.insert(client, piece); } @@ -1246,14 +1246,14 @@ void TorrentClient::schedulePieceForClient(PeerWireClient *client) ++it; } if (!partialPieces.isEmpty()) - piece = partialPieces.value(qrand() % partialPieces.size()); + piece = partialPieces.value(QRandomGenerator::global()->bounded(partialPieces.size())); if (!piece) { // Pick a random piece 3 out of 4 times; otherwise, pick either // one of the most common or the least common pieces available, // depending on the state we're in. int pieceIndex = 0; - if (d->state == WarmingUp || (qrand() & 4) == 0) { + if (d->state == WarmingUp || (QRandomGenerator::global()->generate() & 4) == 0) { int *occurrences = new int[d->pieceCount]; memset(occurrences, 0, d->pieceCount * sizeof(int)); @@ -1293,7 +1293,7 @@ void TorrentClient::schedulePieceForClient(PeerWireClient *client) } // Select one piece randomly - pieceIndex = piecesReadyForDownload.at(qrand() % piecesReadyForDownload.size()); + pieceIndex = piecesReadyForDownload.at(QRandomGenerator::global()->bounded(piecesReadyForDownload.size())); delete [] occurrences; } else { // Make up a list of available piece indices, and pick @@ -1304,7 +1304,7 @@ void TorrentClient::schedulePieceForClient(PeerWireClient *client) if (incompletePiecesAvailableToClient.testBit(i)) values << i; } - pieceIndex = values.at(qrand() % values.size()); + pieceIndex = values.at(QRandomGenerator::global()->bounded(values.size())); } // Create a new TorrentPiece and fill in all initial @@ -1396,8 +1396,8 @@ int TorrentClient::requestBlocks(PeerWireClient *client, TorrentPiece *piece, in // speedup comes from an increased chance of receiving // different blocks from the different peers. for (int i = 0; i < bits.size(); ++i) { - int a = qrand() % bits.size(); - int b = qrand() % bits.size(); + int a = QRandomGenerator::global()->bounded(bits.size()); + int b = QRandomGenerator::global()->bounded(bits.size()); int tmp = bits[a]; bits[a] = bits[b]; bits[b] = tmp; diff --git a/examples/opengl/hellowindow/hellowindow.cpp b/examples/opengl/hellowindow/hellowindow.cpp index 048190d766..a978e19b79 100644 --- a/examples/opengl/hellowindow/hellowindow.cpp +++ b/examples/opengl/hellowindow/hellowindow.cpp @@ -52,6 +52,7 @@ #include #include +#include #include Renderer::Renderer(const QSurfaceFormat &format, Renderer *share, QScreen *screen) @@ -68,9 +69,9 @@ Renderer::Renderer(const QSurfaceFormat &format, Renderer *share, QScreen *scree m_context->create(); m_backgroundColor = QColor::fromRgbF(0.1f, 0.1f, 0.2f, 1.0f); - m_backgroundColor.setRed(qrand() % 64); - m_backgroundColor.setGreen(qrand() % 128); - m_backgroundColor.setBlue(qrand() % 256); + m_backgroundColor.setRed(QRandomGenerator::global()->bounded(64)); + m_backgroundColor.setGreen(QRandomGenerator::global()->bounded(128)); + m_backgroundColor.setBlue(QRandomGenerator::global()->bounded(256)); } HelloWindow::HelloWindow(const QSharedPointer &renderer, QScreen *screen) diff --git a/examples/opengl/legacy/overpainting/bubble.cpp b/examples/opengl/legacy/overpainting/bubble.cpp index afc50117d0..352e359cf9 100644 --- a/examples/opengl/legacy/overpainting/bubble.cpp +++ b/examples/opengl/legacy/overpainting/bubble.cpp @@ -50,6 +50,8 @@ #include "bubble.h" +#include + Bubble::Bubble(const QPointF &position, qreal radius, const QPointF &velocity) : position(position), vel(velocity), radius(radius) { @@ -80,10 +82,10 @@ void Bubble::drawBubble(QPainter *painter) QColor Bubble::randomColor() { - int red = int(205 + 50.0*qrand()/(RAND_MAX+1.0)); - int green = int(205 + 50.0*qrand()/(RAND_MAX+1.0)); - int blue = int(205 + 50.0*qrand()/(RAND_MAX+1.0)); - int alpha = int(91 + 100.0*qrand()/(RAND_MAX+1.0)); + int red = int(205 + QRandomGenerator::global()->bounded(50)); + int green = int(205 + QRandomGenerator::global()->bounded(50)); + int blue = int(205 + QRandomGenerator::global()->bounded(50)); + int alpha = int(91 + QRandomGenerator::global()->bounded(100)); return QColor(red, green, blue, alpha); } diff --git a/examples/opengl/legacy/overpainting/glwidget.cpp b/examples/opengl/legacy/overpainting/glwidget.cpp index 7e9f4a5beb..1ec7bd731c 100644 --- a/examples/opengl/legacy/overpainting/glwidget.cpp +++ b/examples/opengl/legacy/overpainting/glwidget.cpp @@ -53,6 +53,7 @@ #include "glwidget.h" #include +#include #include #include @@ -67,7 +68,6 @@ GLWidget::GLWidget(QWidget *parent) : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) { QTime midnight(0, 0, 0); - qsrand(midnight.secsTo(QTime::currentTime())); logo = 0; xRot = 0; @@ -234,11 +234,11 @@ QSize GLWidget::sizeHint() const void GLWidget::createBubbles(int number) { for (int i = 0; i < number; ++i) { - QPointF position(width()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))), - height()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0)))); - qreal radius = qMin(width(), height())*(0.0125 + 0.0875*qrand()/(RAND_MAX+1.0)); - QPointF velocity(width()*0.0125*(-0.5 + qrand()/(RAND_MAX+1.0)), - height()*0.0125*(-0.5 + qrand()/(RAND_MAX+1.0))); + QPointF position(width()*(0.1 + QRandomGenerator::global()->bounded(0.8)), + height()*(0.1 + QRandomGenerator::global()->bounded(0.8))); + qreal radius = qMin(width(), height())*(0.0125 + QRandomGenerator::global()->bounded(0.0875)); + QPointF velocity(width()*0.0125*(-0.5 + QRandomGenerator::global()->bounded(1.0)), + height()*0.0125*(-0.5 + QRandomGenerator::global()->bounded(1.0))); bubbles.append(new Bubble(position, radius, velocity)); } diff --git a/examples/opengl/qopenglwidget/bubble.cpp b/examples/opengl/qopenglwidget/bubble.cpp index adf5742f6a..dbaf460f6f 100644 --- a/examples/opengl/qopenglwidget/bubble.cpp +++ b/examples/opengl/qopenglwidget/bubble.cpp @@ -109,10 +109,10 @@ void Bubble::drawBubble(QPainter *painter) QColor Bubble::randomColor() { - int red = int(185 + 70.0*qrand()/(RAND_MAX+1.0)); - int green = int(185 + 70.0*qrand()/(RAND_MAX+1.0)); - int blue = int(205 + 50.0*qrand()/(RAND_MAX+1.0)); - int alpha = int(91 + 100.0*qrand()/(RAND_MAX+1.0)); + int red = int(185 + QRandomGenerator::global()->bounded(70)); + int green = int(185 + QRandomGenerator::global()->bounded(70)); + int blue = int(205 + QRandomGenerator::global()->bounded(50)); + int alpha = int(91 + QRandomGenerator::global()->bounded(100)); return QColor(red, green, blue, alpha); } diff --git a/examples/opengl/qopenglwidget/glwidget.cpp b/examples/opengl/qopenglwidget/glwidget.cpp index 40a1258dd5..3fe919f94b 100644 --- a/examples/opengl/qopenglwidget/glwidget.cpp +++ b/examples/opengl/qopenglwidget/glwidget.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -420,11 +421,11 @@ void GLWidget::paintGL() void GLWidget::createBubbles(int number) { for (int i = 0; i < number; ++i) { - QPointF position(width()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))), - height()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0)))); - qreal radius = qMin(width(), height())*(0.0175 + 0.0875*qrand()/(RAND_MAX+1.0)); - QPointF velocity(width()*0.0175*(-0.5 + qrand()/(RAND_MAX+1.0)), - height()*0.0175*(-0.5 + qrand()/(RAND_MAX+1.0))); + QPointF position(width()*(0.1 + QRandomGenerator::global()->bounded(0.8)), + height()*(0.1 + QRandomGenerator::global()->bounded(0.8))); + qreal radius = qMin(width(), height())*(0.0175 + QRandomGenerator::global()->bounded(0.0875)); + QPointF velocity(width()*0.0175*(-0.5 + QRandomGenerator::global()->bounded(1.0)), + height()*0.0175*(-0.5 + QRandomGenerator::global()->bounded(1.0))); m_bubbles.append(new Bubble(position, radius, velocity)); } diff --git a/examples/opengl/qopenglwidget/mainwindow.cpp b/examples/opengl/qopenglwidget/mainwindow.cpp index 1bb2aa2bf0..4bd123628f 100644 --- a/examples/opengl/qopenglwidget/mainwindow.cpp +++ b/examples/opengl/qopenglwidget/mainwindow.cpp @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -155,7 +156,9 @@ void MainWindow::addNew() { if (m_nextY == 4) return; - GLWidget *w = new GLWidget(this, false, qRgb(qrand() % 256, qrand() % 256, qrand() % 256)); + GLWidget *w = new GLWidget(this, false, qRgb(QRandomGenerator::global()->bounded(256), + QRandomGenerator::global()->bounded(256), + QRandomGenerator::global()->bounded(256))); m_glWidgets << w; connect(m_timer, &QTimer::timeout, w, QOverload<>::of(&QWidget::update)); m_layout->addWidget(w, m_nextY, m_nextX, 1, 1); diff --git a/examples/touch/pinchzoom/main.cpp b/examples/touch/pinchzoom/main.cpp index 67099618c7..938432600f 100644 --- a/examples/touch/pinchzoom/main.cpp +++ b/examples/touch/pinchzoom/main.cpp @@ -61,7 +61,6 @@ static const int MouseCount = 7; int main(int argc, char **argv) { QApplication app(argc, argv); - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); //! [0] //! [1] diff --git a/examples/touch/pinchzoom/mouse.cpp b/examples/touch/pinchzoom/mouse.cpp index 7f8c238e6f..1e6814be13 100644 --- a/examples/touch/pinchzoom/mouse.cpp +++ b/examples/touch/pinchzoom/mouse.cpp @@ -52,6 +52,7 @@ #include #include +#include #include #include @@ -70,9 +71,9 @@ static qreal normalizeAngle(qreal angle) //! [0] Mouse::Mouse() : angle(0), speed(0), mouseEyeDirection(0), - color(qrand() % 256, qrand() % 256, qrand() % 256) + color(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256)) { - setTransform(QTransform().rotate(qrand() % (360 * 16)), true); + setTransform(QTransform().rotate(QRandomGenerator::global()->bounded(360 * 16)), true); startTimer(1000 / 33); } //! [0] @@ -184,16 +185,16 @@ void Mouse::timerEvent(QTimerEvent *) // Add some random movement //! [10] - if (dangerMice.size() > 1 && (qrand() % 10) == 0) { - if (qrand() % 1) - angle += (qrand() % 100) / 500.0; + if (dangerMice.size() > 1 && QRandomGenerator::global()->bounded(10) == 0) { + if (QRandomGenerator::global()->bounded(1)) + angle += QRandomGenerator::global()->bounded(1 / 500.0); else - angle -= (qrand() % 100) / 500.0; + angle -= QRandomGenerator::global()->bounded(1 / 500.0); } //! [10] //! [11] - speed += (-50 + qrand() % 100) / 100.0; + speed += (-50 + QRandomGenerator::global()->bounded(100)) / 100.0; qreal dx = ::sin(angle) * 10; mouseEyeDirection = (qAbs(dx / 5) < 1) ? 0 : dx / 5; diff --git a/examples/widgets/animation/animatedtiles/main.cpp b/examples/widgets/animation/animatedtiles/main.cpp index 0511fe8162..89b5b67f8a 100644 --- a/examples/widgets/animation/animatedtiles/main.cpp +++ b/examples/widgets/animation/animatedtiles/main.cpp @@ -50,6 +50,7 @@ #include #include +#include #include class Pixmap : public QObject, public QGraphicsPixmapItem @@ -202,8 +203,8 @@ int main(int argc, char **argv) // Random randomState->assignProperty(item, "pos", - QPointF(-250 + qrand() % 500, - -250 + qrand() % 500)); + QPointF(-250 + QRandomGenerator::global()->bounded(500), + -250 + QRandomGenerator::global()->bounded(500))); // Tiled tiledState->assignProperty(item, "pos", diff --git a/examples/widgets/animation/moveblocks/main.cpp b/examples/widgets/animation/moveblocks/main.cpp index a9b95808a5..6d17696108 100644 --- a/examples/widgets/animation/moveblocks/main.cpp +++ b/examples/widgets/animation/moveblocks/main.cpp @@ -125,7 +125,7 @@ public: void onEntry(QEvent *) override { int n; - while ((n = (qrand() % m_stateCount + 1)) == m_lastIndex) + while ((n = QRandomGenerator::global()->bounded(m_stateCount) + 1) == m_lastIndex) { } m_lastIndex = n; machine()->postEvent(new StateSwitchEvent(n)); @@ -323,8 +323,6 @@ int main(int argc, char **argv) window.resize(300, 300); window.show(); - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); - return app.exec(); } diff --git a/examples/widgets/animation/stickman/lifecycle.cpp b/examples/widgets/animation/stickman/lifecycle.cpp index 253af22b2d..dbe9a299b4 100644 --- a/examples/widgets/animation/stickman/lifecycle.cpp +++ b/examples/widgets/animation/stickman/lifecycle.cpp @@ -91,13 +91,12 @@ public: : QEventTransition(this, QEvent::Timer) { setTargetState(target); - qsrand((uint)QDateTime::currentSecsSinceEpoch()); startTimer(1000); } bool eventTest(QEvent *e) override { - return QEventTransition::eventTest(e) && ((qrand() % 50) == 0); + return QEventTransition::eventTest(e) && QRandomGenerator::global()->bounded(50) == 0; } }; //! [4] diff --git a/examples/widgets/animation/sub-attaq/main.cpp b/examples/widgets/animation/sub-attaq/main.cpp index f65ca7be18..9b28d8c40f 100644 --- a/examples/widgets/animation/sub-attaq/main.cpp +++ b/examples/widgets/animation/sub-attaq/main.cpp @@ -57,8 +57,6 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); Q_INIT_RESOURCE(subattaq); - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); - MainWindow w; w.show(); diff --git a/examples/widgets/animation/sub-attaq/states.cpp b/examples/widgets/animation/sub-attaq/states.cpp index 21cff048e7..e19704db7b 100644 --- a/examples/widgets/animation/sub-attaq/states.cpp +++ b/examples/widgets/animation/sub-attaq/states.cpp @@ -64,6 +64,7 @@ #include #include #include +#include PlayState::PlayState(GraphicsScene *scene, QState *parent) : QState(parent), @@ -193,12 +194,12 @@ void LevelState::initializeLevel() for (int j = 0; j < subContent.second; ++j ) { SubMarine *sub = new SubMarine(submarineDesc.type, submarineDesc.name, submarineDesc.points); scene->addItem(sub); - int random = (qrand() % 15 + 1); + int random = QRandomGenerator::global()->bounded(15) + 1; qreal x = random == 13 || random == 5 ? 0 : scene->width() - sub->size().width(); - qreal y = scene->height() -(qrand() % 150 + 1) - sub->size().height(); + qreal y = scene->height() -(QRandomGenerator::global()->bounded(150) + 1) - sub->size().height(); sub->setPos(x,y); sub->setCurrentDirection(x == 0 ? SubMarine::Right : SubMarine::Left); - sub->setCurrentSpeed(qrand() % 3 + 1); + sub->setCurrentSpeed(QRandomGenerator::global()->bounded(3) + 1); } } } diff --git a/examples/widgets/animation/sub-attaq/submarine_p.h b/examples/widgets/animation/sub-attaq/submarine_p.h index b8d5532962..698b4b494f 100644 --- a/examples/widgets/animation/sub-attaq/submarine_p.h +++ b/examples/widgets/animation/sub-attaq/submarine_p.h @@ -69,6 +69,7 @@ //Qt #include +#include #include //This state is describing when the boat is moving right @@ -88,8 +89,8 @@ public: protected slots: void onAnimationMovementValueChanged(const QVariant &) { - if (qrand() % 200 + 1 == 3) - submarine->launchTorpedo(qrand() % 3 + 1); + if (QRandomGenerator::global()->bounded(200) + 1 == 3) + submarine->launchTorpedo(QRandomGenerator::global()->bounded(3) + 1); } protected: diff --git a/examples/widgets/doc/src/collidingmice-example.qdoc b/examples/widgets/doc/src/collidingmice-example.qdoc index 02417ba521..535057bb6a 100644 --- a/examples/widgets/doc/src/collidingmice-example.qdoc +++ b/examples/widgets/doc/src/collidingmice-example.qdoc @@ -80,8 +80,7 @@ \snippet graphicsview/collidingmice/mouse.cpp 0 To calculate the various components of the mouse's color, we use - the global qrand() function which is a thread-safe version of the - standard C++ rand() function. + \l QRandomGenerator. Then we call the \l {QGraphicsItem::setRotation()}{setRotation()} function inherited from QGraphicsItem. Items live in their own local @@ -178,12 +177,7 @@ \snippet graphicsview/collidingmice/main.cpp 0 - First, we create an application object and call the global - qsrand() function to specify the seed used to generate a new - random number sequence of pseudo random integers with the - previously mentioned qrand() function. - - Then it is time to create the scene: + First, we create an application object and create the scene: \snippet graphicsview/collidingmice/main.cpp 1 diff --git a/examples/widgets/doc/src/dragdroprobot.qdoc b/examples/widgets/doc/src/dragdroprobot.qdoc index ac221ec5f9..f74b898e1b 100644 --- a/examples/widgets/doc/src/dragdroprobot.qdoc +++ b/examples/widgets/doc/src/dragdroprobot.qdoc @@ -257,7 +257,7 @@ \snippet graphicsview/dragdroprobot/coloritem.cpp 0 \c ColorItem's constructor assigns an opaque random color to its color - member by making use of qrand(). For improved usability, it assigns a + member by making use of \l QRandomGenerator. For improved usability, it assigns a tooltip that provides a useful hint to the user, and it also sets a suitable cursor. This ensures that the cursor will chance to Qt::OpenHandCursor when the mouse pointer hovers over the item. diff --git a/examples/widgets/doc/src/elasticnodes.qdoc b/examples/widgets/doc/src/elasticnodes.qdoc index 09ac891b24..65e1195121 100644 --- a/examples/widgets/doc/src/elasticnodes.qdoc +++ b/examples/widgets/doc/src/elasticnodes.qdoc @@ -424,9 +424,8 @@ \section1 The main() Function In contrast to the complexity of the rest of this example, the \c main() - function is very simple: We create a QApplication instance, seed the - randomizer using qsrand(), and then create and show an instance of \c - GraphWidget. Because all nodes in the grid are moved initially, the \c - GraphWidget timer will start immediately after control has returned to the - event loop. + function is very simple: We create a QApplication instance, then create and + show an instance of \c GraphWidget. Because all nodes in the grid are moved + initially, the \c GraphWidget timer will start immediately after control + has returned to the event loop. */ diff --git a/examples/widgets/draganddrop/puzzle/mainwindow.cpp b/examples/widgets/draganddrop/puzzle/mainwindow.cpp index 1914519c68..98a7cd4265 100644 --- a/examples/widgets/draganddrop/puzzle/mainwindow.cpp +++ b/examples/widgets/draganddrop/puzzle/mainwindow.cpp @@ -122,10 +122,8 @@ void MainWindow::setupPuzzle() } } - qsrand(QCursor::pos().x() ^ QCursor::pos().y()); - for (int i = 0; i < piecesList->count(); ++i) { - if (int(2.0*qrand()/(RAND_MAX+1.0)) == 1) { + if (QRandomGenerator::global()->bounded(2) == 1) { QListWidgetItem *item = piecesList->takeItem(i); piecesList->insertItem(0, item); } diff --git a/examples/widgets/graphicsview/boxes/qtbox.cpp b/examples/widgets/graphicsview/boxes/qtbox.cpp index 9a19985fac..3a184dd0b6 100644 --- a/examples/widgets/graphicsview/boxes/qtbox.cpp +++ b/examples/widgets/graphicsview/boxes/qtbox.cpp @@ -414,7 +414,7 @@ void QtBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWi CircleItem::CircleItem(int size, int x, int y) : ItemBase(size, x, y) { - m_color = QColor::fromHsv(rand() % 360, 255, 255); + m_color = QColor::fromHsv(QRandomGenerator::global()->bounded(360), 255, 255); } void CircleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) diff --git a/examples/widgets/graphicsview/boxes/scene.cpp b/examples/widgets/graphicsview/boxes/scene.cpp index 31b9553c75..f51cad99ac 100644 --- a/examples/widgets/graphicsview/boxes/scene.cpp +++ b/examples/widgets/graphicsview/boxes/scene.cpp @@ -50,6 +50,7 @@ #include #include "scene.h" +#include #include #include #include @@ -1072,13 +1073,16 @@ void Scene::newItem(ItemDialog::ItemType type) QSize size = sceneRect().size().toSize(); switch (type) { case ItemDialog::QtBoxItem: - addItem(new QtBox(64, rand() % (size.width() - 64) + 32, rand() % (size.height() - 64) + 32)); + addItem(new QtBox(64, QRandomGenerator::global()->bounded(size.width() - 64) + 32, + QRandomGenerator::global()->bounded(size.height() - 64) + 32)); break; case ItemDialog::CircleItem: - addItem(new CircleItem(64, rand() % (size.width() - 64) + 32, rand() % (size.height() - 64) + 32)); + addItem(new CircleItem(64, QRandomGenerator::global()->bounded(size.width() - 64) + 32, + QRandomGenerator::global()->bounded(size.height() - 64) + 32)); break; case ItemDialog::SquareItem: - addItem(new SquareItem(64, rand() % (size.width() - 64) + 32, rand() % (size.height() - 64) + 32)); + addItem(new SquareItem(64, QRandomGenerator::global()->bounded(size.width() - 64) + 32, + QRandomGenerator::global()->bounded(size.height() - 64) + 32)); break; default: break; diff --git a/examples/widgets/graphicsview/collidingmice/main.cpp b/examples/widgets/graphicsview/collidingmice/main.cpp index a0659b9bc1..91aee70b86 100644 --- a/examples/widgets/graphicsview/collidingmice/main.cpp +++ b/examples/widgets/graphicsview/collidingmice/main.cpp @@ -60,7 +60,6 @@ static const int MouseCount = 7; int main(int argc, char **argv) { QApplication app(argc, argv); - qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime())); //! [0] //! [1] diff --git a/examples/widgets/graphicsview/collidingmice/mouse.cpp b/examples/widgets/graphicsview/collidingmice/mouse.cpp index 298e4aae64..14f887f6e3 100644 --- a/examples/widgets/graphicsview/collidingmice/mouse.cpp +++ b/examples/widgets/graphicsview/collidingmice/mouse.cpp @@ -52,6 +52,7 @@ #include #include +#include #include #include @@ -70,9 +71,9 @@ static qreal normalizeAngle(qreal angle) //! [0] Mouse::Mouse() : angle(0), speed(0), mouseEyeDirection(0), - color(qrand() % 256, qrand() % 256, qrand() % 256) + color(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256)) { - setRotation(qrand() % (360 * 16)); + setRotation(QRandomGenerator::global()->bounded(360 * 16)); } //! [0] @@ -185,16 +186,16 @@ void Mouse::advance(int step) // Add some random movement //! [10] - if (dangerMice.size() > 1 && (qrand() % 10) == 0) { - if (qrand() % 1) - angle += (qrand() % 100) / 500.0; + if (dangerMice.size() > 1 && QRandomGenerator::global()->bounded(10) == 0) { + if (QRandomGenerator::global()->bounded(1)) + angle += QRandomGenerator::global()->bounded(1 / 500.0); else - angle -= (qrand() % 100) / 500.0; + angle -= QRandomGenerator::global()->bounded(1 / 500.0); } //! [10] //! [11] - speed += (-50 + qrand() % 100) / 100.0; + speed += (-50 + QRandomGenerator::global()->bounded(100)) / 100.0; qreal dx = ::sin(angle) * 10; mouseEyeDirection = (qAbs(dx / 5) < 1) ? 0 : dx / 5; diff --git a/examples/widgets/graphicsview/dragdroprobot/coloritem.cpp b/examples/widgets/graphicsview/dragdroprobot/coloritem.cpp index 64a715d31f..262e18a317 100644 --- a/examples/widgets/graphicsview/dragdroprobot/coloritem.cpp +++ b/examples/widgets/graphicsview/dragdroprobot/coloritem.cpp @@ -54,7 +54,7 @@ //! [0] ColorItem::ColorItem() - : color(qrand() % 256, qrand() % 256, qrand() % 256) + : color(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256)) { setToolTip(QString("QColor(%1, %2, %3)\n%4") .arg(color.red()).arg(color.green()).arg(color.blue()) @@ -107,7 +107,7 @@ void ColorItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) //! [6] static int n = 0; - if (n++ > 2 && (qrand() % 3) == 0) { + if (n++ > 2 && QRandomGenerator::global()->bounded(3) == 0) { QImage image(":/images/head.png"); mime->setImageData(image); diff --git a/examples/widgets/graphicsview/dragdroprobot/main.cpp b/examples/widgets/graphicsview/dragdroprobot/main.cpp index 20cec92d26..045e184569 100644 --- a/examples/widgets/graphicsview/dragdroprobot/main.cpp +++ b/examples/widgets/graphicsview/dragdroprobot/main.cpp @@ -73,7 +73,6 @@ int main(int argc, char **argv) { QApplication app(argc, argv); - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); //! [0] //! [1] QGraphicsScene scene(-200, -200, 400, 400); diff --git a/examples/widgets/graphicsview/elasticnodes/graphwidget.cpp b/examples/widgets/graphicsview/elasticnodes/graphwidget.cpp index 844c8f8aac..4259aab803 100644 --- a/examples/widgets/graphicsview/elasticnodes/graphwidget.cpp +++ b/examples/widgets/graphicsview/elasticnodes/graphwidget.cpp @@ -55,6 +55,7 @@ #include #include +#include //! [0] GraphWidget::GraphWidget(QWidget *parent) @@ -247,7 +248,7 @@ void GraphWidget::shuffle() { foreach (QGraphicsItem *item, scene()->items()) { if (qgraphicsitem_cast(item)) - item->setPos(-150 + qrand() % 300, -150 + qrand() % 300); + item->setPos(-150 + QRandomGenerator::global()->bounded(300), -150 + QRandomGenerator::global()->bounded(300)); } } diff --git a/examples/widgets/graphicsview/elasticnodes/main.cpp b/examples/widgets/graphicsview/elasticnodes/main.cpp index 75cc4b0f69..1e372a9f6d 100644 --- a/examples/widgets/graphicsview/elasticnodes/main.cpp +++ b/examples/widgets/graphicsview/elasticnodes/main.cpp @@ -57,7 +57,6 @@ int main(int argc, char **argv) { QApplication app(argc, argv); - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); GraphWidget *widget = new GraphWidget; diff --git a/examples/widgets/itemviews/puzzle/mainwindow.cpp b/examples/widgets/itemviews/puzzle/mainwindow.cpp index 8ee5cf659e..d598dc9017 100644 --- a/examples/widgets/itemviews/puzzle/mainwindow.cpp +++ b/examples/widgets/itemviews/puzzle/mainwindow.cpp @@ -114,8 +114,6 @@ void MainWindow::setupPuzzle() (puzzleImage.height() - size) / 2, size, size).scaled(puzzleWidget->imageSize(), puzzleWidget->imageSize(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - qsrand(QCursor::pos().x() ^ QCursor::pos().y()); - model->addPieces(puzzleImage); puzzleWidget->clear(); } diff --git a/examples/widgets/itemviews/puzzle/piecesmodel.cpp b/examples/widgets/itemviews/puzzle/piecesmodel.cpp index 0fbf0cdcc2..f0649d3776 100644 --- a/examples/widgets/itemviews/puzzle/piecesmodel.cpp +++ b/examples/widgets/itemviews/puzzle/piecesmodel.cpp @@ -52,6 +52,7 @@ #include #include +#include PiecesModel::PiecesModel(int pieceSize, QObject *parent) : QAbstractListModel(parent), m_PieceSize(pieceSize) @@ -77,7 +78,7 @@ QVariant PiecesModel::data(const QModelIndex &index, int role) const void PiecesModel::addPiece(const QPixmap &pixmap, const QPoint &location) { int row; - if (int(2.0 * qrand() / (RAND_MAX + 1.0)) == 1) + if (QRandomGenerator::global()->bounded(2) == 1) row = 0; else row = pixmaps.size(); diff --git a/examples/widgets/mainwindows/mainwindow/toolbar.cpp b/examples/widgets/mainwindows/mainwindow/toolbar.cpp index 97152a64a3..814cfc7f4d 100644 --- a/examples/widgets/mainwindows/mainwindow/toolbar.cpp +++ b/examples/widgets/mainwindows/mainwindow/toolbar.cpp @@ -50,6 +50,8 @@ #include "toolbar.h" +#include + #include #include #include @@ -257,7 +259,7 @@ void ToolBar::randomize() QList randomized; QList actions = this->actions(); while (!actions.isEmpty()) { - QAction *action = actions.takeAt(rand() % actions.size()); + QAction *action = actions.takeAt(QRandomGenerator::global()->bounded(actions.size())); randomized.append(action); } clear(); diff --git a/examples/widgets/statemachine/rogue/window.cpp b/examples/widgets/statemachine/rogue/window.cpp index 428d4c3af6..3515138382 100644 --- a/examples/widgets/statemachine/rogue/window.cpp +++ b/examples/widgets/statemachine/rogue/window.cpp @@ -248,11 +248,9 @@ void Window::movePlayer(Direction direction) void Window::setupMap() { - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); - for (int x = 0; x < WIDTH; ++x) for (int y = 0; y < HEIGHT; ++y) { - if (x == 0 || x == WIDTH - 1 || y == 0 || y == HEIGHT - 1 || qrand() % 40 == 0) + if (x == 0 || x == WIDTH - 1 || y == 0 || y == HEIGHT - 1 || QRandomGenerator::global()->bounded(40) == 0) map[x][y] = '#'; else map[x][y] = '.'; diff --git a/examples/widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp b/examples/widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp index 740d007d44..92620ddd8c 100644 --- a/examples/widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp +++ b/examples/widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp @@ -101,7 +101,7 @@ QRect BasicToolsPlugin::mouseMove(const QString &brush, QPainter &painter, thickness, thickness); } } else if (brush == tr("Random Letters")) { - QChar ch('A' + (qrand() % 26)); + QChar ch(QRandomGenerator::global()->bounded('A', 'Z' + 1)); QFont biggerFont = painter.font(); biggerFont.setBold(true); diff --git a/examples/widgets/tools/undo/mainwindow.cpp b/examples/widgets/tools/undo/mainwindow.cpp index aa570caa80..5976163f3f 100644 --- a/examples/widgets/tools/undo/mainwindow.cpp +++ b/examples/widgets/tools/undo/mainwindow.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include "document.h" @@ -321,7 +322,7 @@ void MainWindow::newDocument() static QColor randomColor() { - int r = (int) (3.0*(rand()/(RAND_MAX + 1.0))); + int r = QRandomGenerator::global()->bounded(3); switch (r) { case 0: return Qt::red; @@ -337,10 +338,10 @@ static QRect randomRect(const QSize &s) { QSize min = Shape::minSize; - int left = (int) ((0.0 + s.width() - min.width())*(rand()/(RAND_MAX + 1.0))); - int top = (int) ((0.0 + s.height() - min.height())*(rand()/(RAND_MAX + 1.0))); - int width = (int) ((0.0 + s.width() - left - min.width())*(rand()/(RAND_MAX + 1.0))) + min.width(); - int height = (int) ((0.0 + s.height() - top - min.height())*(rand()/(RAND_MAX + 1.0))) + min.height(); + int left = (int) ((0.0 + s.width() - min.width())*(QRandomGenerator::global()->bounded(1.0))); + int top = (int) ((0.0 + s.height() - min.height())*(QRandomGenerator::global()->bounded(1.0))); + int width = (int) ((0.0 + s.width() - left - min.width())*(QRandomGenerator::global()->bounded(1.0))) + min.width(); + int height = (int) ((0.0 + s.height() - top - min.height())*(QRandomGenerator::global()->bounded(1.0))) + min.height(); return QRect(left, top, width, height); } diff --git a/examples/widgets/tools/undoframework/diagramitem.cpp b/examples/widgets/tools/undoframework/diagramitem.cpp index 754baa2377..723645c9b2 100644 --- a/examples/widgets/tools/undoframework/diagramitem.cpp +++ b/examples/widgets/tools/undoframework/diagramitem.cpp @@ -65,8 +65,7 @@ DiagramItem::DiagramItem(DiagramType diagramType, QGraphicsItem *item) setPolygon(trianglePolygon); } - QColor color(static_cast(qrand()) % 256, - static_cast(qrand()) % 256, static_cast(qrand()) % 256); + QColor color(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256)); QBrush brush(color); setBrush(brush); setFlag(QGraphicsItem::ItemIsSelectable); diff --git a/examples/widgets/widgets/tetrix/main.cpp b/examples/widgets/widgets/tetrix/main.cpp index 886e94de7c..2698190e76 100644 --- a/examples/widgets/widgets/tetrix/main.cpp +++ b/examples/widgets/widgets/tetrix/main.cpp @@ -59,6 +59,5 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); TetrixWindow window; window.show(); - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); return app.exec(); } diff --git a/examples/widgets/widgets/tetrix/tetrixpiece.cpp b/examples/widgets/widgets/tetrix/tetrixpiece.cpp index 69e1733ac4..3d8fa86860 100644 --- a/examples/widgets/widgets/tetrix/tetrixpiece.cpp +++ b/examples/widgets/widgets/tetrix/tetrixpiece.cpp @@ -57,7 +57,7 @@ //! [0] void TetrixPiece::setRandomShape() { - setShape(TetrixShape(qrand() % 7 + 1)); + setShape(TetrixShape(QRandomGenerator::global()->bounded(7) + 1)); } //! [0] diff --git a/examples/widgets/widgets/tooltips/main.cpp b/examples/widgets/widgets/tooltips/main.cpp index 3c64a33a4c..8276b3dc8d 100644 --- a/examples/widgets/widgets/tooltips/main.cpp +++ b/examples/widgets/widgets/tooltips/main.cpp @@ -57,7 +57,6 @@ int main(int argc, char *argv[]) Q_INIT_RESOURCE(tooltips); QApplication app(argc, argv); - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); SortingBox sortingBox; sortingBox.show(); return app.exec(); diff --git a/examples/widgets/widgets/tooltips/sortingbox.cpp b/examples/widgets/widgets/tooltips/sortingbox.cpp index c15fdcf95b..4769a30c64 100644 --- a/examples/widgets/widgets/tooltips/sortingbox.cpp +++ b/examples/widgets/widgets/tooltips/sortingbox.cpp @@ -292,7 +292,7 @@ QPoint SortingBox::initialItemPosition(const QPainterPath &path) //! [24] QPoint SortingBox::randomItemPosition() { - return QPoint(qrand() % (width() - 120), qrand() % (height() - 120)); + return QPoint(QRandomGenerator::global()->bounded(width() - 120), QRandomGenerator::global()->bounded(height() - 120)); } //! [24] @@ -306,6 +306,6 @@ QColor SortingBox::initialItemColor() //! [26] QColor SortingBox::randomItemColor() { - return QColor::fromHsv(qrand() % 256, 255, 190); + return QColor::fromHsv(QRandomGenerator::global()->bounded(256), 255, 190); } //! [26] diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 2bbc4eddd0..8da6d6b16e 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2017 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -99,10 +100,8 @@ static void qt_create_pipe(Q_PIPE *pipe, bool isInputPipe) wchar_t pipeName[256]; unsigned int attempts = 1000; forever { - // ### The user must make sure to call qsrand() to make the pipe names less predictable. - // ### Replace the call to qrand() with a secure version, once we have it in Qt. _snwprintf(pipeName, sizeof(pipeName) / sizeof(pipeName[0]), - L"\\\\.\\pipe\\qt-%X", qrand()); + L"\\\\.\\pipe\\qt-%X", QRandomGenerator::global()->generate()); DWORD dwOpenMode = FILE_FLAG_OVERLAPPED; DWORD dwOutputBufferSize = 0; diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 5865d9e19a..b8d3e859cf 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -165,7 +165,7 @@ QFileSystemEntry::NativePath QTemporaryFileName::generateNext() Char *rIter = placeholderEnd; while (rIter != placeholderStart) { - quint32 rnd = QRandomGenerator::generate(); + quint32 rnd = QRandomGenerator::global()->generate(); auto applyOne = [&]() { quint32 v = rnd & ((1 << BitsPerCharacter) - 1); rnd >>= BitsPerCharacter; diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp index de32327071..d694352fc1 100644 --- a/src/gui/image/qpixmap_blitter.cpp +++ b/src/gui/image/qpixmap_blitter.cpp @@ -41,6 +41,7 @@ #include #include +#include #include #include @@ -252,7 +253,7 @@ QImage *QBlittablePlatformPixmap::overlay() m_rasterOverlay->size() != QSize(w,h)){ m_rasterOverlay = new QImage(w,h,QImage::Format_ARGB32_Premultiplied); m_rasterOverlay->fill(0x00000000); - uint color = (qrand() % 11)+7; + uint color = QRandomGenerator::global()->bounded(11)+7; m_overlayColor = QColor(Qt::GlobalColor(color)); m_overlayColor.setAlpha(0x88); diff --git a/src/gui/opengl/qopenglgradientcache.cpp b/src/gui/opengl/qopenglgradientcache.cpp index 58dcbed50a..3aa4c0d2e6 100644 --- a/src/gui/opengl/qopenglgradientcache.cpp +++ b/src/gui/opengl/qopenglgradientcache.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include "qopenglfunctions.h" #include "qopenglextensions_p.h" @@ -137,7 +138,7 @@ GLuint QOpenGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient { QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); if (cache.size() == maxCacheSize()) { - int elem_to_remove = qrand() % maxCacheSize(); + int elem_to_remove = QRandomGenerator::global()->bounded(maxCacheSize()); quint64 key = cache.keys()[elem_to_remove]; // need to call glDeleteTextures on each removed cache entry: diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 68554c6579..d0d948bbb7 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -50,6 +50,7 @@ #include #include #include +#include // #include // #include @@ -4229,7 +4230,7 @@ protected: QSharedPointer addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) { if (cache.size() == maxCacheSize()) { // may remove more than 1, but OK - cache.erase(cache.begin() + (qrand() % maxCacheSize())); + cache.erase(cache.begin() + QRandomGenerator::global()->bounded(maxCacheSize())); } auto cache_entry = QSharedPointer::create(gradient.stops(), opacity, gradient.interpolationMode()); generateGradientColorTable(gradient, cache_entry->buffer64, paletteSize(), opacity); diff --git a/src/network/kernel/qdnslookup.cpp b/src/network/kernel/qdnslookup.cpp index 6203ba37b3..10ff35b72c 100644 --- a/src/network/kernel/qdnslookup.cpp +++ b/src/network/kernel/qdnslookup.cpp @@ -42,7 +42,7 @@ #include #include -#include +#include #include #include @@ -50,7 +50,6 @@ QT_BEGIN_NAMESPACE Q_GLOBAL_STATIC(QDnsLookupThreadPool, theDnsLookupThreadPool); -Q_GLOBAL_STATIC(QThreadStorage, theDnsLookupSeedStorage); static bool qt_qdnsmailexchangerecord_less_than(const QDnsMailExchangeRecord &r1, const QDnsMailExchangeRecord &r2) { @@ -85,7 +84,7 @@ static void qt_qdnsmailexchangerecord_sort(QList &record // Randomize the slice of records. while (!slice.isEmpty()) { - const unsigned int pos = qrand() % slice.size(); + const unsigned int pos = QRandomGenerator::global()->bounded(slice.size()); records[i++] = slice.takeAt(pos); } } @@ -134,7 +133,7 @@ static void qt_qdnsservicerecord_sort(QList &records) // Order the slice of records. while (!slice.isEmpty()) { - const unsigned int weightThreshold = qrand() % (sliceWeight + 1); + const unsigned int weightThreshold = QRandomGenerator::global()->bounded(sliceWeight + 1); unsigned int summedWeight = 0; for (int j = 0; j < slice.size(); ++j) { summedWeight += slice.at(j).weight(); @@ -1011,10 +1010,6 @@ void QDnsLookupRunnable::run() query(requestType, requestName, nameserver, &reply); // Sort results. - if (!theDnsLookupSeedStorage()->hasLocalData()) { - qsrand(QTime(0,0,0).msecsTo(QTime::currentTime()) ^ reinterpret_cast(this)); - theDnsLookupSeedStorage()->setLocalData(new bool(true)); - } qt_qdnsmailexchangerecord_sort(reply.mailExchangeRecords); qt_qdnsservicerecord_sort(reply.serviceRecords); diff --git a/src/opengl/gl2paintengineex/qglgradientcache.cpp b/src/opengl/gl2paintengineex/qglgradientcache.cpp index b4ca49514f..fc5e236ca6 100644 --- a/src/opengl/gl2paintengineex/qglgradientcache.cpp +++ b/src/opengl/gl2paintengineex/qglgradientcache.cpp @@ -41,6 +41,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -130,7 +131,7 @@ GLuint QGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient &gra { QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); if (cache.size() == maxCacheSize()) { - int elem_to_remove = qrand() % maxCacheSize(); + int elem_to_remove = QRandomGenerator::global()->bounded(maxCacheSize()); quint64 key = cache.keys()[elem_to_remove]; // need to call glDeleteTextures on each removed cache entry: diff --git a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp index 96656a6dff..2d7c0c2f64 100644 --- a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp +++ b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp @@ -2204,13 +2204,13 @@ InstanceCounter slowMap(const InstanceCounter &in) InstanceCounter fastMap(const InstanceCounter &in) { - QTest::qSleep(rand() % 2 + 1); + QTest::qSleep(QRandomGenerator::global()->bounded(2) + 1); return in; } void slowReduce(int &result, const InstanceCounter&) { - QTest::qSleep(rand() % 4 + 1); + QTest::qSleep(QRandomGenerator::global()->bounded(4) + 1); ++result; } diff --git a/tests/auto/corelib/io/largefile/tst_largefile.cpp b/tests/auto/corelib/io/largefile/tst_largefile.cpp index 5975303ca6..2d13e6166d 100644 --- a/tests/auto/corelib/io/largefile/tst_largefile.cpp +++ b/tests/auto/corelib/io/largefile/tst_largefile.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -174,8 +175,7 @@ static inline QByteArray generateDataBlock(int blockSize, QString text, qint64 u static qint64 counter = 0; - qint64 randomBits = ((qint64)qrand() << 32) - | ((qint64)qrand() & 0x00000000ffffffff); + qint64 randomBits = QRandomGenerator::global()->generate64(); appendRaw(block, randomBits); appendRaw(block, userBits); diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 3a52c684d0..5ecdd92228 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -2362,8 +2362,8 @@ void tst_QObject::testUserData() // Randomize the table a bit for (int i=0; i<100; ++i) { - int p1 = rand() % USER_DATA_COUNT; - int p2 = rand() % USER_DATA_COUNT; + int p1 = QRandomGenerator::global()->bounded(USER_DATA_COUNT); + int p2 = QRandomGenerator::global()->bounded(USER_DATA_COUNT); int tmp = user_data_ids[p1]; user_data_ids[p1] = user_data_ids[p2]; diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp index 8a46bc1c55..8883b6360f 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -115,7 +115,6 @@ Q_CONSTRUCTOR_FUNCTION(initializeLang) static QString seedAndTemplate() { - qsrand(QDateTime::currentSecsSinceEpoch()); return QDir::tempPath() + "/tst_qmimedatabase-XXXXXX"; } diff --git a/tests/auto/corelib/plugin/quuid/testProcessUniqueness/main.cpp b/tests/auto/corelib/plugin/quuid/testProcessUniqueness/main.cpp index daf9b1579a..d1e138d8eb 100644 --- a/tests/auto/corelib/plugin/quuid/testProcessUniqueness/main.cpp +++ b/tests/auto/corelib/plugin/quuid/testProcessUniqueness/main.cpp @@ -35,9 +35,6 @@ int main(int argc, char **argv) Q_UNUSED(argc) Q_UNUSED(argv) - // First, break QUuid. - qrand(); - // Now print a few uuids. printf("%s", qPrintable(QUuid::createUuid().toString())); printf("%s", qPrintable(QUuid::createUuid().toString())); diff --git a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp index 37b052bf1d..58bebe19ac 100644 --- a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp +++ b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include // COM interface macro. @@ -1456,7 +1457,7 @@ void tst_QFuture::nonGlobalThreadPool() void run() Q_DECL_OVERRIDE { - const int ms = 100 + (qrand() % 100 - 100/2); + const int ms = 100 + (QRandomGenerator::global()->bounded(100) - 100/2); QThread::msleep(ms); reportResult(Answer); reportFinished(); diff --git a/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp b/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp index e13c2894af..72299402f0 100644 --- a/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp +++ b/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #define Q_TEST_PERFORMANCE 0 @@ -133,7 +134,7 @@ QVector generateData(QString dataSetType, const int length) QVector container; if (dataSetType == "Random") { for (int i = 0; i < length; ++i) - container.append(rand()); + container.append(QRandomGenerator::global()->generate()); } else if (dataSetType == "Ascending") { for (int i = 0; i < length; ++i) container.append(i); @@ -1082,12 +1083,12 @@ void tst_QAlgorithms::popCount_data_impl(size_t sizeof_T_Int) // and some random ones: if (sizeof_T_Int >= 8) for (size_t i = 0; i < 1000; ++i) { - const quint64 input = quint64(qrand()) << 32 | quint32(qrand()); + const quint64 input = QRandomGenerator::global()->generate64(); QTest::addRow("0x%016llx", input) << input << bitsSetInInt64(input); } else if (sizeof_T_Int >= 2) for (size_t i = 0; i < 1000 ; ++i) { - const quint32 input = qrand(); + const quint32 input = QRandomGenerator::global()->generate(); if (sizeof_T_Int >= 4) QTest::addRow("0x%08x", input) << quint64(input) << bitsSetInInt(input); else @@ -1129,7 +1130,7 @@ void tst_QAlgorithms::countTrailing_data_impl(size_t sizeof_T_Int) // and some random ones: for (uint i = 0; i < sizeof_T_Int*8; ++i) { for (uint j = 0; j < sizeof_T_Int*3; ++j) { // 3 is arbitrary - const quint64 r = quint64(qrand()) << 32 | quint32(qrand()); + const quint64 r = QRandomGenerator::global()->generate64(); const quint64 b = Q_UINT64_C(1) << i; const quint64 mask = ((~(b-1)) ^ b) & type_mask; const quint64 input = (r&mask) | b; @@ -1166,7 +1167,7 @@ void tst_QAlgorithms::countLeading_data_impl(size_t sizeof_T_Int) // and some random ones: for (uint i = 0; i < sizeof_T_Int*8; ++i) { for (uint j = 0; j < sizeof_T_Int*3; ++j) { // 3 is arbitrary - const quint64 r = quint64(qrand()) << 32 | quint32(qrand()); + const quint64 r = QRandomGenerator::global()->generate64(); const quint64 b = Q_UINT64_C(1) << i; const quint64 mask = b-1; const quint64 input = (r&mask) | b; diff --git a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp index 442d4d089c..e1dcdb8407 100644 --- a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp @@ -1884,7 +1884,7 @@ class StrongThread: public QThread protected: void run() { - usleep(rand() % 2000); + usleep(QRandomGenerator::global()->bounded(2000)); ptr->ref(); ptr.clear(); } @@ -1897,7 +1897,7 @@ class WeakThread: public QThread protected: void run() { - usleep(rand() % 2000); + usleep(QRandomGenerator::global()->bounded(2000)); QSharedPointer ptr = weak; if (ptr) ptr->ref(); @@ -1959,7 +1959,6 @@ void tst_QSharedPointer::threadStressTest() base.clear(); - srand(time(NULL)); // start threads for (int i = 0; i < allThreads.count(); ++i) if (allThreads[i]) allThreads[i]->start(); diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 235d53f3c1..54eb8ab99c 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -1754,7 +1755,7 @@ void tst_QImage::smoothScale2() static inline int rand8() { - return int(256. * (qrand() / (RAND_MAX + 1.0))); + return QRandomGenerator::global()->bounded(256); } void tst_QImage::smoothScale3_data() diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 779783d5ec..b8243a2b54 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -45,6 +45,7 @@ #include #endif #include +#include #include #include @@ -3052,7 +3053,7 @@ void tst_QPainter::fpe_steepSlopes_data() qreal randf() { - return rand() / (RAND_MAX + 1.0); + return QRandomGenerator::global()->bounded(1.0); } QPointF randInRect(const QRectF &rect) diff --git a/tests/auto/gui/painting/qpathclipper/tst_qpathclipper.cpp b/tests/auto/gui/painting/qpathclipper/tst_qpathclipper.cpp index 14ba9c5c84..93035af7d3 100644 --- a/tests/auto/gui/painting/qpathclipper/tst_qpathclipper.cpp +++ b/tests/auto/gui/painting/qpathclipper/tst_qpathclipper.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -423,8 +424,8 @@ void tst_QPathClipper::clip() static inline QPointF randomPointInRect(const QRectF &rect) { - qreal rx = qrand() / (RAND_MAX + 1.); - qreal ry = qrand() / (RAND_MAX + 1.); + qreal rx = QRandomGenerator::global()->bounded(1.0); + qreal ry = QRandomGenerator::global()->bounded(1.0); return QPointF(rect.left() + rx * rect.width(), rect.top() + ry * rect.height()); diff --git a/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp b/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp index ca01e83dbe..39f5e9ecc3 100644 --- a/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp +++ b/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp @@ -145,7 +145,7 @@ void tst_QTextPieceTable::insertion3() { QString compare; for (int i = 0; i < 20000; ++i) { - int pos = rand() % (i+1); + int pos = QRandomGenerator::global()->bounded(i+1); QChar c((unsigned short)(i & 0xff) + 1); QString str; str += c; @@ -159,7 +159,7 @@ void tst_QTextPieceTable::insertion4() { QString compare; for (int i = 0; i < 20000; ++i) { - int pos = rand() % (i+1); + int pos = QRandomGenerator::global()->generate() % (i+1); QChar c((unsigned short)((i % 26) + (i>25?'A':'a'))); QString str; str += c; @@ -178,7 +178,7 @@ void tst_QTextPieceTable::insertion5() { QString compare; for (int i = 0; i < 20000; ++i) { - int pos = rand() % (i+1); + int pos = QRandomGenerator::global()->generate() % (i+1); QChar c((unsigned short)((i % 26) + (i>25?'A':'a'))); QString str; str += c; @@ -236,8 +236,8 @@ void tst_QTextPieceTable::removal3() QString compare; int l = 0; for (int i = 0; i < 20000; ++i) { - bool remove = l && (rand() % 2); - int pos = rand() % (remove ? l : (l+1)); + bool remove = l && (QRandomGenerator::global()->bounded(2)); + int pos = QRandomGenerator::global()->bounded(remove ? l : (l+1)); QChar c((unsigned short)((i % 26) + (i>25?'A':'a'))); QString str; str += c; @@ -263,8 +263,8 @@ void tst_QTextPieceTable::removal4() QString compare; int l = 0; for (int i = 0; i < 20000; ++i) { - bool remove = l && (rand() % 2); - int pos = (l > 1) ? rand() % (remove ? l-1 : l) : 0; + bool remove = l && (QRandomGenerator::global()->bounded(2)); + int pos = (l > 1) ? QRandomGenerator::global()->bounded(remove ? l-1 : l) : 0; QChar c((unsigned short)((i % 26) + (i>25?'A':'a'))); QString str; if (c != 'a') { @@ -472,13 +472,12 @@ void tst_QTextPieceTable::undoRedo10() void tst_QTextPieceTable::undoRedo11() { - srand(3); const int loops = 20; QString compare; int l = 0; for (int i = 0; i < loops; ++i) { - bool remove = l && (rand() % 2); - int pos = (l > 1) ? rand() % (remove ? l-1 : l) : 0; + bool remove = l && (QRandomGenerator::global()->bounded(2)); + int pos = (l > 1) ? QRandomGenerator::global()->bounded(remove ? l-1 : l) : 0; QChar c((unsigned short)((i % 26) + (i>25?'A':'a'))); QString str; str += c; diff --git a/tests/auto/network/access/hpack/tst_hpack.cpp b/tests/auto/network/access/hpack/tst_hpack.cpp index bd337c9f5f..810745a065 100644 --- a/tests/auto/network/access/hpack/tst_hpack.cpp +++ b/tests/auto/network/access/hpack/tst_hpack.cpp @@ -273,13 +273,13 @@ void tst_Hpack::bitstreamCompression() std::vector buffer; BitOStream out(buffer); for (unsigned i = 0; i < nValues; ++i) { - const bool isString = std::rand() % 1000 > 500; + const bool isString = QRandomGenerator::global()->bounded(1000) > 500; isA.push_back(isString); if (!isString) { - integers.push_back(std::rand() % 1000); + integers.push_back(QRandomGenerator::global()->bounded(1000u)); out.write(integers.back()); } else { - const auto start = std::rand() % (bytes.length() / 2); + const auto start = QRandomGenerator::global()->bounded(uint(bytes.length()) / 2); auto end = start * 2; if (!end) end = bytes.length() / 2; @@ -287,7 +287,7 @@ void tst_Hpack::bitstreamCompression() const auto &s = strings.back(); totalStringBytes += s.size(); QByteArray data(s.c_str(), int(s.size())); - const bool compressed(std::rand() % 1000 > 500); + const bool compressed(QRandomGenerator::global()->bounded(1000) > 500); out.write(data, compressed); } } @@ -442,8 +442,8 @@ void tst_Hpack::lookupTableDynamic() // Strings are repeating way too often, I want to // have at least some items really evicted and not found, // therefore these weird dances with start/len. - const quint32 start = std::rand() % (dataSize - 10); - quint32 len = std::rand() % (dataSize - start); + const quint32 start = QRandomGenerator::global()->bounded(dataSize - 10); + quint32 len = QRandomGenerator::global()->bounded(dataSize - start); if (!len) len = 1; diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp index 7b453ca635..51e1849512 100644 --- a/tests/auto/network/access/http2/tst_http2.cpp +++ b/tests/auto/network/access/http2/tst_http2.cpp @@ -224,7 +224,7 @@ void tst_Http2::multipleRequests() }; for (int i = 0; i < nRequests; ++i) - sendRequest(i, priorities[std::rand() % 3]); + sendRequest(i, priorities[QRandomGenerator::global()->bounded(3)]); runEventLoop(); diff --git a/tests/auto/network/access/qftp/tst_qftp.cpp b/tests/auto/network/access/qftp/tst_qftp.cpp index fba0508f04..4bc43f068c 100644 --- a/tests/auto/network/access/qftp/tst_qftp.cpp +++ b/tests/auto/network/access/qftp/tst_qftp.cpp @@ -276,8 +276,7 @@ void tst_QFtp::init() inFileDirExistsFunction = false; - srand(time(0)); - uniqueExtension = QString::number((quintptr)this) + QString::number(rand()) + uniqueExtension = QString::number((quintptr)this) + QString::number(QRandomGenerator::global()->generate()) + QString::number((qulonglong)time(0)); } diff --git a/tests/auto/network/access/qnetworkdiskcache/tst_qnetworkdiskcache.cpp b/tests/auto/network/access/qnetworkdiskcache/tst_qnetworkdiskcache.cpp index e996347a9a..856033fb63 100644 --- a/tests/auto/network/access/qnetworkdiskcache/tst_qnetworkdiskcache.cpp +++ b/tests/auto/network/access/qnetworkdiskcache/tst_qnetworkdiskcache.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -693,25 +694,25 @@ public: if (write) { QNetworkCacheMetaData m; - if (qrand() % 2 == 0) + if (QRandomGenerator::global()->bounded(2) == 0) m = metaData; else m = metaData2; - if (qrand() % 20 == 1) { + if (QRandomGenerator::global()->bounded(20) == 1) { //qDebug() << "write update"; cache.updateMetaData(m); continue; } QIODevice *device = cache.prepare(m); - if (qrand() % 20 == 1) { + if (QRandomGenerator::global()->bounded(20) == 1) { //qDebug() << "write remove"; cache.remove(url); continue; } QVERIFY(device); - if (qrand() % 2 == 0) + if (QRandomGenerator::global()->bounded(2) == 0) device->write(longString); else device->write(longString2); @@ -740,9 +741,9 @@ public: delete d; } } - if (qrand() % 5 == 1) + if (QRandomGenerator::global()->bounded(5) == 1) cache.remove(url); - if (qrand() % 5 == 1) + if (QRandomGenerator::global()->bounded(5) == 1) cache.clear(); sleep(0); } @@ -791,7 +792,6 @@ void tst_QNetworkDiskCache::sync() return; QTime midnight(0, 0, 0); - qsrand(midnight.secsTo(QTime::currentTime())); Runner reader(tempDir.path()); reader.dt = QDateTime::currentDateTime(); reader.write = false; diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 93afca3d48..b6b5f5ae70 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -120,12 +121,11 @@ class tst_QNetworkReply: public QObject static QString createUniqueExtension() { if (!seedCreated) { - qsrand(QTime(0,0,0).msecsTo(QTime::currentTime()) + QCoreApplication::applicationPid()); seedCreated = true; // not thread-safe, but who cares } return QString::number(QTime(0, 0, 0).msecsTo(QTime::currentTime())) + QLatin1Char('-') + QString::number(QCoreApplication::applicationPid()) - + QLatin1Char('-') + QString::number(qrand()); + + QLatin1Char('-') + QString::number(QRandomGenerator::global()->generate()); } static QString tempRedirectReplyStr() { @@ -4852,7 +4852,7 @@ void tst_QNetworkReply::ioPostToHttpsUploadProgress() // server send the data much faster than expected. // So better provide random data that cannot be compressed. for (int i = 0; i < wantedSize; ++i) - sourceFile += (char)qrand(); + sourceFile += (char)QRandomGenerator::global()->generate(); // emulate a minimal https server SslServer server; @@ -4932,7 +4932,7 @@ void tst_QNetworkReply::ioGetFromBuiltinHttp() // server send the data much faster than expected. // So better provide random data that cannot be compressed. for (int i = 0; i < wantedSize; ++i) - testData += (char)qrand(); + testData += (char)QRandomGenerator::global()->generate(); QByteArray httpResponse = QByteArray("HTTP/1.0 200 OK\r\nContent-Length: "); httpResponse += QByteArray::number(testData.size()); @@ -8748,7 +8748,7 @@ public slots: m_receivedData += data; if (!m_parsedHeaders && m_receivedData.contains("\r\n\r\n")) { m_parsedHeaders = true; - QTimer::singleShot(qrand()%60, this, SLOT(closeDelayed())); // simulate random network latency + QTimer::singleShot(QRandomGenerator::global()->bounded(60), 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. diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index 7340817ade..d7c8c8c378 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2017 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -57,6 +57,7 @@ #if QT_CONFIG(process) # include #endif +#include #include #include #include @@ -305,8 +306,6 @@ public: tst_QTcpSocket::tst_QTcpSocket() : firstFailName("qt-test-server-first-fail") { - qsrand(time(NULL)); - tmpSocket = 0; //This code relates to the socketsConstructedBeforeEventLoop test case @@ -581,8 +580,7 @@ void tst_QTcpSocket::bind() // try to get a random port number // we do this to ensure we're not trying to bind to the same port as we've just used in // a previous run - race condition with the OS actually freeing the port - Q_STATIC_ASSERT(RAND_MAX > 1024); - port = qrand() & USHRT_MAX; + port = QRandomGenerator::global()->generate() & USHRT_MAX; if (port < 1024) continue; } diff --git a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp index 1a7ccba9be..90fc4e0f2a 100644 --- a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp +++ b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp @@ -138,7 +138,7 @@ public: makeCurrent(); QPainter p(this); - p.fillRect(rect(), QColor(rand() % 256, rand() % 256, rand() % 256)); + p.fillRect(rect(), QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256))); p.setPen(Qt::red); p.setFont(QFont("SansSerif", 24)); p.drawText(rect(), Qt::AlignCenter, "This is an autotest"); @@ -229,7 +229,7 @@ public: int height = 300; QImage image(width, height, QImage::Format_RGB32); QPainter p(&image); - p.fillRect(image.rect(), QColor(rand() % 256, rand() % 256, rand() % 256)); + p.fillRect(image.rect(), QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256))); p.setPen(Qt::red); p.setFont(QFont("SansSerif", 24)); p.drawText(image.rect(), Qt::AlignCenter, "This is an autotest"); @@ -271,7 +271,7 @@ public: public slots: void receiveImage(const QImage &image) { m_images << image; - m_positions << QPoint(-rand() % width() / 2, -rand() % height() / 2); + m_positions << QPoint(-QRandomGenerator::global()->bounded(width() / 2), -QRandomGenerator::global()->bounded(height() / 2)); m_semaphore->release(1); @@ -326,7 +326,7 @@ void tst_QGLThreads::textureUploadInThread() if that works, we're in good shape.. */ -static inline float qrandom() { return (rand() % 100) / 100.f; } +static inline float qrandom() { return (QRandomGenerator::global()->bounded(100)) / 100.f; } void renderAScene(int w, int h) { @@ -345,12 +345,12 @@ void renderAScene(int w, int h) for (int i=0; i<1000; ++i) { GLfloat pos[] = { - (rand() % 100) / 100.f, - (rand() % 100) / 100.f, - (rand() % 100) / 100.f, - (rand() % 100) / 100.f, - (rand() % 100) / 100.f, - (rand() % 100) / 100.f + (QRandomGenerator::global()->bounded(100)) / 100.f, + (QRandomGenerator::global()->bounded(100)) / 100.f, + (QRandomGenerator::global()->bounded(100)) / 100.f, + (QRandomGenerator::global()->bounded(100)) / 100.f, + (QRandomGenerator::global()->bounded(100)) / 100.f, + (QRandomGenerator::global()->bounded(100)) / 100.f }; funcs->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, pos); diff --git a/tests/auto/other/compiler/tst_compiler.cpp b/tests/auto/other/compiler/tst_compiler.cpp index 121d731757..8b59f2758f 100644 --- a/tests/auto/other/compiler/tst_compiler.cpp +++ b/tests/auto/other/compiler/tst_compiler.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2017 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -802,7 +802,7 @@ void tst_Compiler::cxx11_auto_type() QSKIP("Compiler does not support C++11 feature"); #else auto i = 1; - auto x = qrand(); + auto x = QRandomGenerator::global()->generate(); auto l = 1L; auto s = QStringLiteral("Hello World"); @@ -851,8 +851,8 @@ void tst_Compiler::cxx11_decltype() #ifndef Q_COMPILER_DECLTYPE QSKIP("Compiler does not support C++11 feature"); #else - decltype(qrand()) i = 0; - QCOMPARE(i, 0); + decltype(QRandomGenerator::global()->generate()) i = 0; + QCOMPARE(i, 0U); #endif } @@ -1549,7 +1549,7 @@ void tst_Compiler::runtimeArrays() #if __cpp_runtime_arrays-0 < 201304 QSKIP("Compiler does not support this C++14 feature"); #else - int i[qrand() & 0x1f]; + int i[QRandomGenerator::global()->generate() & 0x1f]; Q_UNUSED(i); #endif } diff --git a/tests/auto/other/networkselftest/tst_networkselftest.cpp b/tests/auto/other/networkselftest/tst_networkselftest.cpp index 3b696604b5..dc353d2090 100644 --- a/tests/auto/other/networkselftest/tst_networkselftest.cpp +++ b/tests/auto/other/networkselftest/tst_networkselftest.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -538,7 +539,7 @@ void tst_NetworkSelfTest::imapServer() void tst_NetworkSelfTest::httpServer() { QByteArray uniqueExtension = QByteArray::number((qulonglong)this) + - QByteArray::number((qulonglong)qrand()) + + QByteArray::number((qulonglong)QRandomGenerator::global()->generate()) + QByteArray::number(QDateTime::currentSecsSinceEpoch()); netChat(80, QList() diff --git a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp index 09e070ac20..eafd4d7cea 100644 --- a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include "../../../../../src/widgets/dialogs/qsidebar_p.h" #include "../../../../../src/widgets/dialogs/qfilesystemmodel_p.h" #include "../../../../../src/widgets/dialogs/qfiledialog_p.h" @@ -1196,7 +1197,7 @@ void tst_QFileDialog2::QTBUG6558_showDirsOnly() { const QString tempPath = tempDir.path(); QDir dirTemp(tempPath); - const QString tempName = QLatin1String("showDirsOnly.") + QString::number(qrand()); + const QString tempName = QLatin1String("showDirsOnly.") + QString::number(QRandomGenerator::global()->generate()); dirTemp.mkdir(tempName); dirTemp.cd(tempName); QTRY_VERIFY(dirTemp.exists()); diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index 2abb6e3515..da15583d5d 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -3595,12 +3596,12 @@ void tst_QGraphicsItem::group() QList newItems; for (int i = 0; i < 100; ++i) { QGraphicsItem *item = scene.addRect(QRectF(-25, -25, 50, 50), QPen(Qt::black, 0), - QBrush(QColor(rand() % 255, rand() % 255, - rand() % 255, rand() % 255))); + QBrush(QColor(QRandomGenerator::global()->bounded(255), QRandomGenerator::global()->bounded(255), + QRandomGenerator::global()->bounded(255), QRandomGenerator::global()->bounded(255)))); newItems << item; - item->setPos(-1000 + rand() % 2000, - -1000 + rand() % 2000); - item->setTransform(QTransform().rotate(rand() % 90), true); + item->setPos(-1000 + QRandomGenerator::global()->bounded(2000), + -1000 + QRandomGenerator::global()->bounded(2000)); + item->setTransform(QTransform().rotate(QRandomGenerator::global()->bounded(90)), true); } view.fitInView(scene.itemsBoundingRect()); @@ -4143,8 +4144,8 @@ void tst_QGraphicsItem::ensureVisible() for (int x = -100; x < 100; x += 25) { for (int y = -100; y < 100; y += 25) { - int xmargin = rand() % 75; - int ymargin = rand() % 75; + int xmargin = QRandomGenerator::global()->bounded(75); + int ymargin = QRandomGenerator::global()->bounded(75); item->ensureVisible(x, y, 25, 25, xmargin, ymargin); QApplication::processEvents(); @@ -7137,7 +7138,7 @@ public: : QGraphicsRectItem(QRectF(-10, -10, 20, 20)) { setPen(QPen(Qt::black, 0)); - setBrush(QColor(qrand() % 256, qrand() % 256, qrand() % 256)); + setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256))); } QTransform x; diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp index 7615c5e821..968233438a 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp @@ -1507,10 +1507,10 @@ void tst_QGraphicsScene::mouseGrabberItem() QCOMPARE(scene.mouseGrabberItem(), topMostItem); // Geometrical changes should not affect the mouse grabber. - item->setZValue(rand() % 500); - item2->setZValue(rand() % 500); - item->setPos(rand() % 50000, rand() % 50000); - item2->setPos(rand() % 50000, rand() % 50000); + item->setZValue(QRandomGenerator::global()->bounded(500)); + item2->setZValue(QRandomGenerator::global()->bounded(500)); + item->setPos(QRandomGenerator::global()->bounded(50000), QRandomGenerator::global()->bounded(50000)); + item2->setPos(QRandomGenerator::global()->bounded(50000), QRandomGenerator::global()->bounded(50000)); } QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMouseRelease); @@ -3424,7 +3424,7 @@ void tst_QGraphicsScene::task139710_bspTreeCrash() // add 1000 more items - the BSP tree is now resized for (int i = 0; i < 1000; ++i) { QGraphicsRectItem *item = scene.addRect(QRectF(0, 0, 200, 200)); - item->setPos(qrand() % 10000, qrand() % 10000); + item->setPos(QRandomGenerator::global()->bounded(10000), QRandomGenerator::global()->bounded(10000)); } // trigger delayed item indexing for the first 1000 items @@ -3433,7 +3433,7 @@ void tst_QGraphicsScene::task139710_bspTreeCrash() // add 1000 more items - the BSP tree is now resized for (int i = 0; i < 1000; ++i) { QGraphicsRectItem *item = scene.addRect(QRectF(0, 0, 200, 200)); - item->setPos(qrand() % 10000, qrand() % 10000); + item->setPos(QRandomGenerator::global()->bounded(10000), QRandomGenerator::global()->bounded(10000)); } // get items from the BSP tree and use them. there was junk in the tree @@ -3543,15 +3543,15 @@ void tst_QGraphicsScene::sorting() QGraphicsRectItem *c_2_1 = new QGraphicsRectItem(0, 0, 30, 30, c_2); QGraphicsRectItem *c_2_1_1 = new QGraphicsRectItem(0, 0, 20, 20, c_2_1); QGraphicsRectItem *c_2_2 = new QGraphicsRectItem(0, 0, 30, 30, c_2); - t_1->setBrush(QColor(qrand() % 256, qrand() % 256, qrand() % 256)); - c_1->setBrush(QColor(qrand() % 256, qrand() % 256, qrand() % 256)); - c_1_1->setBrush(QColor(qrand() % 256, qrand() % 256, qrand() % 256)); - c_1_1_1->setBrush(QColor(qrand() % 256, qrand() % 256, qrand() % 256)); - c_1_2->setBrush(QColor(qrand() % 256, qrand() % 256, qrand() % 256)); - c_2->setBrush(QColor(qrand() % 256, qrand() % 256, qrand() % 256)); - c_2_1->setBrush(QColor(qrand() % 256, qrand() % 256, qrand() % 256)); - c_2_1_1->setBrush(QColor(qrand() % 256, qrand() % 256, qrand() % 256)); - c_2_2->setBrush(QColor(qrand() % 256, qrand() % 256, qrand() % 256)); + t_1->setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256))); + c_1->setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256))); + c_1_1->setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256))); + c_1_1_1->setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256))); + c_1_2->setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256))); + c_2->setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256))); + c_2_1->setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256))); + c_2_1_1->setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256))); + c_2_2->setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256))); c_1->setPos(23, 18); c_1_1->setPos(24, 28); diff --git a/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp b/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp index 1fd7b31e22..f1239b2e7c 100644 --- a/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp +++ b/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp @@ -30,16 +30,6 @@ #include #include #include "viewstotest.cpp" -#include - -#if defined(Q_OS_UNIX) || defined(Q_OS_WIN) -#include -#endif - -#if defined(Q_OS_WIN) -# define random rand -# define srandom srand -#endif /*! See viewstotest.cpp for instructions on how to have your view tested with these tests. @@ -410,13 +400,15 @@ void touch(QWidget *widget, Qt::KeyboardModifier modifier, Qt::Key keyPress){ int width = widget->width(); int height = widget->height(); for (int i = 0; i < 5; ++i) { - QTest::mouseClick(widget, Qt::LeftButton, modifier, QPoint(random() % width, random() % height)); - QTest::mouseDClick(widget, Qt::LeftButton, modifier, QPoint(random() % width, random() % height)); - QPoint press(random() % width, random() % height); - QPoint releasePoint(random() % width, random() % height); + QTest::mouseClick(widget, Qt::LeftButton, modifier, + QPoint(QRandomGenerator::global()->bounded(width), QRandomGenerator::global()->bounded(height))); + QTest::mouseDClick(widget, Qt::LeftButton, modifier, + QPoint(QRandomGenerator::global()->bounded(width), QRandomGenerator::global()->bounded(height))); + QPoint press(QRandomGenerator::global()->bounded(width), QRandomGenerator::global()->bounded(height)); + QPoint releasePoint(QRandomGenerator::global()->bounded(width), QRandomGenerator::global()->bounded(height)); QTest::mousePress(widget, Qt::LeftButton, modifier, press); QTest::mouseMove(widget, releasePoint); - if (random() % 1 == 0) + if (QRandomGenerator::global()->bounded(1) == 0) QTest::mouseRelease(widget, Qt::LeftButton, 0, releasePoint); else QTest::mouseRelease(widget, Qt::LeftButton, modifier, releasePoint); @@ -443,7 +435,6 @@ void tst_QItemView::spider() view->setModel(treeModel); view->show(); QVERIFY(QTest::qWaitForWindowActive(view)); - srandom(time(0)); touch(view->viewport(), Qt::NoModifier, Qt::Key_Left); touch(view->viewport(), Qt::ShiftModifier, Qt::Key_Enter); touch(view->viewport(), Qt::ControlModifier, Qt::Key_Backspace); diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 30fc927f7d..7d4024b556 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -9826,7 +9827,7 @@ void tst_QWidget::grab() for (int row = 0; row < image.height(); ++row) { QRgb *line = reinterpret_cast(image.scanLine(row)); for (int col = 0; col < image.width(); ++col) - line[col] = qRgba(rand() & 255, row, col, opaque ? 255 : 127); + line[col] = qRgba(QRandomGenerator::global()->bounded(255), row, col, opaque ? 255 : 127); } QPalette pal = widget.palette(); diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index 71969ec695..3d9620e75a 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -43,10 +43,6 @@ #include #include "qclipboard.h" -#ifdef Q_OS_MAC -#include // For the random function. -#endif - #include #include #include @@ -1949,17 +1945,7 @@ void tst_QLineEdit::noCursorBlinkWhenReadOnly() static void figureOutProperKey(Qt::Key &key, Qt::KeyboardModifiers &pressState) { #ifdef Q_OS_MAC - static bool tst_lineedit_randomized = false; - // Mac has 3 different ways of accomplishing this (same for moving to the back) - // So I guess we should just randomly do this for now. Which may get people mad, but if - // we fail at one point, it's just a matter of setting roll to the correct value - // instead of random. - - if (!tst_lineedit_randomized) { - tst_lineedit_randomized = true; - ::srandom(ulong(time(0))); - } - long roll = ::random() % 3; + long roll = QRandomGenerator::global()->bounded(3); switch (roll) { case 0: key = key == Qt::Key_Home ? Qt::Key_Up : Qt::Key_Down; diff --git a/tests/benchmarks/corelib/tools/qalgorithms/tst_qalgorithms.cpp b/tests/benchmarks/corelib/tools/qalgorithms/tst_qalgorithms.cpp index 11e559a298..a4ad3a08a8 100644 --- a/tests/benchmarks/corelib/tools/qalgorithms/tst_qalgorithms.cpp +++ b/tests/benchmarks/corelib/tools/qalgorithms/tst_qalgorithms.cpp @@ -57,7 +57,7 @@ QVector generateData(QString dataSetType, const int length) QVector container; if (dataSetType == "Random") { for (int i = 0; i < length; ++i) - container.append(rand()); + container.append(QRandomGenerator::global()->generate()); } else if (dataSetType == "Ascending") { for (int i = 0; i < length; ++i) container.append(i); diff --git a/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp b/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp index 507e2af708..1d414161d1 100644 --- a/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp +++ b/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2017 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -102,9 +103,8 @@ tst_bench_QCryptographicHash::tst_bench_QCryptographicHash() } else #endif { - qsrand(time(NULL)); for (int i = 0; i < MaxBlockSize; ++i) - blockOfData[i] = qrand(); + blockOfData[i] = QRandomGenerator::global()->generate(); } } diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp index e3ee0f8e45..7809b38050 100644 --- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp @@ -27,6 +27,7 @@ ****************************************************************************/ #include +#include #include "theme.h" #include "dummydatagen.h" @@ -65,12 +66,11 @@ DummyDataGenerator::~DummyDataGenerator() void DummyDataGenerator::Reset() { - qsrand(100); } QString DummyDataGenerator::randomPhoneNumber(QString indexNumber) { - int index = qrand()%m_countryCodes.count(); + int index = QRandomGenerator::global()->bounded(m_countryCodes.count()); QString countryCode = m_countryCodes.at(index); QString areaCode = QString::number(index) + QString("0").repeated(2-QString::number(index).length()); QString beginNumber = QString::number(555-index*2); @@ -84,13 +84,13 @@ QString DummyDataGenerator::randomFirstName() { m_isMale = !m_isMale; if (m_isMale) - return m_firstNamesM.at(qrand()%m_firstNamesM.count()); - return m_firstNamesF.at(qrand()%m_firstNamesF.count()); + return m_firstNamesM.at(QRandomGenerator::global()->bounded(m_firstNamesM.count())); + return m_firstNamesF.at(QRandomGenerator::global()->bounded(m_firstNamesF.count())); } QString DummyDataGenerator::randomLastName() { - return m_lastNames.at(qrand()%m_lastNames.count()); + return m_lastNames.at(QRandomGenerator::global()->bounded(m_lastNames.count())); } QString DummyDataGenerator::randomName() @@ -101,8 +101,8 @@ QString DummyDataGenerator::randomName() QString DummyDataGenerator::randomIconItem() { QString avatar = Theme::p()->pixmapPath() + "contact_default_icon.svg"; - if (qrand()%4) { - int randVal = 1+qrand()%25; + if (QRandomGenerator::global()->bounded(4)) { + int randVal = 1+QRandomGenerator::global()->bounded(25); if (m_isMale && randVal > 15) { randVal -= 15; @@ -118,7 +118,7 @@ QString DummyDataGenerator::randomIconItem() QString DummyDataGenerator::randomStatusItem() { - switch (qrand()%3) { + switch (QRandomGenerator::global()->bounded(3)) { case 0: return Theme::p()->pixmapPath() + "contact_status_online.svg"; case 1: return Theme::p()->pixmapPath() + "contact_status_offline.svg"; case 2: return Theme::p()->pixmapPath() + "contact_status_idle.svg"; diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp index 6c97f94683..e0cc0f8eb4 100644 --- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp @@ -82,7 +82,7 @@ int main(int argc, char *argv[]) for (int i = 0; i < atoi(argv[1]); ++i) { QGraphicsRectItem *child = scene.addRect(-5, -5, 10, 10, QPen(Qt::NoPen), QBrush(Qt::blue)); - child->setPos(-50 + qrand() % 100, -50 + qrand() % 100); + child->setPos(-50 + QRandomGenerator::global()->bounded(100), -50 + QRandomGenerator::global()->bounded(100)); child->setParentItem(item); } diff --git a/tests/benchmarks/gui/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/benchmarks/gui/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp index c2f41a7557..d9bc7f21b6 100644 --- a/tests/benchmarks/gui/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp @@ -31,6 +31,7 @@ #include #include #include +#include class tst_QGraphicsWidget : public QObject { @@ -72,7 +73,9 @@ void tst_QGraphicsWidget::move() QGraphicsView view(&scene); view.show(); QBENCHMARK { - widget->setPos(qrand(),qrand()); + // truncate the random values to 24 bits to + // avoid overflowing + widget->setPos(QRandomGenerator::global()->generate() & 0xffffff, QRandomGenerator::global()->generate() & 0xffffff); } } diff --git a/tests/benchmarks/gui/painting/qtbench/benchmarktests.h b/tests/benchmarks/gui/painting/qtbench/benchmarktests.h index e4b98336c7..42b06778f9 100644 --- a/tests/benchmarks/gui/painting/qtbench/benchmarktests.h +++ b/tests/benchmarks/gui/painting/qtbench/benchmarktests.h @@ -37,6 +37,7 @@ #include #include #include +#include class Benchmark { @@ -47,9 +48,9 @@ public: : m_size(size) { for (int i=0; i<16; ++i) { - m_colors[i] = QColor::fromRgbF((rand() % 4) / 3.0, - (rand() % 4) / 3.0, - (rand() % 4) / 3.0, + m_colors[i] = QColor::fromRgbF((QRandomGenerator::global()->bounded(4)) / 3.0, + (QRandomGenerator::global()->bounded(4)) / 3.0, + (QRandomGenerator::global()->bounded(4)) / 3.0, 1); } } @@ -142,7 +143,7 @@ public: ImageFillRectBenchmark(int size) : Benchmark(QSize(size, size)) { - int s = rand() % 24 + 8; + int s = QRandomGenerator::global()->bounded(24) + 8; m_content = QImage(s, s, QImage::Format_ARGB32_Premultiplied); QPainter p(&m_content); p.fillRect(0, 0, s, s, Qt::white); diff --git a/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp index dfa658df11..b2f4cbd7ba 100644 --- a/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -525,7 +526,7 @@ void tst_qnetworkreply::echoPerformance() data.resize(1024*1024*10); // 10 MB // init with garbage. needed so ssl cannot compress it in an efficient way. for (size_t i = 0; i < data.size() / sizeof(int); i++) { - int r = qrand(); + char r = char(QRandomGenerator::global()->generate()); data.data()[i*sizeof(int)] = r; } diff --git a/tests/manual/cocoa/nativewidgets/main.cpp b/tests/manual/cocoa/nativewidgets/main.cpp index bfa97aa62f..3923e30de7 100644 --- a/tests/manual/cocoa/nativewidgets/main.cpp +++ b/tests/manual/cocoa/nativewidgets/main.cpp @@ -37,7 +37,7 @@ class ColorWidget : public QWidget void changeColor() { - color.setHsv((qreal(qrand()) / RAND_MAX) * 50 + 200, s, s); + color.setHsv(QRandomGenerator::global()->bounded(50) + 200, s, s); } public: diff --git a/tests/manual/textrendering/textperformance/main.cpp b/tests/manual/textrendering/textperformance/main.cpp index 9bd6d036af..eb6d09b9c8 100644 --- a/tests/manual/textrendering/textperformance/main.cpp +++ b/tests/manual/textrendering/textperformance/main.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -93,17 +94,17 @@ public: static const QString text = QLatin1String("Qt rocks!!!"); static const int textsPerPaint = 30; for (int i = 0; i < textsPerPaint; i++) { - const int fontSize = 4 + (qrand() % 5); - const int fontWeight = (qrand() % 2) == 1 ? QFont::Normal : QFont::Bold; - const bool fontItalic = (qrand() % 2) == 1; + const int fontSize = 4 + QRandomGenerator::global()->bounded(5); + const int fontWeight = QRandomGenerator::global()->bounded(2) == 1 ? QFont::Normal : QFont::Bold; + const bool fontItalic = QRandomGenerator::global()->bounded(2) == 1; const QFont font("Default", fontSize, fontWeight, fontItalic); p.setFont(font); - p.setPen(QColor::fromHsv(qrand() % 359, 155 + qrand() % 100, - 155 + qrand() % 100, 100 + qrand() % 155)); + p.setPen(QColor::fromHsv(QRandomGenerator::global()->bounded(359), 155 + QRandomGenerator::global()->bounded(100), + 155 + QRandomGenerator::global()->bounded(100), 100 + QRandomGenerator::global()->bounded(155))); const QSize textSize(p.fontMetrics().boundingRect(text).size()); const QPoint position( - -textSize.width() / 2 + (qrand() % size.width()), - textSize.height() / 2 + (qrand() % size.height())); + -textSize.width() / 2 + QRandomGenerator::global()->bounded(size.width()), + textSize.height() / 2 + QRandomGenerator::global()->bounded(size.height())); p.drawText(position, text); } } @@ -126,8 +127,8 @@ public: QString text; for (int i = 0; i < piecesPerPaint; ++i) { - QString piece = QLatin1String(pieces[qrand() % piecesCount]); - if (i == 0 || qrand() % 2) { + QString piece = QLatin1String(pieces[QRandomGenerator::global()->bounded(piecesCount)]); + if (i == 0 || QRandomGenerator::global()->bounded(2)) { // Make this piece the beginning of a new sentence. piece[0] = piece[0].toUpper(); if (i > 0) @@ -160,7 +161,7 @@ public: for (int i = 0; i < systemsPerPaint; i++) { if (i > 0) text.append(QLatin1Char(' ')); - text.append(samples.at(qrand() % samples.count())); + text.append(samples.at(QRandomGenerator::global()->bounded(samples.count()))); } p.drawText(QRectF(QPointF(0, 0), QSizeF(size)), Qt::AlignTop | Qt::AlignAbsolute | Qt::TextWordWrap, text); diff --git a/tests/manual/windowchildgeometry/controllerwidget.cpp b/tests/manual/windowchildgeometry/controllerwidget.cpp index 1d18c5d51b..871313d983 100644 --- a/tests/manual/windowchildgeometry/controllerwidget.cpp +++ b/tests/manual/windowchildgeometry/controllerwidget.cpp @@ -29,16 +29,12 @@ #include "controllerwidget.h" #include -#if QT_VERSION >= 0x050000 -# include -# include -# include -# include -# include -#else -# include -#endif - +#include +#include +#include +#include +#include +#include #include CoordinateControl::CoordinateControl(const QString &sep) : m_x(new QSpinBox), m_y(new QSpinBox) @@ -280,7 +276,7 @@ public: explicit Window(QWindow *parent = 0) : QWindow(parent) , m_backingStore(new QBackingStore(this)) - , m_color(Qt::GlobalColor(qrand() % 18)) + , m_color(Qt::GlobalColor(QRandomGenerator::global()->bounded(18))) { setObjectName(QStringLiteral("window")); setTitle(tr("TestWindow")); -- cgit v1.2.3 From 39355daa40438eef386ce55f02e7ba9ff824993f Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 7 Nov 2017 11:51:57 +0100 Subject: tst_QNetworkReply::getFromUnreachableIp - fix a failing test This patch works around Windows X86 on QEMU antics. It appears on this platform the test behaves in some unpredictable manner: - WSAConnect with 255.255.255.255 does not always immediately fail with some error, so socket engine waits for a connection timeout (30 s.), but the test itself - only waits for 5 seconds and then tests that a request has finished with error, which is not true (we are still connecting). To make it work - whenever we have bearermanager feature enabled, set a connection timeout to something reasonable, not 30 s. Since we try to connect to each address twice, make timeout 1.5 s (so it's 3 s. in total and still is < 5 s.). Task-number: QTBUG-64264 Change-Id: I1d40c140667fca8402ec9344e66d313b6df54256 Reviewed-by: Timur Pocheptsov --- .../access/qnetworkreply/tst_qnetworkreply.cpp | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 099ea8ff39..b86750a900 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -6766,6 +6766,48 @@ void tst_QNetworkReply::getFromUnreachableIp() { QNetworkAccessManager manager; +#ifdef Q_OS_WIN32 + // This test assumes that attempt to connect to 255.255.255.255 fails more + // or less fast/immediately. This is not what we observe on Windows x86: + // WSAConnect on non-blocking socket returns SOCKET_ERROR, WSAGetLastError + // returns WSAEWOULDBLOCK (expected) and getsockopt most of the time returns + // NOERROR; so socket engine starts a timer (30 s.) and waits for a timeout/ + // error/success. Unfortunately, the test itself is waiting only for 5 s. + // So we have to adjust the connection timeout or skip the test completely + // if the 'bearermanagement' feature is not available. +#if QT_CONFIG(bearermanagement) + class ConfigurationGuard + { + public: + explicit ConfigurationGuard(QNetworkAccessManager *m) + : manager(m) + { + Q_ASSERT(m); + auto conf = manager->configuration(); + previousTimeout = conf.connectTimeout(); + conf.setConnectTimeout(1500); + manager->setConfiguration(conf); + } + ~ConfigurationGuard() + { + Q_ASSERT(manager); + auto conf = manager->configuration(); + conf.setConnectTimeout(previousTimeout); + manager->setConfiguration(conf); + } + private: + QNetworkAccessManager *manager = nullptr; + int previousTimeout = 0; + + Q_DISABLE_COPY(ConfigurationGuard) + }; + + const ConfigurationGuard restorer(&manager); +#else // bearermanagement + QSKIP("This test is non-deterministic on Windows x86"); +#endif // !bearermanagement +#endif // Q_OS_WIN32 + QNetworkRequest request(QUrl("http://255.255.255.255/42/23/narf/narf/narf")); QNetworkReplyPtr reply(manager.get(request)); -- cgit v1.2.3 From dfdd99fc123ee80e162f0c14b4687fa00a328215 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 25 Sep 2017 12:09:08 +0200 Subject: Doc: Be more specific on full stop in QVersionNumber So far we just write ... '.'. , which looks weird. Change-Id: Iac6fc781c80976994ea0a182b55958baa39a7e52 Reviewed-by: Leena Miettinen --- src/corelib/tools/qversionnumber.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qversionnumber.cpp b/src/corelib/tools/qversionnumber.cpp index 97e5da8b3c..d2667ddea9 100644 --- a/src/corelib/tools/qversionnumber.cpp +++ b/src/corelib/tools/qversionnumber.cpp @@ -388,7 +388,7 @@ QVersionNumber QVersionNumber::commonPrefix(const QVersionNumber &v1, /*! \fn QString QVersionNumber::toString() const - Returns a string with all of the segments delimited by a '.'. + Returns a string with all of the segments delimited by a period (\c{.}). \sa majorVersion(), minorVersion(), microVersion(), segments() */ @@ -411,7 +411,7 @@ QString QVersionNumber::toString() const int *suffixIndex) Constructs a QVersionNumber from a specially formatted \a string of - non-negative decimal numbers delimited by '.'. + non-negative decimal numbers delimited by a period (\c{.}). Once the numerical segments have been parsed, the remainder of the string is considered to be the suffix string. The start index of that string will be -- cgit v1.2.3 From 7d10936443750b8b0c90bf1c979ad6ab51eb92a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Sun, 5 Nov 2017 16:18:54 +0100 Subject: Fix QHighDpi::fromNativeLocalExposedRegion rounding errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ceiling width/height fails to take into account rects that do no have their top left position on an exact point boundary. Example: QRect(0,0 20x20) and QRect(1,1 20x20) with scale 2.0 would give the same result of QRect(0,0 10x10). The correct rects are QRect(0,0 10x10) and QRect(0,0 11x11), so that we are sure to repaint all pixels within the exposed region. Before 5138fada0b9c, rects were also rounded incorrectly. The old method would give the result of QRect(0,0 11x11) in both cases, causing the exposed region to be larger than a window. Amends 5138fada0b9ce3968b23ec11df5f0d4e67544c43 Task-number: QTBUG-63943 Change-Id: I9f3dddf649bdc506c23bce1b6704860d61481459 Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qhighdpiscaling_p.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h index 0a060a2d2c..83fc9452c5 100644 --- a/src/gui/kernel/qhighdpiscaling_p.h +++ b/src/gui/kernel/qhighdpiscaling_p.h @@ -402,7 +402,8 @@ inline QRegion fromNativeLocalExposedRegion(const QRegion &pixelRegion, const QW const QPointF topLeftP = rect.topLeft() / scaleFactor; const QSizeF sizeP = rect.size() / scaleFactor; pointRegion += QRect(QPoint(qFloor(topLeftP.x()), qFloor(topLeftP.y())), - QSize(qCeil(sizeP.width()), qCeil(sizeP.height()))); + QPoint(qCeil(topLeftP.x() + sizeP.width() - 1.0), + qCeil(topLeftP.y() + sizeP.height() - 1.0))); } return pointRegion; } -- cgit v1.2.3 From 429d5f0c5edf776004a8a28c3a93f97e41f2ef85 Mon Sep 17 00:00:00 2001 From: Robert Szefner Date: Mon, 23 Oct 2017 23:56:51 +0200 Subject: Set correct datatype for column 'more_data' in PostgreSQL Task-number: QTBUG-63861 Change-Id: Ice9e788841046482bf5c4653eb859d00bc6b1c59 Reviewed-by: Friedemann Kleint Reviewed-by: Andy Shaw --- tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp index 8f8cfe009d..81206a5856 100644 --- a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp +++ b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp @@ -77,6 +77,8 @@ void tst_QSqlDriver::recreateTestTables(QSqlDatabase db) doubleField = "more_data double"; else if (dbType == QSqlDriver::Oracle) doubleField = "more_data number(8,7)"; + else if (dbType == QSqlDriver::PostgreSQL) + doubleField = "more_data double precision"; else doubleField = "more_data double(8,7)"; QVERIFY_SQL( q, exec("create table " + relTEST1 + -- cgit v1.2.3 From e27bd981373cc3d22e54d8cbe030e5c329f9beda Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 8 Nov 2017 12:10:29 +0100 Subject: qfile tests: Make sure files are writable before deleting them On some platforms (like UWP) files that are copied during qfile auto tests are not writable by default. The cleanup will fail for these files if the permissions are not set accordingly. Change-Id: Id925dcadfc6b505c87f1f55d5ea05e286b60a5a5 Reviewed-by: Maurice Kalinowski Reviewed-by: Friedemann Kleint --- tests/auto/corelib/io/qfile/tst_qfile.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 5f3ebeadd7..8db89b9f05 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -405,6 +405,8 @@ void tst_QFile::cleanup() QDir remainingDir(absoluteFilePath); QVERIFY2(remainingDir.removeRecursively(), qPrintable(absoluteFilePath)); } else { + if (!(QFile::permissions(absoluteFilePath) & QFile::WriteUser)) + QVERIFY2(QFile::setPermissions(absoluteFilePath, QFile::WriteUser), qPrintable(absoluteFilePath)); QVERIFY2(QFile::remove(absoluteFilePath), qPrintable(absoluteFilePath)); } } -- cgit v1.2.3 From bbc68dc815122e6be9ea44adadd93ffb715c7792 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 8 Nov 2017 12:12:06 +0100 Subject: Fix tst_QFile::useQFileInAFileHandler for systems using resources for test data Resource files are extracted to m_dataDir in tst_QFile::initTestCase. Instead of trying to access the file from the resource on systems that use qrc for bundling the test data, we have to use the files that were extracted at the beginning of the test. Change-Id: I35453fbdeb27e317d1342ff1cb7bbea9cebea14d Reviewed-by: Maurice Kalinowski Reviewed-by: Friedemann Kleint --- tests/auto/corelib/io/qfile/tst_qfile.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 8db89b9f05..8a3d490925 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -2190,12 +2190,20 @@ public: if (fileName.startsWith(":!")) { QDir dir; - QString realFile = QFINDTESTDATA(fileName.mid(2)); +#ifndef BUILTIN_TESTDATA + const QString realFile = QFINDTESTDATA(fileName.mid(2)); +#else + const QString realFile = m_dataDir->filePath(fileName.mid(2)); +#endif if (dir.exists(realFile)) return new QFSFileEngine(realFile); } return 0; } + +#ifdef BUILTIN_TESTDATA + QSharedPointer m_dataDir; +#endif }; #endif @@ -2204,6 +2212,9 @@ void tst_QFile::useQFileInAFileHandler() { // This test should not dead-lock MyRecursiveHandler handler; +#ifdef BUILTIN_TESTDATA + handler.m_dataDir = m_dataDir; +#endif QFile file(":!tst_qfile.cpp"); QVERIFY(file.exists()); } -- cgit v1.2.3 From 82c3c9d45d5fad0ed18e096f09729579a0902a71 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 8 Nov 2017 13:58:19 +0100 Subject: Fix tst_QFile::handle for systems using builtin test data To obtain the file's handle, we need to obtain it from the extracted test data instead of qrc. Change-Id: I89c5c3f3a7da7e36205a439581a6d83efffdc07c Reviewed-by: Maurice Kalinowski Reviewed-by: Friedemann Kleint --- tests/auto/corelib/io/qfile/tst_qfile.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 8a3d490925..16a3cfd766 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -445,8 +445,6 @@ void tst_QFile::initTestCase() m_stdinProcessDir = QFINDTESTDATA("stdinprocess"); QVERIFY(!m_stdinProcessDir.isEmpty()); #endif - m_testSourceFile = QFINDTESTDATA("tst_qfile.cpp"); - QVERIFY(!m_testSourceFile.isEmpty()); m_testLogFile = QFINDTESTDATA("testlog.txt"); QVERIFY(!m_testLogFile.isEmpty()); m_dosFile = QFINDTESTDATA("dosfile.txt"); @@ -459,12 +457,15 @@ void tst_QFile::initTestCase() QVERIFY(!m_twoDotsFile.isEmpty()); #ifndef BUILTIN_TESTDATA + m_testSourceFile = QFINDTESTDATA("tst_qfile.cpp"); + QVERIFY(!m_testSourceFile.isEmpty()); m_testFile = QFINDTESTDATA("testfile.txt"); QVERIFY(!m_testFile.isEmpty()); #else m_dataDir = QEXTRACTTESTDATA("/"); QVERIFY2(!m_dataDir.isNull(), qPrintable("Could not extract test data")); m_testFile = m_dataDir->path() + "/testfile.txt"; + m_testSourceFile = m_dataDir->path() + "/tst_qfile.cpp"; #endif m_resourcesDir = QFINDTESTDATA("resources"); QVERIFY(!m_resourcesDir.isEmpty()); -- cgit v1.2.3 From 579d0cb2bed193ccb1901b121a360f85d1c57a54 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 8 Nov 2017 14:09:11 +0100 Subject: Fix tst_QFile::openDirectory for systems using builtin test data To obtain "proper" directory behavior, we have to check against the extracted "resources" directory instead of its qrc counterpart. Change-Id: I4996ba74419945f78d356ad953a5b826ff663687 Reviewed-by: Maurice Kalinowski --- tests/auto/corelib/io/qfile/tst_qfile.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 16a3cfd766..5f0eae6fc3 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -461,14 +461,15 @@ void tst_QFile::initTestCase() QVERIFY(!m_testSourceFile.isEmpty()); m_testFile = QFINDTESTDATA("testfile.txt"); QVERIFY(!m_testFile.isEmpty()); + m_resourcesDir = QFINDTESTDATA("resources"); + QVERIFY(!m_resourcesDir.isEmpty()); #else m_dataDir = QEXTRACTTESTDATA("/"); QVERIFY2(!m_dataDir.isNull(), qPrintable("Could not extract test data")); m_testFile = m_dataDir->path() + "/testfile.txt"; m_testSourceFile = m_dataDir->path() + "/tst_qfile.cpp"; + m_resourcesDir = m_dataDir->path() + "/resources"; #endif - m_resourcesDir = QFINDTESTDATA("resources"); - QVERIFY(!m_resourcesDir.isEmpty()); m_noEndOfLineFile = QFINDTESTDATA("noendofline.txt"); QVERIFY(!m_noEndOfLineFile.isEmpty()); -- cgit v1.2.3 From d0736e9d17d0b3ec2f7aa3f323a1edf70aa83e27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 7 Nov 2017 15:03:32 +0100 Subject: Cocoa: Make High DPI drag cursor work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ide4bc50ab7173529a00fe60a04204bad0b3f275e Task-id: QTBUG-60769 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qnsview.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index ec9d25fff9..2e64204fb7 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -2068,6 +2068,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin } else { NSImage *nsimage = qt_mac_create_nsimage(pixmapCursor); + nsimage.size = NSSizeFromCGSize((pixmapCursor.size() / pixmapCursor.devicePixelRatioF()).toCGSize()); nativeCursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSZeroPoint]; [nsimage release]; } -- cgit v1.2.3 From 4502999ff054f16aab1fdd99fbd9256b22ecadf9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 12 Oct 2017 21:58:51 -0700 Subject: QRandomGenerator: remove the per-thread buffer Since we're adding a deterministic generator that inherently does not use syscalls, and people should really use that one by default, there is no point in optimizing the secure generator wrt syscalls. Besides, keeping the random data in memory for longer than needed is likely inadviseable. Change-Id: Ib17dde1a1dbb49a7bba8fffd14ed0871117fe930 Reviewed-by: Lars Knoll --- src/corelib/global/qrandom.cpp | 72 +++------------------- src/corelib/global/qrandom_p.h | 1 - .../qrandomgenerator/tst_qrandomgenerator.cpp | 1 - 3 files changed, 8 insertions(+), 66 deletions(-) diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index 9abb9ece7f..17f25ead86 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -129,7 +129,6 @@ namespace { class SystemRandom { public: - enum { EfficientBufferFill = true }; static qssize_t fillBuffer(void *buffer, qssize_t count) Q_DECL_NOTHROW { // getentropy can read at most 256 bytes, so break the reading @@ -217,7 +216,6 @@ qssize_t SystemRandom::fillBuffer(void *buffer, qssize_t count) class SystemRandom { public: - enum { EfficientBufferFill = true }; static qssize_t fillBuffer(void *buffer, qssize_t count) Q_DECL_NOTHROW { auto RtlGenRandom = SystemFunction036; @@ -228,7 +226,6 @@ public: class SystemRandom { public: - enum { EfficientBufferFill = false }; static qssize_t fillBuffer(void *, qssize_t) Q_DECL_NOTHROW { // always use the fallback @@ -362,9 +359,15 @@ static qssize_t fill_cpu(quint32 *buffer, qssize_t count) Q_DECL_NOTHROW return 0; } -static void fill_internal(quint32 *buffer, qssize_t count) - Q_DECL_NOEXCEPT_EXPR(noexcept(SystemRandom::fillBuffer(buffer, count))) +static Q_NEVER_INLINE void fill(void *begin, void *end) + Q_DECL_NOEXCEPT_EXPR(noexcept(SystemRandom::fillBuffer(nullptr, 1))) { + // Verify that the pointers are properly aligned for 32-bit + Q_ASSERT(quintptr(begin) % sizeof(quint32) == 0); + Q_ASSERT(quintptr(end) % sizeof(quint32) == 0); + quint32 *buffer = reinterpret_cast(begin); + qssize_t count = reinterpret_cast(end) - buffer; + if (Q_UNLIKELY(uint(qt_randomdevice_control) & SetRandomData)) { uint value = uint(qt_randomdevice_control) & RandomDataMask; std::fill_n(buffer, count, value); @@ -386,65 +389,6 @@ static void fill_internal(quint32 *buffer, qssize_t count) } } -static Q_NEVER_INLINE void fill(void *buffer, void *bufferEnd) - Q_DECL_NOEXCEPT_EXPR(noexcept(fill_internal(static_cast(buffer), 1))) -{ - struct ThreadState { - enum { - DesiredBufferByteSize = 32, - BufferCount = DesiredBufferByteSize / sizeof(quint32) - }; - quint32 buffer[BufferCount]; - int idx = BufferCount; - }; - - // Verify that the pointers are properly aligned for 32-bit - Q_ASSERT(quintptr(buffer) % sizeof(quint32) == 0); - Q_ASSERT(quintptr(bufferEnd) % sizeof(quint32) == 0); - - quint32 *ptr = reinterpret_cast(buffer); - quint32 * const end = reinterpret_cast(bufferEnd); - -#if defined(Q_COMPILER_THREAD_LOCAL) && !defined(QT_BOOTSTRAPPED) - if (SystemRandom::EfficientBufferFill && (end - ptr) < ThreadState::BufferCount - && uint(qt_randomdevice_control) == 0) { - thread_local ThreadState state; - qssize_t itemsAvailable = ThreadState::BufferCount - state.idx; - - // copy as much as we already have - qssize_t itemsToCopy = qMin(qssize_t(end - ptr), itemsAvailable); - memcpy(ptr, state.buffer + state.idx, size_t(itemsToCopy) * sizeof(*ptr)); - ptr += itemsToCopy; - - if (ptr != end) { - // refill the buffer and try again - fill_internal(state.buffer, ThreadState::BufferCount); - state.idx = 0; - - itemsToCopy = end - ptr; - memcpy(ptr, state.buffer + state.idx, size_t(itemsToCopy) * sizeof(*ptr)); - ptr = end; - } - - // erase what we copied and advance -# ifdef Q_OS_WIN - // Microsoft recommends this - SecureZeroMemory(state.buffer + state.idx, size_t(itemsToCopy) * sizeof(*ptr)); -# else - // We're quite confident the compiler will not optimize this out because - // we're writing to a thread-local buffer - memset(state.buffer + state.idx, 0, size_t(itemsToCopy) * sizeof(*ptr)); -# endif - state.idx += itemsToCopy; - } -#endif // Q_COMPILER_THREAD_LOCAL && !QT_BOOTSTRAPPED - - if (ptr != end) { - // fill directly in the user buffer - fill_internal(ptr, end - ptr); - } -} - /*! \class QRandomGenerator \inmodule QtCore diff --git a/src/corelib/global/qrandom_p.h b/src/corelib/global/qrandom_p.h index 6ac2904e1b..525a73cce4 100644 --- a/src/corelib/global/qrandom_p.h +++ b/src/corelib/global/qrandom_p.h @@ -56,7 +56,6 @@ QT_BEGIN_NAMESPACE enum QRandomGeneratorControl { - SkipMemfill = 1, SkipSystemRNG = 2, SkipHWRNG = 4, SetRandomData = 8, diff --git a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp index 4b38d46317..e583766f21 100644 --- a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp +++ b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp @@ -119,7 +119,6 @@ void tst_QRandomGenerator::generate32_data() QTest::addColumn("control"); QTest::newRow("default") << 0U; #ifdef QT_BUILD_INTERNAL - QTest::newRow("direct") << uint(SkipMemfill); QTest::newRow("system") << uint(SkipHWRNG); # ifdef HAVE_FALLBACK_ENGINE QTest::newRow("fallback") << uint(SkipHWRNG | SkipSystemRNG); -- cgit v1.2.3 From af456842e13ab83cfeb44f3638b62652b201281c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 11 Oct 2017 15:28:40 +0200 Subject: Change QRandomGenerator to have a deterministic mode Now only QRandomGenerator::system() will access the system-wide RNG, which we document to be cryptographically-safe and possibly backed by a true HWRNG. Everything else just wraps a Mersenne Twister. Change-Id: I0a103569c81b4711a649fffd14ec8cd3469425df Reviewed-by: Lars Knoll --- src/corelib/global/qrandom.cpp | 707 +++++++++++++-------- src/corelib/global/qrandom.h | 160 +++-- src/corelib/global/qrandom_p.h | 17 + .../qrandomgenerator/tst_qrandomgenerator.cpp | 334 +++++++--- 4 files changed, 834 insertions(+), 384 deletions(-) diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index 17f25ead86..44b807d745 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -43,10 +43,8 @@ #include "qrandom.h" #include "qrandom_p.h" #include +#include #include -#include - -#include #include @@ -86,6 +84,7 @@ DECLSPEC_IMPORT BOOLEAN WINAPI SystemFunction036(PVOID RandomBuffer, ULONG Rando #undef Q_ASSERT_X #undef Q_ASSERT #define Q_ASSERT(cond) assert(cond) +#define Q_ASSERT_X(cond, x, msg) assert(cond && msg) #if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) # define NDEBUG 1 #endif @@ -122,13 +121,41 @@ static QT_FUNCTION_TARGET(RDRND) qssize_t qt_random_cpu(void *buffer, qssize_t c out: return ptr - reinterpret_cast(buffer); } +#else +static qssize_t qt_random_cpu(void *, qssize_t) +{ + return 0; +} #endif namespace { -#if QT_CONFIG(getentropy) -class SystemRandom +static QBasicMutex globalPRNGMutex; + +struct PRNGLocker +{ + const bool locked; + PRNGLocker(const QRandomGenerator *that) + : locked(that == nullptr || that == QRandomGenerator::global()) + { + if (locked) + globalPRNGMutex.lock(); + } + ~PRNGLocker() + { + if (locked) + globalPRNGMutex.unlock(); + } +}; +} + +enum { + // may be "overridden" by a member enum + FillBufferNoexcept = true +}; + +struct QRandomGenerator::SystemGenerator : public QRandomGenerator::SystemGeneratorBase { -public: +#if QT_CONFIG(getentropy) static qssize_t fillBuffer(void *buffer, qssize_t count) Q_DECL_NOTHROW { // getentropy can read at most 256 bytes, so break the reading @@ -146,94 +173,94 @@ public: Q_UNUSED(ret); return count; } -}; #elif defined(Q_OS_UNIX) -class SystemRandom -{ - static QBasicAtomicInt s_fdp1; // "file descriptor plus 1" - static int openDevice(); -#ifdef Q_CC_GNU - // If it's not GCC or GCC-like, then we'll leak the file descriptor - __attribute__((destructor)) -#endif - static void closeDevice(); - SystemRandom() {} -public: - enum { EfficientBufferFill = true }; - static qssize_t fillBuffer(void *buffer, qssize_t count); -}; -QBasicAtomicInt SystemRandom::s_fdp1 = Q_BASIC_ATOMIC_INITIALIZER(0); + QBasicAtomicInt fdp1; // "file descriptor plus 1" + int openDevice() + { + int fd = fdp1.loadAcquire() - 1; + if (fd != -1) + return fd; + + fd = qt_safe_open("/dev/urandom", O_RDONLY); + if (fd == -1) + fd = qt_safe_open("/dev/random", O_RDONLY | O_NONBLOCK); + if (fd == -1) { + // failed on both, set to -2 so we won't try again + fd = -2; + } -void SystemRandom::closeDevice() -{ - int fd = s_fdp1.loadAcquire() - 1; - if (fd >= 0) - qt_safe_close(fd); -} + int opened_fdp1; + if (fdp1.testAndSetOrdered(0, fd + 1, opened_fdp1)) + return fd; -int SystemRandom::openDevice() -{ - int fd = s_fdp1.loadAcquire() - 1; - if (fd != -1) - return fd; - - fd = qt_safe_open("/dev/urandom", O_RDONLY); - if (fd == -1) - fd = qt_safe_open("/dev/random", O_RDONLY | O_NONBLOCK); - if (fd == -1) { - // failed on both, set to -2 so we won't try again - fd = -2; + // failed, another thread has opened the file descriptor + if (fd >= 0) + qt_safe_close(fd); + return opened_fdp1 - 1; } - int opened_fdp1; - if (s_fdp1.testAndSetOrdered(0, fd + 1, opened_fdp1)) { - if (fd >= 0) { - static const SystemRandom closer; - Q_UNUSED(closer); - } - return fd; +#ifdef Q_CC_GNU + // If it's not GCC or GCC-like, then we'll leak the file descriptor + __attribute__((destructor)) +#endif + static void closeDevice() + { + int fd = static_cast(system()->storage.sys).fdp1.load() - 1; + if (fd >= 0) + qt_safe_close(fd); } - // failed, another thread has opened the file descriptor - if (fd >= 0) - qt_safe_close(fd); - return opened_fdp1 - 1; -} + SystemGenerator() : fdp1 Q_BASIC_ATOMIC_INITIALIZER(0) {} -qssize_t SystemRandom::fillBuffer(void *buffer, qssize_t count) -{ - int fd = openDevice(); - if (Q_UNLIKELY(fd < 0)) - return 0; + qssize_t fillBuffer(void *buffer, qssize_t count) + { + int fd = openDevice(); + if (Q_UNLIKELY(fd < 0)) + return 0; - qint64 n = qt_safe_read(fd, buffer, count); - return qMax(n, 0); // ignore any errors -} -#endif // Q_OS_UNIX + qint64 n = qt_safe_read(fd, buffer, count); + return qMax(n, 0); // ignore any errors + } -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) -class SystemRandom -{ -public: - static qssize_t fillBuffer(void *buffer, qssize_t count) Q_DECL_NOTHROW +#elif defined(Q_OS_WIN) && !defined(Q_OS_WINRT) + qssize_t fillBuffer(void *buffer, qssize_t count) Q_DECL_NOTHROW { auto RtlGenRandom = SystemFunction036; return RtlGenRandom(buffer, ULONG(count)) ? count: 0; } -}; #elif defined(Q_OS_WINRT) -class SystemRandom -{ -public: - static qssize_t fillBuffer(void *, qssize_t) Q_DECL_NOTHROW + qssize_t fillBuffer(void *, qssize_t) Q_DECL_NOTHROW { // always use the fallback return 0; } -}; #endif // Q_OS_WINRT -} // unnamed namespace + + static SystemGenerator &self() + { + return static_cast(QRandomGenerator::system()->storage.sys); + } + void generate(quint32 *begin, quint32 *end) Q_DECL_NOEXCEPT_EXPR(FillBufferNoexcept); + + // For std::mersenne_twister_engine implementations that use something + // other than quint32 (unsigned int) to fill their buffers. + template void generate(T *begin, T *end) + { + Q_STATIC_ASSERT(sizeof(T) >= sizeof(quint32)); + if (sizeof(T) == sizeof(quint32)) { + // Microsoft Visual Studio uses unsigned long, but that's still 32-bit + generate(reinterpret_cast(begin), reinterpret_cast(end)); + } else { + // Slow path. Fix your C++ library. + std::generate(begin, end, [this]() { + quint32 datum; + generate(&datum, &datum + 1); + return datum; + }); + } + } +}; #if defined(Q_OS_WIN) static void fallback_update_seed(unsigned) {} @@ -252,6 +279,7 @@ static void fallback_update_seed(unsigned) {} static void fallback_fill(quint32 *, qssize_t) Q_DECL_NOTHROW { // no fallback necessary, getentropy cannot fail under normal circumstances + Q_UNREACHABLE(); } #elif defined(Q_OS_BSD4) static void fallback_update_seed(unsigned) {} @@ -347,26 +375,11 @@ static void fallback_fill(quint32 *ptr, qssize_t left) Q_DECL_NOTHROW } #endif -static qssize_t fill_cpu(quint32 *buffer, qssize_t count) Q_DECL_NOTHROW -{ -#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND) - if (qCpuHasFeature(RDRND) && (uint(qt_randomdevice_control) & SkipHWRNG) == 0) - return qt_random_cpu(buffer, count); -#else - Q_UNUSED(buffer); - Q_UNUSED(count); -#endif - return 0; -} - -static Q_NEVER_INLINE void fill(void *begin, void *end) - Q_DECL_NOEXCEPT_EXPR(noexcept(SystemRandom::fillBuffer(nullptr, 1))) +Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, quint32 *end) + Q_DECL_NOEXCEPT_EXPR(FillBufferNoexcept) { - // Verify that the pointers are properly aligned for 32-bit - Q_ASSERT(quintptr(begin) % sizeof(quint32) == 0); - Q_ASSERT(quintptr(end) % sizeof(quint32) == 0); - quint32 *buffer = reinterpret_cast(begin); - qssize_t count = reinterpret_cast(end) - buffer; + quint32 *buffer = begin; + qssize_t count = end - begin; if (Q_UNLIKELY(uint(qt_randomdevice_control) & SetRandomData)) { uint value = uint(qt_randomdevice_control) & RandomDataMask; @@ -374,10 +387,13 @@ static Q_NEVER_INLINE void fill(void *begin, void *end) return; } - qssize_t filled = fill_cpu(buffer, count); + qssize_t filled = 0; + if (qt_has_hwrng() && (uint(qt_randomdevice_control) & SkipHWRNG) == 0) + filled += qt_random_cpu(buffer, count); + if (filled != count && (uint(qt_randomdevice_control) & SkipSystemRNG) == 0) { qssize_t bytesFilled = - SystemRandom::fillBuffer(buffer + filled, (count - filled) * qssize_t(sizeof(*buffer))); + fillBuffer(buffer + filled, (count - filled) * qssize_t(sizeof(*buffer))); filled += bytesFilled / qssize_t(sizeof(*buffer)); } if (filled) @@ -392,85 +408,153 @@ static Q_NEVER_INLINE void fill(void *begin, void *end) /*! \class QRandomGenerator \inmodule QtCore + \reentrant \since 5.10 \brief The QRandomGenerator class allows one to obtain random values from a - high-quality, seed-less Random Number Generator. + high-quality Random Number Generator. QRandomGenerator may be used to generate random values from a high-quality - random number generator. Unlike qrand(), QRandomGenerator does not need to be - seeded. That also means it is not possible to force it to produce a - reliable sequence, which may be needed for debugging. + random number generator. Like the C++ random engines, QRandomGenerator can + be seeded with user-provided values through the constructor. + When seeded, the sequence of numbers generated by this + class is deterministic. That is to say, given the same seed data, + QRandomGenerator will generate the same sequence of numbers. But given + different seeds, the results should be considerably different. + + QRandomGenerator::global() returns a global instance of QRandomGenerator + that Qt will ensure to be securely seeded. This object is thread-safe, may + be shared for most uses, and is always seeded from + QRandomGenerator::system() + + QRandomGenerator::system() may be used to access the system's + cryptographically-safe random generator. On Unix systems, it's equivalent + to reading from \c {/dev/urandom} or the \c {getrandom()} or \c + {getentropy()} system calls. The class can generate 32-bit or 64-bit quantities, or fill an array of those. The most common way of generating new values is to call the generate(), generate64() or fillRange() functions. One would use it as: \code - quint32 value = QRandomGenerator::generate(); + quint32 value = QRandomGenerator::global()->generate(); + \endcode + + Additionally, it provides a floating-point function generateDouble() that + returns a number in the range [0, 1) (that is, inclusive of zero and + exclusive of 1). There's also a set of convenience functions that + facilitate obtaining a random number in a bounded, integral range. + + \section1 Seeding and determinism + + QRandomGenerator may be seeded with specific seed data. When that is done, + the numbers generated by the object will always be the same, as in the + following example: + + \code + QRandomGenerator prng1(1234), prng2(1234); + Q_ASSERT(prng1.generate32() == prng2.generate32()); + Q_ASSERT(prng1.generate64() == prng2.generate64()); \endcode - Additionally, it provides a floating-point function generateDouble() that returns - a number in the range [0, 1) (that is, inclusive of zero and exclusive of - 1). There's also a set of convenience functions that facilitate obtaining a - random number in a bounded, integral range. + The seed data takes the form of one or more 32-bit words. The ideal seed + size is approximately equal to the size of the QRandomGenerator class + itself. Due to mixing of the seed data, QRandomGenerator cannot guarantee + that distinct seeds will produce different sequences. + + QRandomGenerator::global() is always seeded from + QRandomGenerator::system(), so it's not possible to make it produce + identical sequences. - \warning This class is not suitable for bulk data creation. See below for the - technical reasons. + \section1 Bulk data - \section1 Frequency and entropy exhaustion + When operating in deterministic mode, QRandomGenerator may be used for bulk + data generation. In fact, applications that do not need + cryptographically-secure or true random data are advised to use a regular + QRandomGenerator instead of QRandomGenerator::system() for their random + data needs. - QRandomGenerator does not need to be seeded and instead uses operating system - or hardware facilities to generate random numbers. On some systems and with - certain hardware, those facilities are true Random Number Generators. - However, if they are true RNGs, those facilities have finite entropy source - and thus may fail to produce any results if the entropy pool is exhausted. + For ease of use, QRandomGenerator provides a global object that can + be easily used, as in the following example: + + \code + int x = QRandomGenerator::global()->generate32(); + int y = QRandomGenerator::global()->generate32(); + int w = QRandomGenerator::global()->bounded(16384); + int h = QRandomGenerator::global()->bounded(16384); + \endcode + + \section1 System-wide random number generator + + QRandomGenerator::system() may be used to access the system-wide random + number generator, which is cryptographically-safe on all systems that Qt + runs on. This function will use hardware facilities to generate random + numbers where available. On such systems, those facilities are true Random + Number Generators. However, if they are true RNGs, those facilities have + finite entropy sources and thus may fail to produce any results if their + entropy pool is exhausted. If that happens, first the operating system then QRandomGenerator will fall back to Pseudo Random Number Generators of decreasing qualities (Qt's - fallback generator being the simplest). Therefore, QRandomGenerator should - not be used for high-frequency random number generation, lest the entropy - pool become empty. As a rule of thumb, this class should not be called upon - to generate more than a kilobyte per second of random data (note: this may - vary from system to system). + fallback generator being the simplest). Whether those generators are still + of cryptographic quality is implementation-defined. Therefore, + QRandomGenerator::system() should not be used for high-frequency random + number generation, lest the entropy pool become empty. As a rule of thumb, + this class should not be called upon to generate more than a kilobyte per + second of random data (note: this may vary from system to system). If an application needs true RNG data in bulk, it should use the operating - system facilities (such as \c{/dev/random} on Unix systems) directly and - wait for entropy to become available. If true RNG is not required, - applications should instead use a PRNG engines and can use QRandomGenerator to - seed those. + system facilities (such as \c{/dev/random} on Linux) directly and wait for + entropy to become available. If the application requires PRNG engines of + cryptographic quality but not of true randomness, + QRandomGenerator::system() may still be used (see section below). + + If neither a true RNG nor a cryptographically secure PRNG are required, + applications should instead use PRNG engines like QRandomGenerator's + deterministic mode and those from the C++ Standard Library. + QRandomGenerator::system() can be used to seed those. + + \section2 Fallback quality + + QRandomGenerator::system() uses the operating system facilities to obtain + random numbers, which attempt to collect real entropy from the surrounding + environment to produce true random numbers. However, it's possible that the + entropy pool becomes exhausted, in which case the operating system will + fall back to a pseudo-random engine for a time. Under no circumstances will + QRandomGenerator::system() block, waiting for more entropy to be collected. + + The following operating systems guarantee that the results from their + random-generation API will be of at least cryptographically-safe quality, + even if the entropy pool is exhausted: Apple OSes (Darwin), BSDs, Linux, + Windows. Barring a system installation problem (such as \c{/dev/urandom} + not being readable by the current process), QRandomGenerator::system() will + therefore have the same guarantees. + + On other operating systems, QRandomGenerator will fall back to a PRNG of + good numeric distribution, but it cannot guarantee proper seeding in all + cases. Please consult the OS documentation for more information. + + Applications that require QRandomGenerator not to fall back to + non-cryptographic quality generators are advised to check their operating + system documentation or restrict their deployment to one of the above. + + \section1 Reentrancy and thread-safety + + QRandomGenerator is reentrant, meaning that multiple threads can operate on + this class at the same time, so long as they operate on different objects. + If multiple threads need to share one PRNG sequence, external locking by a + mutex is required. + + The exceptions are the objects returned by QRandomGenerator::global() and + QRandomGenerator::system(): those objects are thread-safe and may be used + by any thread without external locking. Note that thread-safety does not + extend to copying those objects: they should always be used by reference. \section1 Standard C++ Library compatibility - QRandomGenerator is modeled after - \c{\l{http://en.cppreference.com/w/cpp/numeric/random/random_device}{std::random_device}} - and may be used in almost all contexts that the Standard Library can. - QRandomGenerator attempts to use either the same engine that backs - \c{std::random_device} or a better one. Note that \c{std::random_device} is - also allowed to fail if the source entropy pool becomes exhausted, in which - case it will throw an exception. QRandomGenerator never throws, but may abort - program execution instead. - - Like the Standard Library class, QRandomGenerator can be used to seed Standard - Library deterministic random engines from \c{}, such as the - Mersenne Twister. Unlike \c{std::random_device}, QRandomGenerator also - implements the API of - \c{\l{http://en.cppreference.com/w/cpp/numeric/random/seed_seq}{std::seed_seq}}, - allowing it to seed the deterministic engines directly. - - The following code can be used to create and seed the - implementation-defined default deterministic PRNG, then use it to fill a - block range: - - \code - QRandomGenerator rd; - std::default_random_engine rng(rd); - std::generate(block.begin(), block.end(), rng); - - // equivalent to: - for (auto &v : block) - v = rng(); - \endcode + QRandomGenerator is modeled after the requirements for random number + engines in the C++ Standard Library and may be used in almost all contexts + that the Standard Library engines can. QRandomGenerator is also compatible with the uniform distribution classes \c{std::uniform_int_distribution} and \c{std:uniform_real_distribution}, as @@ -479,57 +563,101 @@ static Q_NEVER_INLINE void fill(void *begin, void *end) [1, 2.5): \code - QRandomGenerator64 rd; std::uniform_real_distribution dist(1, 2.5); - return dist(rd); + return dist(*QRandomGenerator::global()); \endcode - Note the use of the QRandomGenerator64 class instead of QRandomGenerator to - obtain 64 bits of random data in a single call, though it is not required - to make the algorithm work (the Standard Library functions will make as - many calls as required to obtain enough bits of random data for the desired - range). - \sa QRandomGenerator64, qrand() */ /*! - \fn QRandomGenerator::QRandomGenerator() - \internal - Defaulted constructor, does nothing. + \fn QRandomGenerator::QRandomGenerator(quint32 seed) + + Initializes this QRandomGenerator object with the value \a seed as + the seed. Two objects constructed with the same seed value will + produce the same number sequence. */ /*! - \typedef QRandomGenerator::result_type + \fn QRandomGenerator::QRandomGenerator(const quint32 (&seedBuffer)[N]) + \overload - A typedef to the type that operator()() returns. That is, quint32. + Initializes this QRandomGenerator object with the values found in the + array \a seedBuffer as the seed. Two objects constructed or reseeded with + the same seed value will produce the same number sequence. + */ - \sa operator()() +/*! + \fn QRandomGenerator::QRandomGenerator(const quint32 *seedBuffer, qssize_t len) + \overload + + Initializes this QRandomGenerator object with \a len values found in + the array \a seedBuffer as the seed. Two objects constructed or reseeded + with the same seed value will produce the same number sequence. + + This constructor is equivalent to: + \code + std::seed_seq sseq(seedBuffer, seedBuffer + len); + QRandomGenerator generator(sseq); + \endcode */ /*! - \fn result_type QRandomGenerator::operator()() + \fn QRandomGenerator::QRandomGenerator(const quint32 *begin, const quin32 *end) + \overload - Generates a 32-bit random quantity and returns it. + Initializes this QRandomGenerator object with the values found in the range + from \a begin to \a end as the seed. Two objects constructed or reseeded + with the same seed value will produce the same number sequence. - \sa QRandomGenerator::generate(), QRandomGenerator::generate64() + This constructor is equivalent to: + \code + std::seed_seq sseq(begin, end); + QRandomGenerator generator(sseq); + \endcode + */ + +/*! + \fn QRandomGenerator::QRandomGenerator(std::seed_seq &sseq) + \overload + + Initializes this QRandomGenerator object with the seed sequence \a + sseq as the seed. Two objects constructed or reseeded with the same seed + value will produce the same number sequence. */ /*! - \fn double QRandomGenerator::entropy() const + \fn QRandomGenerator::QRandomGenerator(const QRandomGenerator &other) - Returns the estimate of the entropy in the random generator source. + Creates a copy of the generator state in the \a other object. If \a other is + QRandomGenerator::system() or a copy of that, this object will also read + from the operating system random-generating facilities. In that case, the + sequences generated by the two objects will be different. - This function exists to comply with the Standard Library requirements for - \c{\l{http://en.cppreference.com/w/cpp/numeric/random/random_device}{std::random_device}} - but it does not and cannot ever work. It is not possible to obtain a - reliable entropy value in a shared entropy pool in a multi-tasking system, - as other processes or threads may use that entropy. Any value non-zero - value that this function could return would be obsolete by the time the - user code reached it. + In all other cases, the new QRandomGenerator object will start at the same + position in the deterministic sequence as the \a other object was. Both + objects will generate the same sequence from this point on. - Since QRandomGenerator attempts to use a hardware Random Number Generator, - this function always returns 0.0. + For that reason, it is not adviseable to create a copy of + QRandomGenerator::global(). If one needs an exclusive deterministic + generator, consider instead creating a new object and seeding it from + QRandomGenerator::system(). + */ + +/*! + \typedef QRandomGenerator::result_type + + A typedef to the type that operator()() returns. That is, quint32. + + \sa operator()() + */ + +/*! + \fn result_type QRandomGenerator::operator()() + + Generates a 32-bit random quantity and returns it. + + \sa generate(), generate64() */ /*! @@ -537,7 +665,7 @@ static Q_NEVER_INLINE void fill(void *begin, void *end) Returns the minimum value that QRandomGenerator may ever generate. That is, 0. - \sa max(), QRandomGenerator64::max() + \sa max(), QRandomGenerator64::min() */ /*! @@ -556,7 +684,7 @@ static Q_NEVER_INLINE void fill(void *begin, void *end) and \a end. This function is equivalent to (and is implemented as): \code - std::generate(begin, end, []() { return generate(); }); + std::generate(begin, end, [this]() { return generate(); }); \endcode This function complies with the requirements for the function @@ -569,7 +697,7 @@ static Q_NEVER_INLINE void fill(void *begin, void *end) quantities, one can write: \code - std::generate(begin, end, []() { return QRandomGenerator::generate64(); }); + std::generate(begin, end, []() { return QRandomGenerator::global()->generate64(); }); \endcode If the range refers to contiguous memory (such as an array or the data from @@ -647,26 +775,26 @@ static Q_NEVER_INLINE void fill(void *begin, void *end) */ /*! - \fn qreal QRandomGenerator::bounded(qreal sup) + \fn qreal QRandomGenerator::bounded(qreal highest) Generates one random qreal in the range between 0 (inclusive) and \a - sup (exclusive). This function is equivalent to and is implemented as: + highest (exclusive). This function is equivalent to and is implemented as: \code - return generateDouble() * sup; + return generateDouble() * highest; \endcode \sa generateDouble(), bounded() */ /*! - \fn quint32 QRandomGenerator::bounded(quint32 sup) + \fn quint32 QRandomGenerator::bounded(quint32 highest) \overload Generates one random 32-bit quantity in the range between 0 (inclusive) and - \a sup (exclusive). The same result may also be obtained by using + \a highest (exclusive). The same result may also be obtained by using \c{\l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{std::uniform_int_distribution}} - with parameters 0 and \c{sup - 1}. That class can also be used to obtain + with parameters 0 and \c{highest - 1}. That class can also be used to obtain quantities larger than 32 bits. For example, to obtain a value between 0 and 255 (inclusive), one would write: @@ -685,11 +813,11 @@ static Q_NEVER_INLINE void fill(void *begin, void *end) */ /*! - \fn quint32 QRandomGenerator::bounded(int sup) + \fn quint32 QRandomGenerator::bounded(int highest) \overload Generates one random 32-bit quantity in the range between 0 (inclusive) and - \a sup (exclusive). \a sup must not be negative. + \a highest (exclusive). \a highest must not be negative. Note that this function cannot be used to obtain values in the full 32-bit range of int. Instead, use generate() and cast to int. @@ -698,13 +826,13 @@ static Q_NEVER_INLINE void fill(void *begin, void *end) */ /*! - \fn quint32 QRandomGenerator::bounded(quint32 min, quint32 sup) + \fn quint32 QRandomGenerator::bounded(quint32 lowest, quint32 highest) \overload - Generates one random 32-bit quantity in the range between \a min (inclusive) - and \a sup (exclusive). The same result may also be obtained by using + Generates one random 32-bit quantity in the range between \a lowest (inclusive) + and \a highest (exclusive). The same result may also be obtained by using \c{\l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{std::uniform_int_distribution}} - with parameters \a min and \c{\a sup - 1}. That class can also be used to + with parameters \a lowest and \c{\a highest - 1}. That class can also be used to obtain quantities larger than 32 bits. For example, to obtain a value between 1000 (incl.) and 2000 (excl.), one @@ -722,11 +850,11 @@ static Q_NEVER_INLINE void fill(void *begin, void *end) */ /*! - \fn quint32 QRandomGenerator::bounded(int min, int sup) + \fn quint32 QRandomGenerator::bounded(int lowest, int highest) \overload - Generates one random 32-bit quantity in the range between \a min - (inclusive) and \a sup (exclusive), both of which may be negative. + Generates one random 32-bit quantity in the range between \a lowest + (inclusive) and \a highest (exclusive), both of which may be negative. Note that this function cannot be used to obtain values in the full 32-bit range of int. Instead, use generate() and cast to int. @@ -734,6 +862,54 @@ static Q_NEVER_INLINE void fill(void *begin, void *end) \sa generate(), generate64(), generateDouble() */ +/*! + \fn QRandomGenerator *QRandomGenerator::system() + \threadsafe + + Returns a pointer to a shared QRandomGenerator that always uses the + facilities provided by the operating system to generate random numbers. The + system facilities are considered to be cryptographically safe on at least + the following operating systems: Apple OSes (Darwin), BSDs, Linux, Windows. + That may also be the case on other operating systems. + + They are also possibly backed by a true hardware random number generator. + For that reason, the QRandomGenerator returned by this function should not + be used for bulk data generation. Instead, use it to seed QRandomGenerator + or a random engine from the header. + + The object returned by this function is thread-safe and may be used in any + thread without locks. It may also be copied and the resulting + QRandomGenerator will also access the operating system facilities, but they + will not generate the same sequence. + + \sa global() +*/ + +/*! + \fn QRandomGenerator *QRandomGenerator::global() + \threadsafe + + Returns a pointer to a shared QRandomGenerator that was seeded using + QRandomGenerator::system(). This function should be used to create random data + without the expensive creation of a securely-seeded QRandomGenerator for a + specific use or storing the rather large QRandomGenerator object. + large QRandomGenerator object. + + For example, the following creates a random RGB color: + + \code + return QColor::fromRgb(QRandomGenerator::global()->generate()); + \endcode + + Accesses to this object are thread-safe and it may therefore be used in any + thread without locks. The object may also be copied and the sequence + produced by the copy will be the same as the shared object will produce. + Note, however, that if there are other threads accessing the global object, + those threads may obtain samples at unpredictable intervals. + + \sa system() +*/ + /*! \class QRandomGenerator64 \inmodule QtCore @@ -755,10 +931,11 @@ static Q_NEVER_INLINE void fill(void *begin, void *end) */ /*! - \fn QRandomGenerator64::QRandomGenerator64() - \internal - Defaulted constructor, does nothing. - */ + \fn QRandomGenerator64::QRandomGenerator64(const QRandomGenerator &other) + \internal + + Creates a copy. +*/ /*! \typedef QRandomGenerator64::result_type @@ -793,80 +970,78 @@ static Q_NEVER_INLINE void fill(void *begin, void *end) \sa QRandomGenerator::generate(), QRandomGenerator::generate64() */ -/*! - \fn double QRandomGenerator64::entropy() const - - Returns the estimate of the entropy in the random generator source. - - This function exists to comply with the Standard Library requirements for - \c{\l{http://en.cppreference.com/w/cpp/numeric/random/random_device}{std::random_device}} - but it does not and cannot ever work. It is not possible to obtain a - reliable entropy value in a shared entropy pool in a multi-tasking system, - as other processes or threads may use that entropy. Any value non-zero - value that this function could return would be obsolete by the time the - user code reached it. - - Since QRandomGenerator64 attempts to use a hardware Random Number Generator, - this function always returns 0.0. - */ - -/*! - \fn result_type QRandomGenerator64::min() - - Returns the minimum value that QRandomGenerator64 may ever generate. That is, 0. - - \sa max(), QRandomGenerator::max() - */ +inline QRandomGenerator::Storage::Storage() +{ + // nothing +} -/*! - \fn result_type QRandomGenerator64::max() +inline QRandomGenerator64::QRandomGenerator64(System s) + : QRandomGenerator(s) +{ +} - Returns the maximum value that QRandomGenerator64 may ever generate. That is, - \c {std::numeric_limits::max()}. +QRandomGenerator64 *QRandomGenerator64::system() +{ + static QRandomGenerator64 system(System{}); + return &system; +} - \sa min(), QRandomGenerator::max() - */ +QRandomGenerator64 *QRandomGenerator64::global() +{ + PRNGLocker lock(nullptr); + static QRandomGenerator64 global(System{}); + if (global.type == SystemRNG) { + // seed with the system CSPRNG and change the type + new (&global.storage.engine()) RandomEngine(static_cast(system()->storage.sys)); + global.type = MersenneTwister; + } -/*! - Generates one 32-bit random value and returns it. + return &global; +} - Note about casting to a signed integer: all bits returned by this function - are random, so there's a 50% chance that the most significant bit will be - set. If you wish to cast the returned value to int and keep it positive, - you should mask the sign bit off: +/// \internal +inline QRandomGenerator::QRandomGenerator(System) + : type(SystemRNG) +{ + Q_STATIC_ASSERT(sizeof(storage) >= sizeof(SystemGenerator)); + new (&storage) SystemGenerator(); +} - \code - int value = QRandomGenerator::generate() & std::numeric_limits::max(); - \endcode - \sa generate64(), generateDouble() - */ -quint32 QRandomGenerator::generate() +QRandomGenerator::QRandomGenerator(const QRandomGenerator &other) + : type(other.type) { - quint32 ret; - fill(&ret, &ret + 1); - return ret; + if (type != SystemRNG) { + PRNGLocker lock(&other); + storage.engine() = other.storage.engine(); + } } -/*! - Generates one 64-bit random value and returns it. +QRandomGenerator &QRandomGenerator::operator=(const QRandomGenerator &other) +{ + if (this != &other) { + if (Q_UNLIKELY(this == system()) || Q_UNLIKELY(this == global())) + qFatal("Attempted to overwrite a QRandomGenerator to system() or global()."); - Note about casting to a signed integer: all bits returned by this function - are random, so there's a 50% chance that the most significant bit will be - set. If you wish to cast the returned value to qint64 and keep it positive, - you should mask the sign bit off: + if ((type = other.type) != SystemRNG) { + PRNGLocker lock(&other); + storage.engine() = other.storage.engine(); + } + } + return *this; +} - \code - qint64 value = QRandomGenerator::generate64() & std::numeric_limits::max(); - \endcode +QRandomGenerator::QRandomGenerator(std::seed_seq &sseq) Q_DECL_NOTHROW + : type(MersenneTwister) +{ + new (&storage.engine()) RandomEngine(sseq); +} - \sa generate(), generateDouble(), QRandomGenerator64 - */ -quint64 QRandomGenerator::generate64() +QRandomGenerator::QRandomGenerator(const quint32 *begin, const quint32 *end) + : type(MersenneTwister) { - quint64 ret; - fill(&ret, &ret + 1); - return ret; + std::seed_seq s(begin, end); + new (&storage.engine()) RandomEngine(s); } /*! @@ -875,9 +1050,19 @@ quint64 QRandomGenerator::generate64() Fills the range pointed by \a buffer and \a bufferEnd with 32-bit random values. The buffer must be correctly aligned. */ -void QRandomGenerator::fillRange_helper(void *buffer, void *bufferEnd) +void QRandomGenerator::_fillRange(void *buffer, void *bufferEnd) { - fill(buffer, bufferEnd); + // Verify that the pointers are properly aligned for 32-bit + Q_ASSERT(quintptr(buffer) % sizeof(quint32) == 0); + Q_ASSERT(quintptr(bufferEnd) % sizeof(quint32) == 0); + quint32 *begin = static_cast(buffer); + quint32 *end = static_cast(bufferEnd); + + if (type == SystemRNG || Q_UNLIKELY(uint(qt_randomdevice_control) & (UseSystemRNG|SetRandomData))) + return SystemGenerator::self().generate(begin, end); + + PRNGLocker lock(this); + std::generate(begin, end, [this]() { return storage.engine()(); }); } #if defined(Q_OS_ANDROID) && (__ANDROID_API__ < 21) diff --git a/src/corelib/global/qrandom.h b/src/corelib/global/qrandom.h index 049495d4e8..e6fd4f02de 100644 --- a/src/corelib/global/qrandom.h +++ b/src/corelib/global/qrandom.h @@ -42,6 +42,7 @@ #include #include // for std::generate +#include // for std::mt19937 QT_BEGIN_NAMESPACE @@ -51,19 +52,37 @@ class QRandomGenerator template using IfValidUInt = typename std::enable_if::value && sizeof(UInt) >= sizeof(uint), bool>::type; public: - static QRandomGenerator system() { return {}; } - static QRandomGenerator global() { return {}; } - QRandomGenerator() = default; - - // ### REMOVE BEFORE 5.10 - QRandomGenerator *operator->() { return this; } - static quint32 get32() { return generate(); } - static quint64 get64() { return generate64(); } - static qreal getReal() { return generateDouble(); } - - static Q_CORE_EXPORT quint32 generate(); - static Q_CORE_EXPORT quint64 generate64(); - static double generateDouble() + QRandomGenerator(quint32 seed = 1) + : QRandomGenerator(&seed, 1) + {} + template QRandomGenerator(const quint32 (&seedBuffer)[N]) + : QRandomGenerator(seedBuffer, seedBuffer + N) + {} + QRandomGenerator(const quint32 *seedBuffer, qssize_t len) + : QRandomGenerator(seedBuffer, seedBuffer + len) + {} + Q_CORE_EXPORT QRandomGenerator(std::seed_seq &sseq) Q_DECL_NOTHROW; + Q_CORE_EXPORT QRandomGenerator(const quint32 *begin, const quint32 *end); + + // copy constructor & assignment operator (move unnecessary) + Q_CORE_EXPORT QRandomGenerator(const QRandomGenerator &other); + Q_CORE_EXPORT QRandomGenerator &operator=(const QRandomGenerator &other); + + quint32 generate() + { + quint32 ret; + fillRange(&ret, 1); + return ret; + } + + quint64 generate64() + { + quint32 buf[2]; + fillRange(buf); + return buf[0] | (quint64(buf[1]) << 32); + } + + double generateDouble() { // IEEE 754 double precision has: // 1 bit sign @@ -77,87 +96,144 @@ public: return double(x) / double(limit); } - static qreal bounded(qreal sup) + double bounded(double highest) { - return generateDouble() * sup; + return generateDouble() * highest; } - static quint32 bounded(quint32 sup) + quint32 bounded(quint32 highest) { quint64 value = generate(); - value *= sup; + value *= highest; value /= (max)() + quint64(1); return quint32(value); } - static int bounded(int sup) + int bounded(int highest) { - return int(bounded(quint32(sup))); + return int(bounded(quint32(highest))); } - static quint32 bounded(quint32 min, quint32 sup) + quint32 bounded(quint32 lowest, quint32 highest) { - return bounded(sup - min) + min; + return bounded(highest - lowest) + lowest; } - static int bounded(int min, int sup) + int bounded(int lowest, int highest) { - return bounded(sup - min) + min; + return bounded(highest - lowest) + lowest; } template = true> - static void fillRange(UInt *buffer, qssize_t count) + void fillRange(UInt *buffer, qssize_t count) { - fillRange_helper(buffer, buffer + count); + _fillRange(buffer, buffer + count); } template = true> - static void fillRange(UInt (&buffer)[N]) + void fillRange(UInt (&buffer)[N]) { - fillRange_helper(buffer, buffer + N); + _fillRange(buffer, buffer + N); } // API like std::seed_seq template void generate(ForwardIterator begin, ForwardIterator end) { - auto generator = static_cast(&QRandomGenerator::generate); - std::generate(begin, end, generator); + std::generate(begin, end, [this]() { return generate(); }); } void generate(quint32 *begin, quint32 *end) { - fillRange_helper(begin, end); + _fillRange(begin, end); } - // API like std::random_device + // API like std:: random engines typedef quint32 result_type; result_type operator()() { return generate(); } - double entropy() const Q_DECL_NOTHROW { return 0.0; } static Q_DECL_CONSTEXPR result_type min() { return (std::numeric_limits::min)(); } static Q_DECL_CONSTEXPR result_type max() { return (std::numeric_limits::max)(); } + static inline QRandomGenerator *system(); + static inline QRandomGenerator *global(); + +protected: + enum System {}; + QRandomGenerator(System); + private: - static Q_CORE_EXPORT void fillRange_helper(void *buffer, void *bufferEnd); + Q_CORE_EXPORT void _fillRange(void *buffer, void *bufferEnd); + + friend class QRandomGenerator64; + struct SystemGeneratorBase {}; + struct SystemGenerator; + typedef std::mt19937 RandomEngine; + + union Storage { + SystemGeneratorBase sys; +#ifdef Q_COMPILER_UNRESTRICTED_UNIONS + RandomEngine twister; + RandomEngine &engine() { return twister; } + const RandomEngine &engine() const { return twister; } +#else + std::aligned_storage::type buffer; + RandomEngine &engine() { return reinterpret_cast(buffer); } + const RandomEngine &engine() const { return reinterpret_cast(buffer); } +#endif + + Q_STATIC_ASSERT_X(std::is_trivially_destructible::value, + "std::mersenne_twister not trivially destructible as expected"); + Storage(); + }; + uint type; + Storage storage; }; -class QRandomGenerator64 +class QRandomGenerator64 : public QRandomGenerator { + QRandomGenerator64(System); public: - static QRandomGenerator64 system() { return {}; } - static QRandomGenerator64 global() { return {}; } - QRandomGenerator64() = default; - - static quint64 generate() { return QRandomGenerator::generate64(); } + // unshadow generate() overloads, since we'll override. + using QRandomGenerator::generate; + quint64 generate() { return generate64(); } - // API like std::random_device typedef quint64 result_type; - result_type operator()() { return QRandomGenerator::generate64(); } - double entropy() const Q_DECL_NOTHROW { return 0.0; } + result_type operator()() { return generate64(); } + +#ifndef Q_QDOC + QRandomGenerator64(quint32 seed = 1) + : QRandomGenerator(seed) + {} + template QRandomGenerator64(const quint32 (&seedBuffer)[N]) + : QRandomGenerator(seedBuffer) + {} + QRandomGenerator64(const quint32 *seedBuffer, qssize_t len) + : QRandomGenerator(seedBuffer, len) + {} + QRandomGenerator64(std::seed_seq &sseq) Q_DECL_NOTHROW + : QRandomGenerator(sseq) + {} + QRandomGenerator64(const quint32 *begin, const quint32 *end) + : QRandomGenerator(begin, end) + {} + QRandomGenerator64(const QRandomGenerator &other) : QRandomGenerator(other) {} + static Q_DECL_CONSTEXPR result_type min() { return (std::numeric_limits::min)(); } static Q_DECL_CONSTEXPR result_type max() { return (std::numeric_limits::max)(); } + static Q_CORE_EXPORT QRandomGenerator64 *system(); + static Q_CORE_EXPORT QRandomGenerator64 *global(); +#endif // Q_QDOC }; +inline QRandomGenerator *QRandomGenerator::system() +{ + return QRandomGenerator64::system(); +} + +inline QRandomGenerator *QRandomGenerator::global() +{ + return QRandomGenerator64::global(); +} QT_END_NAMESPACE diff --git a/src/corelib/global/qrandom_p.h b/src/corelib/global/qrandom_p.h index 525a73cce4..917a91098e 100644 --- a/src/corelib/global/qrandom_p.h +++ b/src/corelib/global/qrandom_p.h @@ -52,10 +52,12 @@ // #include "qglobal_p.h" +#include QT_BEGIN_NAMESPACE enum QRandomGeneratorControl { + UseSystemRNG = 1, SkipSystemRNG = 2, SkipHWRNG = 4, SetRandomData = 8, @@ -64,6 +66,11 @@ enum QRandomGeneratorControl { RandomDataMask = 0xfffffff0 }; +enum RNGType { + SystemRNG = 0, + MersenneTwister = 1 +}; + #if defined(QT_BUILD_INTERNAL) && defined(QT_BUILD_CORE_LIB) Q_CORE_EXPORT QBasicAtomicInteger qt_randomdevice_control = Q_BASIC_ATOMIC_INITIALIZER(0U); #elif defined(QT_BUILD_INTERNAL) @@ -72,6 +79,16 @@ extern Q_CORE_EXPORT QBasicAtomicInteger qt_randomdevice_control; enum { qt_randomdevice_control = 0 }; #endif +inline bool qt_has_hwrng() +{ +#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND) + return qCpuHasFeature(RDRND); +#else + return false; +#endif +} + + QT_END_NAMESPACE #endif // QRANDOM_P_H diff --git a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp index e583766f21..f9b3ce5390 100644 --- a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp +++ b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp @@ -43,8 +43,8 @@ #define COMMA , #define QVERIFY_3TIMES(statement) \ do {\ - if (!QTest::qVerify(static_cast(statement), #statement, "1st try", __FILE__, __LINE__))\ - if (!QTest::qVerify(static_cast(statement), #statement, "2nd try", __FILE__, __LINE__))\ + if (!static_cast(statement))\ + if (!static_cast(statement))\ if (!QTest::qVerify(static_cast(statement), #statement, "3rd try", __FILE__, __LINE__))\ return;\ } while (0) @@ -71,6 +71,13 @@ public slots: void cleanup() { setRNGControl(0); } private slots: + void basics(); + void knownSequence(); + void copying(); + void copyingGlobal(); + void copyingSystem(); + void systemRng(); + void generate32_data(); void generate32(); void generate64_data() { generate32_data(); } @@ -110,18 +117,154 @@ private slots: void stdRandomDistributions(); }; +// The first 20 results of the sequence: +static const quint32 defaultRngResults[] = { + 853323747U, 2396352728U, 3025954838U, 2985633182U, 2815751046U, + 340588426U, 3587208406U, 298087538U, 2912478009U, 3642122814U, + 3202916223U, 799257577U, 1872145992U, 639469699U, 3201121432U, + 2388658094U, 1735523408U, 2215232359U, 668106566U, 2554687763U +}; + + using namespace std; QT_WARNING_DISABLE_GCC("-Wfloat-equal") QT_WARNING_DISABLE_CLANG("-Wfloat-equal") +struct RandomGenerator : public QRandomGenerator +{ + RandomGenerator(uint control) + : QRandomGenerator(control ? + QRandomGenerator(control & RandomDataMask) : + *QRandomGenerator::global()) + { + setRNGControl(control); + } +}; + +void tst_QRandomGenerator::basics() +{ + // default constructible + QRandomGenerator rng; + + // copyable && movable + rng = rng; + rng = std::move(rng); + + // 64-bit + QRandomGenerator64 rng64; + rng64 = rng64; + rng64 = std::move(rng64); + + // 32- and 64-bit should be interchangeable: + rng = rng64; + rng64 = rng; + rng = std::move(rng64); + rng64 = std::move(rng); + + // access global + QRandomGenerator *global = QRandomGenerator::global(); + QRandomGenerator globalCopy = *global; + globalCopy = *global; + QRandomGenerator64 *global64 = QRandomGenerator64::global(); + QRandomGenerator64 globalCopy64 = *global64; + globalCopy64 = *global64; + + // access system + QRandomGenerator *system = QRandomGenerator::system(); + QRandomGenerator systemRng = *system; + systemRng = *system; + + QRandomGenerator64 *system64 = QRandomGenerator64::system(); + QRandomGenerator64 systemRng64 = *system64; + systemRng64 = *system64; + + Q_STATIC_ASSERT(std::is_same::value); + Q_STATIC_ASSERT(std::is_samegenerate()) COMMA quint64>::value); +} + +void tst_QRandomGenerator::knownSequence() +{ + QRandomGenerator rng; + for (quint32 x : defaultRngResults) + QCOMPARE(rng(), x); +} + +void tst_QRandomGenerator::copying() +{ + QRandomGenerator rng1; + QRandomGenerator rng2 = rng1; + + quint32 samples[20]; + rng1.fillRange(samples); + + // should produce the same sequence, whichever it was + for (quint32 x : samples) + QCOMPARE(rng2(), x); +} + +void tst_QRandomGenerator::copyingGlobal() +{ + QRandomGenerator &global = *QRandomGenerator::global(); + QRandomGenerator copy = global; + + quint32 samples[20]; + global.fillRange(samples); + + // should produce the same sequence, whichever it was + for (quint32 x : samples) + QCOMPARE(copy(), x); +} + +void tst_QRandomGenerator::copyingSystem() +{ + QRandomGenerator &system = *QRandomGenerator::system(); + QRandomGenerator copy = system; + QRandomGenerator copy2 = copy; + copy2 = copy; + + quint32 samples[20]; + copy2.fillRange(samples); + + // should NOT produce the same sequence, whichever it was + int sameCount = 0; + for (quint32 x : samples) + sameCount += (copy() == x); + QVERIFY(sameCount < 20); +} + +void tst_QRandomGenerator::systemRng() +{ + QRandomGenerator *rng = QRandomGenerator::system(); + rng->generate(); + rng->generate64(); + rng->generateDouble(); + rng->bounded(100); + rng->bounded(100U); + +#ifdef QT_BUILD_INTERNAL + quint32 setpoint = std::numeric_limits::max(); + ++setpoint; + quint64 setpoint64 = quint64(setpoint) << 32 | setpoint; + setRNGControl(SetRandomData | setpoint); + + QCOMPARE(rng->generate(), setpoint); + QCOMPARE(rng->generate64(), setpoint64); + QCOMPARE(rng->generateDouble(), ldexp(setpoint64, -64)); + QCOMPARE(rng->bounded(100), 50); +#endif +} + void tst_QRandomGenerator::generate32_data() { QTest::addColumn("control"); - QTest::newRow("default") << 0U; + QTest::newRow("fixed") << (RandomValue32 & RandomDataMask); + QTest::newRow("global") << 0U; #ifdef QT_BUILD_INTERNAL - QTest::newRow("system") << uint(SkipHWRNG); + if (qt_has_hwrng()) + QTest::newRow("hwrng") << uint(UseSystemRNG); + QTest::newRow("system") << uint(UseSystemRNG | SkipHWRNG); # ifdef HAVE_FALLBACK_ENGINE - QTest::newRow("fallback") << uint(SkipHWRNG | SkipSystemRNG); + QTest::newRow("system-fallback") << uint(UseSystemRNG | SkipHWRNG | SkipSystemRNG); # endif #endif } @@ -129,39 +272,40 @@ void tst_QRandomGenerator::generate32_data() void tst_QRandomGenerator::generate32() { QFETCH(uint, control); - setRNGControl(control); + RandomGenerator rng(control); for (int i = 0; i < 4; ++i) { - QVERIFY_3TIMES([] { - quint32 value = QRandomGenerator::generate(); + QVERIFY_3TIMES([&] { + quint32 value = rng.generate(); return value != 0 && value != RandomValue32; }()); } // and should hopefully be different from repeated calls for (int i = 0; i < 4; ++i) - QVERIFY_3TIMES(QRandomGenerator::generate() != QRandomGenerator::generate()); + QVERIFY_3TIMES(rng.generate() != rng.generate()); } void tst_QRandomGenerator::generate64() { QFETCH(uint, control); - setRNGControl(control); + RandomGenerator rng(control); + QVERIFY_3TIMES(rng.generate64() > std::numeric_limits::max()); for (int i = 0; i < 4; ++i) { - QVERIFY_3TIMES([] { - quint64 value = QRandomGenerator::generate(); + QVERIFY_3TIMES([&] { + quint64 value = rng.generate64(); return value != 0 && value != RandomValue32 && value != RandomValue64; }()); } // and should hopefully be different from repeated calls for (int i = 0; i < 4; ++i) - QVERIFY_3TIMES(QRandomGenerator::generate64() != QRandomGenerator::generate64()); + QVERIFY_3TIMES(rng.generate64() != rng.generate64()); for (int i = 0; i < 4; ++i) - QVERIFY_3TIMES(QRandomGenerator::generate() != quint32(QRandomGenerator::generate64())); + QVERIFY_3TIMES(rng.generate() != quint32(rng.generate64())); for (int i = 0; i < 4; ++i) - QVERIFY_3TIMES(QRandomGenerator::generate() != (QRandomGenerator::generate64() >> 32)); + QVERIFY_3TIMES(rng.generate() != (rng.generate64() >> 32)); } void tst_QRandomGenerator::quality() @@ -190,7 +334,9 @@ void tst_QRandomGenerator::quality() Q_STATIC_ASSERT(FailureThreshold > AcceptableThreshold); QFETCH(uint, control); - setRNGControl(control); + if (control & RandomDataMask) + return; + RandomGenerator rng(control); int histogram[UCHAR_MAX + 1]; memset(histogram, 0, sizeof(histogram)); @@ -199,7 +345,7 @@ void tst_QRandomGenerator::quality() // test the quality of the generator quint32 buffer[BufferCount]; memset(buffer, 0xcc, sizeof(buffer)); - generate_n(buffer, +BufferCount, [] { return QRandomGenerator::generate(); }); + generate_n(buffer, +BufferCount, [&] { return rng.generate(); }); quint8 *ptr = reinterpret_cast(buffer); quint8 *end = ptr + sizeof(buffer); @@ -224,20 +370,20 @@ void tst_QRandomGenerator::quality() template void fillRange_template() { QFETCH(uint, control); - setRNGControl(control); + RandomGenerator rng(control); for (int i = 0; i < 4; ++i) { - QVERIFY_3TIMES([] { + QVERIFY_3TIMES([&] { T value[1] = { RandomValue32 }; - QRandomGenerator::fillRange(value); + rng.fillRange(value); return value[0] != 0 && value[0] != RandomValue32; }()); } for (int i = 0; i < 4; ++i) { - QVERIFY_3TIMES([] { + QVERIFY_3TIMES([&] { T array[2] = {}; - QRandomGenerator::fillRange(array); + rng.fillRange(array); return array[0] != array[1]; }()); } @@ -245,18 +391,18 @@ template void fillRange_template() if (sizeof(T) > sizeof(quint32)) { // just to shut up a warning about shifting uint more than the width enum { Shift = sizeof(T) / 2 * CHAR_BIT }; - QVERIFY_3TIMES([] { + QVERIFY_3TIMES([&] { T value[1] = { }; - QRandomGenerator::fillRange(value); + rng.fillRange(value); return quint32(value[0] >> Shift) != quint32(value[0]); }()); } // fill in a longer range - auto longerArrayCheck = [] { + auto longerArrayCheck = [&] { T array[32]; memset(array, 0, sizeof(array)); - QRandomGenerator::fillRange(array); + rng.fillRange(array); if (sizeof(T) == sizeof(RandomValue64) && find(begin(array), end(array), RandomValue64) != end(array)) return false; @@ -273,11 +419,11 @@ void tst_QRandomGenerator::fillRangeULLong() { fillRange_template(); template void generate_template() { QFETCH(uint, control); - setRNGControl(control); + RandomGenerator rng(control); // almost the same as fillRange, but limited to 32 bits for (int i = 0; i < 4; ++i) { - QVERIFY_3TIMES([] { + QVERIFY_3TIMES([&] { T value[1] = { RandomValue32 }; QRandomGenerator().generate(begin(value), end(value)); return value[0] != 0 && value[0] != RandomValue32 @@ -286,10 +432,10 @@ template void generate_template() } // fill in a longer range - auto longerArrayCheck = [] { + auto longerArrayCheck = [&] { T array[72] = {}; // at least 256 bytes QRandomGenerator().generate(begin(array), end(array)); - return find_if(begin(array), end(array), [](T cur) { + return find_if(begin(array), end(array), [&](T cur) { return cur == 0 || cur == RandomValue32 || cur == RandomValue64 || cur > numeric_limits::max(); }) == end(array); @@ -303,12 +449,12 @@ void tst_QRandomGenerator::generateULLong() { generate_template(); } void tst_QRandomGenerator::generateNonContiguous() { QFETCH(uint, control); - setRNGControl(control); + RandomGenerator rng(control); QLinkedList list = { 0, 0, 0, 0, 0, 0, 0, 0 }; auto longerArrayCheck = [&] { QRandomGenerator().generate(list.begin(), list.end()); - return find_if(list.begin(), list.end(), [](quint64 cur) { + return find_if(list.begin(), list.end(), [&](quint64 cur) { return cur == 0 || cur == RandomValue32 || cur == RandomValue64 || cur > numeric_limits::max(); }) == list.end(); @@ -326,7 +472,7 @@ void tst_QRandomGenerator::bounded_data() QTest::addColumn("sup"); QTest::addColumn("expected"); - auto newRow = [](quint32 val, quint32 sup) { + auto newRow = [&](quint32 val, quint32 sup) { // calculate the scaled value quint64 scaled = val; scaled <<= 32; @@ -352,31 +498,31 @@ void tst_QRandomGenerator::bounded() QFETCH(uint, control); QFETCH(quint32, sup); QFETCH(quint32, expected); - setRNGControl(control); + RandomGenerator rng(control); - quint32 value = QRandomGenerator::bounded(sup); + quint32 value = rng.bounded(sup); QVERIFY(value < sup); QCOMPARE(value, expected); - int ivalue = QRandomGenerator::bounded(sup); + int ivalue = rng.bounded(sup); QVERIFY(ivalue < int(sup)); QCOMPARE(ivalue, int(expected)); // confirm only the bound now - setRNGControl(control & (SkipHWRNG|SkipSystemRNG)); - value = QRandomGenerator::bounded(sup); + setRNGControl(control & (SkipHWRNG|SkipSystemRNG|UseSystemRNG)); + value = rng.bounded(sup); QVERIFY(value < sup); - value = QRandomGenerator::bounded(sup / 2, 3 * sup / 2); + value = rng.bounded(sup / 2, 3 * sup / 2); QVERIFY(value >= sup / 2); QVERIFY(value < 3 * sup / 2); - ivalue = QRandomGenerator::bounded(-int(sup), int(sup)); + ivalue = rng.bounded(-int(sup), int(sup)); QVERIFY(ivalue >= -int(sup)); QVERIFY(ivalue < int(sup)); // wholly negative range - ivalue = QRandomGenerator::bounded(-int(sup), 0); + ivalue = rng.bounded(-int(sup), 0); QVERIFY(ivalue >= -int(sup)); QVERIFY(ivalue < 0); } @@ -407,7 +553,9 @@ void tst_QRandomGenerator::boundedQuality() Q_STATIC_ASSERT(FailureThreshold > AcceptableThreshold); QFETCH(uint, control); - setRNGControl(control); + if (control & RandomDataMask) + return; + RandomGenerator rng(control); int histogram[Bound]; memset(histogram, 0, sizeof(histogram)); @@ -415,7 +563,7 @@ void tst_QRandomGenerator::boundedQuality() { // test the quality of the generator QVector buffer(BufferCount, 0xcdcdcdcd); - generate(buffer.begin(), buffer.end(), [] { return QRandomGenerator::bounded(Bound); }); + generate(buffer.begin(), buffer.end(), [&] { return rng.bounded(Bound); }); for (quint32 value : qAsConst(buffer)) { QVERIFY(value < Bound); @@ -441,24 +589,26 @@ void tst_QRandomGenerator::boundedQuality() void tst_QRandomGenerator::generateReal() { QFETCH(uint, control); - setRNGControl(control); + RandomGenerator rng(control); for (int i = 0; i < 4; ++i) { - QVERIFY_3TIMES([] { - qreal value = QRandomGenerator::generateDouble(); + QVERIFY_3TIMES([&] { + qreal value = rng.generateDouble(); return value >= 0 && value < 1 && value != RandomValueFP; }()); } // and should hopefully be different from repeated calls for (int i = 0; i < 4; ++i) - QVERIFY_3TIMES(QRandomGenerator::generateDouble() != QRandomGenerator::generateDouble()); + QVERIFY_3TIMES(rng.generateDouble() != rng.generateDouble()); } void tst_QRandomGenerator::qualityReal() { QFETCH(uint, control); - setRNGControl(control); + if (control & RandomDataMask) + return; + RandomGenerator rng(control); enum { SampleSize = 160, @@ -474,7 +624,7 @@ void tst_QRandomGenerator::qualityReal() }; double data[SampleSize]; - std::generate(std::begin(data), std::end(data), &QRandomGenerator::generateDouble); + std::generate(std::begin(data), std::end(data), [&rng] { return rng.generateDouble(); }); int aboveHalf = 0; int belowOneEighth = 0; @@ -503,12 +653,22 @@ void tst_QRandomGenerator::qualityReal() template void seedStdRandomEngine() { - QRandomGenerator rd; - Engine e(rd); - QVERIFY_3TIMES(e() != 0); + { + QRandomGenerator &rd = *QRandomGenerator::system(); + Engine e(rd); + QVERIFY_3TIMES(e() != 0); + + e.seed(rd); + QVERIFY_3TIMES(e() != 0); + } + { + QRandomGenerator64 &rd = *QRandomGenerator64::system(); + Engine e(rd); + QVERIFY_3TIMES(e() != 0); - e.seed(rd); - QVERIFY_3TIMES(e() != 0); + e.seed(rd); + QVERIFY_3TIMES(e() != 0); + } } void tst_QRandomGenerator::seedStdRandomEngines() @@ -533,12 +693,16 @@ void tst_QRandomGenerator::stdUniformIntDistribution_data() QTest::addColumn("control"); QTest::addColumn("max"); - auto newRow = [](quint32 max) { - QTest::addRow("default:%u", max) << 0U << max; - QTest::addRow("system:%u", max) << uint(SkipHWRNG) << max; - #ifdef HAVE_FALLBACK_ENGINE - QTest::addRow("fallback:%u", max) << uint(SkipHWRNG | SkipSystemRNG) << max; - #endif + auto newRow = [&](quint32 max) { +#ifdef QT_BUILD_INTERNAL + if (qt_has_hwrng()) + QTest::addRow("hwrng:%u", max) << uint(UseSystemRNG) << max; + QTest::addRow("system:%u", max) << uint(UseSystemRNG | SkipHWRNG) << max; +# ifdef HAVE_FALLBACK_ENGINE + QTest::addRow("system-fallback:%u", max) << uint(UseSystemRNG | SkipHWRNG | SkipSystemRNG) << max; +# endif +#endif + QTest::addRow("global:%u", max) << 0U << max; }; // useless: we can only generate zeroes: @@ -553,7 +717,7 @@ void tst_QRandomGenerator::stdUniformIntDistribution() { QFETCH(uint, control); QFETCH(quint32, max); - setRNGControl(control & (SkipHWRNG|SkipSystemRNG)); + RandomGenerator rng(control); { QRandomGenerator rd; @@ -621,21 +785,19 @@ void tst_QRandomGenerator::stdGenerateCanonical() QSKIP("MSVC 2013's std::generate_canonical is broken"); #else QFETCH(uint, control); - setRNGControl(control); + RandomGenerator rng(control); for (int i = 0; i < 4; ++i) { - QVERIFY_3TIMES([] { - QRandomGenerator rd; - qreal value = std::generate_canonical(rd); + QVERIFY_3TIMES([&] { + qreal value = std::generate_canonical(rng); return value > 0 && value < 1 && value != RandomValueFP; }()); } // and should hopefully be different from repeated calls - QRandomGenerator rd; for (int i = 0; i < 4; ++i) - QVERIFY_3TIMES(std::generate_canonical(rd) != - std::generate_canonical(rd)); + QVERIFY_3TIMES(std::generate_canonical(rng) != + std::generate_canonical(rng)); #endif } @@ -649,12 +811,16 @@ void tst_QRandomGenerator::stdUniformRealDistribution_data() QTest::addColumn("min"); QTest::addColumn("sup"); - auto newRow = [](double min, double sup) { - QTest::addRow("default:%g-%g", min, sup) << 0U << min << sup; - QTest::addRow("system:%g-%g", min, sup) << uint(SkipHWRNG) << min << sup; - #ifdef HAVE_FALLBACK_ENGINE - QTest::addRow("fallback:%g-%g", min, sup) << uint(SkipHWRNG | SkipSystemRNG) << min << sup; - #endif + auto newRow = [&](double min, double sup) { +#ifdef QT_BUILD_INTERNAL + if (qt_has_hwrng()) + QTest::addRow("hwrng:%g-%g", min, sup) << uint(UseSystemRNG) << min << sup; + QTest::addRow("system:%g-%g", min, sup) << uint(UseSystemRNG | SkipHWRNG) << min << sup; +# ifdef HAVE_FALLBACK_ENGINE + QTest::addRow("system-fallback:%g-%g", min, sup) << uint(UseSystemRNG | SkipHWRNG | SkipSystemRNG) << min << sup; +# endif +#endif + QTest::addRow("global:%g-%g", min, sup) << 0U << min << sup; }; newRow(0, 0); // useless: we can only generate zeroes @@ -670,7 +836,7 @@ void tst_QRandomGenerator::stdUniformRealDistribution() QFETCH(uint, control); QFETCH(double, min); QFETCH(double, sup); - setRNGControl(control & (SkipHWRNG|SkipSystemRNG)); + RandomGenerator rng(control & (SkipHWRNG|SkipSystemRNG|UseSystemRNG)); { QRandomGenerator rd; @@ -695,13 +861,9 @@ void tst_QRandomGenerator::stdUniformRealDistribution() } } -void tst_QRandomGenerator::stdRandomDistributions() +template void stdRandomDistributions_template() { - // just a compile check for some of the distributions, besides - // std::uniform_int_distribution and std::uniform_real_distribution (tested - // above) - - QRandomGenerator rd; + Generator rd; std::bernoulli_distribution()(rd); @@ -723,6 +885,16 @@ void tst_QRandomGenerator::stdRandomDistributions() } } +void tst_QRandomGenerator::stdRandomDistributions() +{ + // just a compile check for some of the distributions, besides + // std::uniform_int_distribution and std::uniform_real_distribution (tested + // above) + + stdRandomDistributions_template(); + stdRandomDistributions_template(); +} + QTEST_APPLESS_MAIN(tst_QRandomGenerator) #include "tst_qrandomgenerator.moc" -- cgit v1.2.3 From cfad4e298f4d65fe26c3a4109d19839bdfcd30c2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 23 Oct 2017 19:39:45 -0700 Subject: QRandomGenerator: add securelySeeded(), to ensure appropriate seeding Since we don't document how many bytes one needs (it's 2496), it's difficult for the caller to provide just enough data in the seed sequence. Moreover, since std::mt19937 doesn't make it easy to provide the ideal size either, we can't actually write code that operates optimally given a quint32 range either -- we only provide it via std::seed_seq, which is inefficient. However, we can do it internally by passing QRandomGenerator to the std::mersenne_twister_engine constructor, as it's designed to work. Change-Id: Icaa86fc7b54d4b368c0efffd14f0613c10998321 Reviewed-by: Lars Knoll --- src/corelib/global/qrandom.cpp | 60 ++++++++++++++++++---- src/corelib/global/qrandom.h | 7 +++ .../qrandomgenerator/tst_qrandomgenerator.cpp | 19 +++++++ 3 files changed, 77 insertions(+), 9 deletions(-) diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index 44b807d745..2241dc7095 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -422,6 +422,9 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, QRandomGenerator will generate the same sequence of numbers. But given different seeds, the results should be considerably different. + QRandomGenerator::securelySeeded() can be used to create a QRandomGenerator + that is securely seeded with QRandomGenerator::system(), meaning that the + sequence of numbers it generates cannot be easily predicted. Additionally, QRandomGenerator::global() returns a global instance of QRandomGenerator that Qt will ensure to be securely seeded. This object is thread-safe, may be shared for most uses, and is always seeded from @@ -462,7 +465,8 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, itself. Due to mixing of the seed data, QRandomGenerator cannot guarantee that distinct seeds will produce different sequences. - QRandomGenerator::global() is always seeded from + QRandomGenerator::global(), like all generators created by + QRandomGenerator::securelySeeded(), is always seeded from QRandomGenerator::system(), so it's not possible to make it produce identical sequences. @@ -576,6 +580,8 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, Initializes this QRandomGenerator object with the value \a seed as the seed. Two objects constructed with the same seed value will produce the same number sequence. + + \sa securelySeeded() */ /*! @@ -585,6 +591,8 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, Initializes this QRandomGenerator object with the values found in the array \a seedBuffer as the seed. Two objects constructed or reseeded with the same seed value will produce the same number sequence. + + \sa securelySeeded() */ /*! @@ -600,6 +608,8 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, std::seed_seq sseq(seedBuffer, seedBuffer + len); QRandomGenerator generator(sseq); \endcode + + \sa securelySeeded() */ /*! @@ -615,6 +625,8 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, std::seed_seq sseq(begin, end); QRandomGenerator generator(sseq); \endcode + + \sa securelySeeded() */ /*! @@ -624,6 +636,8 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, Initializes this QRandomGenerator object with the seed sequence \a sseq as the seed. Two objects constructed or reseeded with the same seed value will produce the same number sequence. + + \sa securelySeeded() */ /*! @@ -640,8 +654,8 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, For that reason, it is not adviseable to create a copy of QRandomGenerator::global(). If one needs an exclusive deterministic - generator, consider instead creating a new object and seeding it from - QRandomGenerator::system(). + generator, consider instead using securelySeeded() to obtain a new object + that shares no relationship with the QRandomGenerator::global(). */ /*! @@ -882,7 +896,7 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, QRandomGenerator will also access the operating system facilities, but they will not generate the same sequence. - \sa global() + \sa securelySeeded(), global() */ /*! @@ -890,10 +904,9 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, \threadsafe Returns a pointer to a shared QRandomGenerator that was seeded using - QRandomGenerator::system(). This function should be used to create random data - without the expensive creation of a securely-seeded QRandomGenerator for a - specific use or storing the rather large QRandomGenerator object. - large QRandomGenerator object. + securelySeeded(). This function should be used to create random data + without the expensive creation of a securely-seeded QRandomGenerator + for a specific use or storing the rather large QRandomGenerator object. For example, the following creates a random RGB color: @@ -907,9 +920,28 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, Note, however, that if there are other threads accessing the global object, those threads may obtain samples at unpredictable intervals. - \sa system() + \sa securelySeeded(), system() */ +/*! + \fn QRandomGenerator QRandomGenerator::securelySeeded() + + Returns a new QRandomGenerator object that was securely seeded with + QRandomGenerator::system(). This function will obtain the ideal seed size + for the algorithm that QRandomGenerator uses and is therefore the + recommended way for creating a new QRandomGenerator object that will be + kept for some time. + + Given the amount of data required to securely seed the deterministic + engine, this function is somewhat expensive and should not be used for + short-term uses of QRandomGenerator (using it to generate fewer than 2600 + bytes of random data is effectively a waste of resources). If the use + doesn't require that much data, consider using QRandomGenerator::global() + and not storing a QRandomGenerator object instead. + + \sa global(), system() + */ + /*! \class QRandomGenerator64 \inmodule QtCore @@ -999,6 +1031,16 @@ QRandomGenerator64 *QRandomGenerator64::global() return &global; } +QRandomGenerator64 QRandomGenerator64::securelySeeded() +{ + QRandomGenerator64 result(System{}); + result.type = MersenneTwister; + + // seed with the system CSPRNG + new (&result.storage.engine()) RandomEngine(static_cast(system()->storage.sys)); + return result; +} + /// \internal inline QRandomGenerator::QRandomGenerator(System) : type(SystemRNG) diff --git a/src/corelib/global/qrandom.h b/src/corelib/global/qrandom.h index e6fd4f02de..c25a0ad643 100644 --- a/src/corelib/global/qrandom.h +++ b/src/corelib/global/qrandom.h @@ -156,6 +156,7 @@ public: static inline QRandomGenerator *system(); static inline QRandomGenerator *global(); + static inline QRandomGenerator securelySeeded(); protected: enum System {}; @@ -222,6 +223,7 @@ public: static Q_DECL_CONSTEXPR result_type max() { return (std::numeric_limits::max)(); } static Q_CORE_EXPORT QRandomGenerator64 *system(); static Q_CORE_EXPORT QRandomGenerator64 *global(); + static Q_CORE_EXPORT QRandomGenerator64 securelySeeded(); #endif // Q_QDOC }; @@ -235,6 +237,11 @@ inline QRandomGenerator *QRandomGenerator::global() return QRandomGenerator64::global(); } +QRandomGenerator QRandomGenerator::securelySeeded() +{ + return QRandomGenerator64::securelySeeded(); +} + QT_END_NAMESPACE #endif // QRANDOM_H diff --git a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp index f9b3ce5390..9c1828d1dd 100644 --- a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp +++ b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp @@ -77,6 +77,7 @@ private slots: void copyingGlobal(); void copyingSystem(); void systemRng(); + void securelySeeding(); void generate32_data(); void generate32(); @@ -161,6 +162,9 @@ void tst_QRandomGenerator::basics() rng = std::move(rng64); rng64 = std::move(rng); + rng = QRandomGenerator64::securelySeeded(); + rng64 = QRandomGenerator::securelySeeded(); + // access global QRandomGenerator *global = QRandomGenerator::global(); QRandomGenerator globalCopy = *global; @@ -254,6 +258,21 @@ void tst_QRandomGenerator::systemRng() #endif } +void tst_QRandomGenerator::securelySeeding() +{ + QRandomGenerator rng1 = QRandomGenerator::securelySeeded(); + QRandomGenerator rng2 = QRandomGenerator::securelySeeded(); + + quint32 samples[20]; + rng1.fillRange(samples); + + // should NOT produce the same sequence, whichever it was + int sameCount = 0; + for (quint32 x : samples) + sameCount += (rng2() == x); + QVERIFY(sameCount < 20); +} + void tst_QRandomGenerator::generate32_data() { QTest::addColumn("control"); -- cgit v1.2.3 From 08bf28de03f16e5b014b23e228dfc3cfc2ac7feb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 23 Oct 2017 19:16:34 -0700 Subject: QRandomGenerator: add more of the std Random Engine API This brings us to almost parity with the C++11 Random Engine API requirements (see chapter 26.5.1.4 [rand.req.eng]). We don't implement the templated Sseq requirements because it would require moving the implementation details to the public API. And we don't implement the code because we don't want to. Change-Id: Icaa86fc7b54d4b368c0efffd14f05ff813ebd759 Reviewed-by: Lars Knoll --- src/corelib/global/qrandom.cpp | 90 +++++++++++++++++++--- src/corelib/global/qrandom.h | 24 +++++- .../qrandomgenerator/tst_qrandomgenerator.cpp | 41 ++++++++++ 3 files changed, 142 insertions(+), 13 deletions(-) diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index 2241dc7095..a9596df432 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -558,7 +558,15 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, QRandomGenerator is modeled after the requirements for random number engines in the C++ Standard Library and may be used in almost all contexts - that the Standard Library engines can. + that the Standard Library engines can. Exceptions to the requirements are + the following: + + \list + \li QRandomGenerator does not support seeding from another seed + sequence-like class besides std::seed_seq itself; + \li QRandomGenerator is not comparable (but is copyable) or + streamable to \c{std::ostream} or from \c{std::istream}. + \endlist QRandomGenerator is also compatible with the uniform distribution classes \c{std::uniform_int_distribution} and \c{std:uniform_real_distribution}, as @@ -575,13 +583,13 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, */ /*! - \fn QRandomGenerator::QRandomGenerator(quint32 seed) + \fn QRandomGenerator::QRandomGenerator(quint32 seedValue) - Initializes this QRandomGenerator object with the value \a seed as - the seed. Two objects constructed with the same seed value will + Initializes this QRandomGenerator object with the value \a seedValue as + the seed. Two objects constructed or reseeded with the same seed value will produce the same number sequence. - \sa securelySeeded() + \sa seed(), securelySeeded() */ /*! @@ -592,7 +600,7 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, array \a seedBuffer as the seed. Two objects constructed or reseeded with the same seed value will produce the same number sequence. - \sa securelySeeded() + \sa seed(), securelySeeded() */ /*! @@ -609,7 +617,7 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, QRandomGenerator generator(sseq); \endcode - \sa securelySeeded() + \sa seed(), securelySeeded() */ /*! @@ -626,7 +634,7 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, QRandomGenerator generator(sseq); \endcode - \sa securelySeeded() + \sa seed(), securelySeeded() */ /*! @@ -637,7 +645,7 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, sseq as the seed. Two objects constructed or reseeded with the same seed value will produce the same number sequence. - \sa securelySeeded() + \sa seed(), securelySeeded() */ /*! @@ -658,6 +666,24 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, that shares no relationship with the QRandomGenerator::global(). */ +/*! + \fn bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2) + \relates QRandomGenerator + + Returns true if the two the two engines \a rng1 and \a rng2 are at the same + state or if they are both reading from the operating system facilities, + false otherwise. +*/ + +/*! + \fn bool operator!=(const QRandomGenerator &rng1, const QRandomGenerator &rng2) + \relates QRandomGenerator + + Returns true if the two the two engines \a rng1 and \a rng2 are at + different states or if one of them is reading from the operating system + facilities and the other is not, false otherwise. +*/ + /*! \typedef QRandomGenerator::result_type @@ -691,6 +717,31 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, \sa min(), QRandomGenerator64::max() */ +/*! + \fn void QRandomGenerator::seed(quint32 seed) + + Reseeds this object using the value \a seed as the seed. + */ + +/*! + \fn void QRandomGenerator::seed(std::seed_seq &seed) + \overload + + Reseeds this object using the seed sequence \a sseq as the seed. + */ + +/*! + \fn void QRandomGenerator::discard(unsigned long long z) + + Discards the next \a z entries from the sequence. This method is equivalent + to calling generate() \a z times and discarding the result, as in: + + \code + while (z--) + generator.generate(); + \endcode +*/ + /*! \fn void QRandomGenerator::generate(ForwardIterator begin, ForwardIterator end) @@ -1086,6 +1137,27 @@ QRandomGenerator::QRandomGenerator(const quint32 *begin, const quint32 *end) new (&storage.engine()) RandomEngine(s); } +void QRandomGenerator::discard(unsigned long long z) +{ + if (Q_UNLIKELY(type == SystemRNG)) + return; + + PRNGLocker lock(this); + storage.engine().discard(z); +} + +bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2) +{ + if (rng1.type != rng2.type) + return false; + if (rng1.type == SystemRNG) + return true; + + // Lock global() if either is it (otherwise this locking is a no-op) + PRNGLocker locker(&rng1 == QRandomGenerator::global() ? &rng1 : &rng2); + return rng1.storage.engine() == rng2.storage.engine(); +} + /*! \internal diff --git a/src/corelib/global/qrandom.h b/src/corelib/global/qrandom.h index c25a0ad643..c31c9afddb 100644 --- a/src/corelib/global/qrandom.h +++ b/src/corelib/global/qrandom.h @@ -52,8 +52,8 @@ class QRandomGenerator template using IfValidUInt = typename std::enable_if::value && sizeof(UInt) >= sizeof(uint), bool>::type; public: - QRandomGenerator(quint32 seed = 1) - : QRandomGenerator(&seed, 1) + QRandomGenerator(quint32 seedValue = 1) + : QRandomGenerator(&seedValue, 1) {} template QRandomGenerator(const quint32 (&seedBuffer)[N]) : QRandomGenerator(seedBuffer, seedBuffer + N) @@ -68,6 +68,12 @@ public: Q_CORE_EXPORT QRandomGenerator(const QRandomGenerator &other); Q_CORE_EXPORT QRandomGenerator &operator=(const QRandomGenerator &other); + friend Q_CORE_EXPORT bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2); + friend bool operator!=(const QRandomGenerator &rng1, const QRandomGenerator &rng2) + { + return !(rng1 == rng2); + } + quint32 generate() { quint32 ret; @@ -151,6 +157,9 @@ public: // API like std:: random engines typedef quint32 result_type; result_type operator()() { return generate(); } + void seed(quint32 s = 1) { *this = { s }; } + void seed(std::seed_seq &sseq) Q_DECL_NOTHROW { *this = { sseq }; } + Q_CORE_EXPORT void discard(unsigned long long z); static Q_DECL_CONSTEXPR result_type min() { return (std::numeric_limits::min)(); } static Q_DECL_CONSTEXPR result_type max() { return (std::numeric_limits::max)(); } @@ -202,8 +211,8 @@ public: result_type operator()() { return generate64(); } #ifndef Q_QDOC - QRandomGenerator64(quint32 seed = 1) - : QRandomGenerator(seed) + QRandomGenerator64(quint32 seedValue = 1) + : QRandomGenerator(seedValue) {} template QRandomGenerator64(const quint32 (&seedBuffer)[N]) : QRandomGenerator(seedBuffer) @@ -219,6 +228,13 @@ public: {} QRandomGenerator64(const QRandomGenerator &other) : QRandomGenerator(other) {} + void discard(unsigned long long z) + { + Q_ASSERT_X(z * 2 > z, "QRandomGenerator64::discard", + "Overflow. Are you sure you want to skip over 9 quintillion samples?"); + QRandomGenerator::discard(z * 2); + } + static Q_DECL_CONSTEXPR result_type min() { return (std::numeric_limits::min)(); } static Q_DECL_CONSTEXPR result_type max() { return (std::numeric_limits::max)(); } static Q_CORE_EXPORT QRandomGenerator64 *system(); diff --git a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp index 9c1828d1dd..220ec9a2f8 100644 --- a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp +++ b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp @@ -73,6 +73,7 @@ public slots: private slots: void basics(); void knownSequence(); + void discard(); void copying(); void copyingGlobal(); void copyingSystem(); @@ -191,32 +192,63 @@ void tst_QRandomGenerator::knownSequence() QRandomGenerator rng; for (quint32 x : defaultRngResults) QCOMPARE(rng(), x); + + // should work again if we reseed it + rng.seed(); + for (quint32 x : defaultRngResults) + QCOMPARE(rng(), x); +} + +void tst_QRandomGenerator::discard() +{ + QRandomGenerator rng; + rng.discard(1); + QCOMPARE(rng(), defaultRngResults[1]); + + rng.discard(9); + QCOMPARE(rng(), defaultRngResults[11]); } void tst_QRandomGenerator::copying() { QRandomGenerator rng1; QRandomGenerator rng2 = rng1; + QCOMPARE(rng1, rng2); quint32 samples[20]; rng1.fillRange(samples); + // not equal anymore + QVERIFY(rng1 != rng2); + // should produce the same sequence, whichever it was for (quint32 x : samples) QCOMPARE(rng2(), x); + + // now they should compare equal again + QCOMPARE(rng1, rng2); } void tst_QRandomGenerator::copyingGlobal() { QRandomGenerator &global = *QRandomGenerator::global(); QRandomGenerator copy = global; + QCOMPARE(copy, global); + QCOMPARE(global, copy); quint32 samples[20]; global.fillRange(samples); + // not equal anymore + QVERIFY(copy != global); + // should produce the same sequence, whichever it was for (quint32 x : samples) QCOMPARE(copy(), x); + + // equal again + QCOMPARE(copy, global); + QCOMPARE(global, copy); } void tst_QRandomGenerator::copyingSystem() @@ -225,15 +257,24 @@ void tst_QRandomGenerator::copyingSystem() QRandomGenerator copy = system; QRandomGenerator copy2 = copy; copy2 = copy; + QCOMPARE(system, copy); + QCOMPARE(copy, copy2); quint32 samples[20]; copy2.fillRange(samples); + // they still compre equally + QCOMPARE(system, copy); + QCOMPARE(copy, copy2); + // should NOT produce the same sequence, whichever it was int sameCount = 0; for (quint32 x : samples) sameCount += (copy() == x); QVERIFY(sameCount < 20); + + QCOMPARE(system, copy); + QCOMPARE(copy, copy2); } void tst_QRandomGenerator::systemRng() -- cgit v1.2.3 From 86d91d2bf8e7ac7a75f88f0e4886140abc06fd4c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 18 Oct 2017 15:58:59 -0700 Subject: QRandomGenerator: optimize the global() and system() storage We store both in a single memory structure, instead of two local statics. By construction, we also ensure that the global PRNG mutex is in a different cacheline from the global PRNG state itself. Finally, we don't store the full system QRandomGenerator, since we only need the type member from it. Change-Id: Icaa86fc7b54d4b368c0efffd14eecc48ff05ec27 Reviewed-by: Edward Welbourne --- src/corelib/global/qrandom.cpp | 192 +++++++++++++++++++++++++++++------------ src/corelib/global/qrandom.h | 14 +-- 2 files changed, 144 insertions(+), 62 deletions(-) diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index a9596df432..58458d6984 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -128,32 +128,12 @@ static qssize_t qt_random_cpu(void *, qssize_t) } #endif -namespace { -static QBasicMutex globalPRNGMutex; - -struct PRNGLocker -{ - const bool locked; - PRNGLocker(const QRandomGenerator *that) - : locked(that == nullptr || that == QRandomGenerator::global()) - { - if (locked) - globalPRNGMutex.lock(); - } - ~PRNGLocker() - { - if (locked) - globalPRNGMutex.unlock(); - } -}; -} - enum { // may be "overridden" by a member enum FillBufferNoexcept = true }; -struct QRandomGenerator::SystemGenerator : public QRandomGenerator::SystemGeneratorBase +struct QRandomGenerator::SystemGenerator { #if QT_CONFIG(getentropy) static qssize_t fillBuffer(void *buffer, qssize_t count) Q_DECL_NOTHROW @@ -175,6 +155,8 @@ struct QRandomGenerator::SystemGenerator : public QRandomGenerator::SystemGenera } #elif defined(Q_OS_UNIX) + enum { FillBufferNoexcept = false }; + QBasicAtomicInt fdp1; // "file descriptor plus 1" int openDevice() { @@ -206,12 +188,12 @@ struct QRandomGenerator::SystemGenerator : public QRandomGenerator::SystemGenera #endif static void closeDevice() { - int fd = static_cast(system()->storage.sys).fdp1.load() - 1; + int fd = self().fdp1.load() - 1; if (fd >= 0) qt_safe_close(fd); } - SystemGenerator() : fdp1 Q_BASIC_ATOMIC_INITIALIZER(0) {} + Q_DECL_CONSTEXPR SystemGenerator() : fdp1 Q_BASIC_ATOMIC_INITIALIZER(0) {} qssize_t fillBuffer(void *buffer, qssize_t count) { @@ -237,10 +219,7 @@ struct QRandomGenerator::SystemGenerator : public QRandomGenerator::SystemGenera } #endif // Q_OS_WINRT - static SystemGenerator &self() - { - return static_cast(QRandomGenerator::system()->storage.sys); - } + static SystemGenerator &self(); void generate(quint32 *begin, quint32 *end) Q_DECL_NOEXCEPT_EXPR(FillBufferNoexcept); // For std::mersenne_twister_engine implementations that use something @@ -405,6 +384,99 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, } } +struct QRandomGenerator::SystemAndGlobalGenerators +{ + // Construction notes: + // 1) The global PRNG state is in a different cacheline compared to the + // mutex that protects it. This avoids any false cacheline sharing of + // the state in case another thread tries to lock the mutex. It's not + // a common scenario, but since sizeof(QRandomGenerator) >= 2560, the + // overhead is actually acceptable. + // 2) We use both Q_DECL_ALIGN and std::aligned_storage<..., 64> because + // some implementations of std::aligned_storage can't align to more + // than a primitive type's alignment. + // 3) We don't store the entire system QRandomGenerator, only the space + // used by the QRandomGenerator::type member. This is fine because we + // (ab)use the common initial sequence exclusion to aliasing rules. + QBasicMutex globalPRNGMutex; + struct ShortenedSystem { uint type; } system_; + SystemGenerator sys; + Q_DECL_ALIGN(64) std::aligned_storage::type global_; + +#ifdef Q_COMPILER_CONSTEXPR + constexpr SystemAndGlobalGenerators() + : globalPRNGMutex{}, system_{0}, sys{}, global_{} + {} +#endif + + void confirmLiteral() + { +#if defined(Q_COMPILER_CONSTEXPR) && !defined(Q_CC_MSVC) + // Currently fails to compile with MSVC 2017, saying QBasicMutex is not + // a literal type. Disassembly with MSVC 2013 and 2015 shows it is + // actually a literal; MSVC 2017 has a bug relating to this, so we're + // withhold judgement for now. + + constexpr SystemAndGlobalGenerators g = {}; + Q_UNUSED(g); + Q_STATIC_ASSERT(std::is_literal_type::value); +#endif + } + + static SystemAndGlobalGenerators *self() + { + static SystemAndGlobalGenerators g; + Q_STATIC_ASSERT(sizeof(g) > sizeof(QRandomGenerator64)); + return &g; + } + + static QRandomGenerator64 *system() + { + // Though we never call the constructor, the system QRandomGenerator is + // properly initialized by the zero initialization performed in self(). + // Though QRandomGenerator is has non-vacuous initialization, we + // consider it initialized because of the common initial sequence. + return reinterpret_cast(&self()->system_); + } + + static QRandomGenerator64 *globalNoInit() + { + // This function returns the pointer to the global QRandomGenerator, + // but does not initialize it. Only call it directly if you meant to do + // a pointer comparison. + return reinterpret_cast(&self()->global_); + } + + static void securelySeed(QRandomGenerator *rng) + { + // force reconstruction, just to be pedantic + new (rng) QRandomGenerator{System{}}; + + rng->type = MersenneTwister; + new (&rng->storage.engine()) RandomEngine(self()->sys); + } + + struct PRNGLocker { + const bool locked; + PRNGLocker(const QRandomGenerator *that) + : locked(that == globalNoInit()) + { + if (locked) + self()->globalPRNGMutex.lock(); + } + ~PRNGLocker() + { + if (locked) + self()->globalPRNGMutex.unlock(); + } + }; +}; + +inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::self() +{ + return SystemAndGlobalGenerators::self()->sys; +} + /*! \class QRandomGenerator \inmodule QtCore @@ -1053,7 +1125,8 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, \sa QRandomGenerator::generate(), QRandomGenerator::generate64() */ -inline QRandomGenerator::Storage::Storage() +Q_DECL_CONSTEXPR QRandomGenerator::Storage::Storage() + : dummy(0) { // nothing } @@ -1065,30 +1138,33 @@ inline QRandomGenerator64::QRandomGenerator64(System s) QRandomGenerator64 *QRandomGenerator64::system() { - static QRandomGenerator64 system(System{}); - return &system; + auto self = SystemAndGlobalGenerators::system(); + Q_ASSERT(self->type == SystemRNG); + return self; } QRandomGenerator64 *QRandomGenerator64::global() { - PRNGLocker lock(nullptr); - static QRandomGenerator64 global(System{}); - if (global.type == SystemRNG) { - // seed with the system CSPRNG and change the type - new (&global.storage.engine()) RandomEngine(static_cast(system()->storage.sys)); - global.type = MersenneTwister; - } + auto self = SystemAndGlobalGenerators::globalNoInit(); - return &global; + // Yes, this is a double-checked lock. + // We can return even if the type is not completely initialized yet: + // any thread trying to actually use the contents of the random engine + // will necessarily wait on the lock. + if (Q_LIKELY(self->type != SystemRNG)) + return self; + + SystemAndGlobalGenerators::PRNGLocker locker(self); + if (self->type == SystemRNG) + SystemAndGlobalGenerators::securelySeed(self); + + return self; } QRandomGenerator64 QRandomGenerator64::securelySeeded() { QRandomGenerator64 result(System{}); - result.type = MersenneTwister; - - // seed with the system CSPRNG - new (&result.storage.engine()) RandomEngine(static_cast(system()->storage.sys)); + SystemAndGlobalGenerators::securelySeed(&result); return result; } @@ -1096,30 +1172,29 @@ QRandomGenerator64 QRandomGenerator64::securelySeeded() inline QRandomGenerator::QRandomGenerator(System) : type(SystemRNG) { - Q_STATIC_ASSERT(sizeof(storage) >= sizeof(SystemGenerator)); - new (&storage) SystemGenerator(); + // don't touch storage } - QRandomGenerator::QRandomGenerator(const QRandomGenerator &other) : type(other.type) { + Q_ASSERT(this != system()); + Q_ASSERT(this != SystemAndGlobalGenerators::globalNoInit()); + if (type != SystemRNG) { - PRNGLocker lock(&other); + SystemAndGlobalGenerators::PRNGLocker lock(&other); storage.engine() = other.storage.engine(); } } QRandomGenerator &QRandomGenerator::operator=(const QRandomGenerator &other) { - if (this != &other) { - if (Q_UNLIKELY(this == system()) || Q_UNLIKELY(this == global())) - qFatal("Attempted to overwrite a QRandomGenerator to system() or global()."); + if (Q_UNLIKELY(this == system()) || Q_UNLIKELY(this == SystemAndGlobalGenerators::globalNoInit())) + qFatal("Attempted to overwrite a QRandomGenerator to system() or global()."); - if ((type = other.type) != SystemRNG) { - PRNGLocker lock(&other); - storage.engine() = other.storage.engine(); - } + if ((type = other.type) != SystemRNG) { + SystemAndGlobalGenerators::PRNGLocker lock(&other); + storage.engine() = other.storage.engine(); } return *this; } @@ -1127,12 +1202,18 @@ QRandomGenerator &QRandomGenerator::operator=(const QRandomGenerator &other) QRandomGenerator::QRandomGenerator(std::seed_seq &sseq) Q_DECL_NOTHROW : type(MersenneTwister) { + Q_ASSERT(this != system()); + Q_ASSERT(this != SystemAndGlobalGenerators::globalNoInit()); + new (&storage.engine()) RandomEngine(sseq); } QRandomGenerator::QRandomGenerator(const quint32 *begin, const quint32 *end) : type(MersenneTwister) { + Q_ASSERT(this != system()); + Q_ASSERT(this != SystemAndGlobalGenerators::globalNoInit()); + std::seed_seq s(begin, end); new (&storage.engine()) RandomEngine(s); } @@ -1142,7 +1223,7 @@ void QRandomGenerator::discard(unsigned long long z) if (Q_UNLIKELY(type == SystemRNG)) return; - PRNGLocker lock(this); + SystemAndGlobalGenerators::PRNGLocker lock(this); storage.engine().discard(z); } @@ -1154,6 +1235,7 @@ bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2) return true; // Lock global() if either is it (otherwise this locking is a no-op) + using PRNGLocker = QRandomGenerator::SystemAndGlobalGenerators::PRNGLocker; PRNGLocker locker(&rng1 == QRandomGenerator::global() ? &rng1 : &rng2); return rng1.storage.engine() == rng2.storage.engine(); } @@ -1175,7 +1257,7 @@ void QRandomGenerator::_fillRange(void *buffer, void *bufferEnd) if (type == SystemRNG || Q_UNLIKELY(uint(qt_randomdevice_control) & (UseSystemRNG|SetRandomData))) return SystemGenerator::self().generate(begin, end); - PRNGLocker lock(this); + SystemAndGlobalGenerators::PRNGLocker lock(this); std::generate(begin, end, [this]() { return storage.engine()(); }); } diff --git a/src/corelib/global/qrandom.h b/src/corelib/global/qrandom.h index c31c9afddb..bde64646a4 100644 --- a/src/corelib/global/qrandom.h +++ b/src/corelib/global/qrandom.h @@ -163,8 +163,8 @@ public: static Q_DECL_CONSTEXPR result_type min() { return (std::numeric_limits::min)(); } static Q_DECL_CONSTEXPR result_type max() { return (std::numeric_limits::max)(); } - static inline QRandomGenerator *system(); - static inline QRandomGenerator *global(); + static inline Q_DECL_CONST_FUNCTION QRandomGenerator *system(); + static inline Q_DECL_CONST_FUNCTION QRandomGenerator *global(); static inline QRandomGenerator securelySeeded(); protected: @@ -175,12 +175,12 @@ private: Q_CORE_EXPORT void _fillRange(void *buffer, void *bufferEnd); friend class QRandomGenerator64; - struct SystemGeneratorBase {}; struct SystemGenerator; + struct SystemAndGlobalGenerators; typedef std::mt19937 RandomEngine; union Storage { - SystemGeneratorBase sys; + uint dummy; #ifdef Q_COMPILER_UNRESTRICTED_UNIONS RandomEngine twister; RandomEngine &engine() { return twister; } @@ -193,7 +193,7 @@ private: Q_STATIC_ASSERT_X(std::is_trivially_destructible::value, "std::mersenne_twister not trivially destructible as expected"); - Storage(); + Q_DECL_CONSTEXPR Storage(); }; uint type; Storage storage; @@ -237,8 +237,8 @@ public: static Q_DECL_CONSTEXPR result_type min() { return (std::numeric_limits::min)(); } static Q_DECL_CONSTEXPR result_type max() { return (std::numeric_limits::max)(); } - static Q_CORE_EXPORT QRandomGenerator64 *system(); - static Q_CORE_EXPORT QRandomGenerator64 *global(); + static Q_DECL_CONST_FUNCTION Q_CORE_EXPORT QRandomGenerator64 *system(); + static Q_DECL_CONST_FUNCTION Q_CORE_EXPORT QRandomGenerator64 *global(); static Q_CORE_EXPORT QRandomGenerator64 securelySeeded(); #endif // Q_QDOC }; -- cgit v1.2.3 From add5de85081fe9defb447ebaf827b07e692c93a0 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Tue, 31 Oct 2017 08:51:06 +0200 Subject: Update gitignore Change-Id: I3d525e523e457524daf6afae390559d943286a6a Reviewed-by: Laszlo Agocs --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index af2afcba7f..f98f90d292 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,9 @@ /src/corelib/global/qconfig.cpp /src/corelib/global/qconfig.h /src/corelib/global/qconfig_p.h +/src/gui/vulkan/qvulkanfunctions.h +/src/gui/vulkan/qvulkanfunctions_p.cpp +/src/gui/vulkan/qvulkanfunctions_p.h /bin/qt.conf /bin/qmake /bin/qvkgen @@ -50,7 +53,8 @@ qt*-config.pri /doc/qt*/* /src/angle/src/QtANGLE/*.def -/src/angle/src/QtANGLE/libANGLE +/src/angle/src/QtANGLE/libANGLE/ +/src/angle/src/libGLESv2/libANGLE/ /src/corelib/global/qfloat16tables.cpp -- cgit v1.2.3 From 25b18fb241315ed314b6b67f4b97028e2a1e484a Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 2 Nov 2017 17:46:35 +0100 Subject: Document interaction of style name and other style properties Setting style name to "Regular" and then setting bold to true, results in platform depending behavior, and should be avoided. Also removes comment about style name not working on Windows, it has been working since 5.8.0. Task-number: QTBUG-63792 Change-Id: Ie5be7215a673f5751dbeb6512df8ec7bfaef4d0a Reviewed-by: Leena Miettinen Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfont.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 7f3ed3adaa..806ede88e2 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -727,11 +727,9 @@ void QFont::setFamily(const QString &family) /*! \since 4.8 - Returns the requested font style name, it will be used to match the + Returns the requested font style name. This can be used to match the font with irregular styles (that can't be normalized in other style - properties). It depends on system font support, thus only works for - \macos and X11 so far. On Windows irregular styles will be added - as separate font families so there is no need for this. + properties). \sa setFamily(), setStyle() */ @@ -744,7 +742,12 @@ QString QFont::styleName() const \since 4.8 Sets the style name of the font to \a styleName. When set, other style properties - like \l style() and \l weight() will be ignored for font matching. + like \l style() and \l weight() will be ignored for font matching, though they may be + simulated afterwards if supported by the platform's font engine. + + Due to the lower quality of artificially simulated styles, and the lack of full cross + platform support, it is not recommended to use matching by style name together with + matching by style properties \sa styleName() */ @@ -985,6 +988,10 @@ int QFont::pixelSize() const Sets the style() of the font to QFont::StyleItalic if \a enable is true; otherwise the style is set to QFont::StyleNormal. + \note If styleName() is set, this value may be ignored, or if supported + on the platform, the font may be rendered tilted instead of picking a + designed italic font-variant. + \sa italic(), QFontInfo */ @@ -1050,6 +1057,8 @@ int QFont::weight() const Sets the weight of the font to \a weight, using the scale defined by \l QFont::Weight enumeration. + \note If styleName() is set, this value may be ignored for font selection. + \sa weight(), QFontInfo */ void QFont::setWeight(int weight) @@ -1083,6 +1092,9 @@ void QFont::setWeight(int weight) For finer boldness control use setWeight(). + \note If styleName() is set, this value may be ignored, or if supported + on the platform, the font artificially embolded. + \sa bold(), setWeight() */ -- cgit v1.2.3 From 3c63c8d2f233c2d2ad02a4be185bda25c82b532b Mon Sep 17 00:00:00 2001 From: Sami Nurmenniemi Date: Thu, 9 Nov 2017 17:07:55 +0200 Subject: Blacklist tst_qstandardpaths::testFindExecutable for b2qt/arm64 Task-number: QTBUG-64404 Change-Id: Ie04cf67574c4eb8b8e5bdb78e8e30173042edab7 Reviewed-by: Liang Qi --- tests/auto/corelib/io/qstandardpaths/BLACKLIST | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/auto/corelib/io/qstandardpaths/BLACKLIST diff --git a/tests/auto/corelib/io/qstandardpaths/BLACKLIST b/tests/auto/corelib/io/qstandardpaths/BLACKLIST new file mode 100644 index 0000000000..d5ee9650cd --- /dev/null +++ b/tests/auto/corelib/io/qstandardpaths/BLACKLIST @@ -0,0 +1,3 @@ +[testFindExecutable] +# QTBUG-64404 +b2qt 64bit -- cgit v1.2.3 From 3bbeb1e9dce958ddba54f6b102bb409a63c9f889 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Sun, 12 Nov 2017 14:44:04 +0100 Subject: test: blacklist tst_QWidget::multipleToplevelFocusCheck() and setToolTip() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit on Ubuntu_16_04 and openSUSE_42_3. Task-number: QTBUG-64446 Change-Id: If8fff2823f041428852822470a2f00157795558b Reviewed-by: Tony Sarajärvi --- tests/auto/widgets/kernel/qwidget/BLACKLIST | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index 0b1d7b4437..4ac176f70e 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -81,3 +81,8 @@ ubuntu-14.04 osx [activateWindow] osx-10.12 ci +[multipleToplevelFocusCheck] +opensuse-42.3 +ubuntu-16.04 +[setToolTip] +opensuse-42.3 -- cgit v1.2.3 From 1a05a7149358a5b5fb11b1f87a85760cc182a726 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 12 Nov 2017 14:15:28 -0800 Subject: Fix QBasicMutex default constructor not constexpr Commit 02dc39fa8ee6fd9945728e12208a9e313ac4dd4b added the constructor for the bootstrapped mode. For the regular mode, we hadn't needed, since the {} syntax guaranteed initialization for us. Turns out there's at least one compiler that doesn't think it was enough (GCC for QNX 7). Task-number: QTBUG-64451 Change-Id: Ic632b4163d784b83951cfffd14f6766b4cb4eb64 Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Liang Qi --- src/corelib/thread/qmutex.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h index 607cc13a2f..3d24379fa9 100644 --- a/src/corelib/thread/qmutex.h +++ b/src/corelib/thread/qmutex.h @@ -67,6 +67,12 @@ class QMutexData; class Q_CORE_EXPORT QBasicMutex { public: +#ifdef Q_COMPILER_CONSTEXPR + constexpr QBasicMutex() + : d_ptr(nullptr) + {} +#endif + // BasicLockable concept inline void lock() QT_MUTEX_LOCK_NOEXCEPT { if (!fastTryLock()) -- cgit v1.2.3 From e4206c3cd5f3cdf431fb7aae9a790f303be0e616 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Mon, 13 Nov 2017 12:42:36 +0100 Subject: test: blacklist tst_QWidget::multipleToplevelFocusCheck() on all Linux. This amends 3bbeb1e9dce958ddba54f6b102bb409a63c9f889. Task-number: QTBUG-64446 Change-Id: I24ca5b881502fac41922e07908801eefee7f31d6 Reviewed-by: Friedemann Kleint Reviewed-by: Gatis Paeglis --- tests/auto/widgets/kernel/qwidget/BLACKLIST | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index 4ac176f70e..4cef2d57a4 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -82,7 +82,4 @@ osx [activateWindow] osx-10.12 ci [multipleToplevelFocusCheck] -opensuse-42.3 -ubuntu-16.04 -[setToolTip] -opensuse-42.3 +linux -- cgit v1.2.3 From c84f7554894cef0cbeeba8a61f441286e190a797 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 13 Nov 2017 11:28:41 +0100 Subject: Offscreen QPA: Use fusion style always MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevent it from crashing when naively using it for example on Windows, which defaults to the Windows Vista style operating on native window handles. Change-Id: I7b1dfb00a6b6860d0f0a134653ce1142b45959ec Reviewed-by: Sami Nurmenniemi Reviewed-by: Gatis Paeglis Reviewed-by: Morten Johan Sørvig --- .../platforms/offscreen/qoffscreenintegration.cpp | 32 ++++++++++++++++++++++ .../platforms/offscreen/qoffscreenintegration.h | 3 ++ 2 files changed, 35 insertions(+) diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp index 3eb8675d77..75bb786b28 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp @@ -61,6 +61,7 @@ #include #include #include +#include #include @@ -167,6 +168,37 @@ QAbstractEventDispatcher *QOffscreenIntegration::createEventDispatcher() const #endif } +static QString themeName() { return QStringLiteral("offscreen"); } + +QStringList QOffscreenIntegration::themeNames() const +{ + return QStringList(themeName()); +} + +// Restrict the styles to "fusion" to prevent native styles requiring native +// window handles (eg Windows Vista style) from being used. +class OffscreenTheme : public QPlatformTheme +{ +public: + OffscreenTheme() {} + + QVariant themeHint(ThemeHint h) const override + { + switch (h) { + case StyleNames: + return QVariant(QStringList(QStringLiteral("fusion"))); + default: + break; + } + return QPlatformTheme::themeHint(h); + } +}; + +QPlatformTheme *QOffscreenIntegration::createPlatformTheme(const QString &name) const +{ + return name == themeName() ? new OffscreenTheme() : nullptr; +} + QPlatformFontDatabase *QOffscreenIntegration::fontDatabase() const { return m_fontDatabase.data(); diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.h b/src/plugins/platforms/offscreen/qoffscreenintegration.h index 569ec8fc28..f72587d11a 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.h +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.h @@ -69,6 +69,9 @@ public: QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + QStringList themeNames() const; + QPlatformTheme *createPlatformTheme(const QString &name) const; + static QOffscreenIntegration *createOffscreenIntegration(); private: -- cgit v1.2.3 From a95936f37695706144ba6ca050c3493af88d7d34 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 12 Nov 2017 15:49:44 -0800 Subject: QSemaphoreReleaser: Move private members to the usual position Change-Id: Ic632b4163d784b83951cfffd14f67b902d096d8b Reviewed-by: Edward Welbourne Reviewed-by: hjk --- src/corelib/thread/qsemaphore.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/thread/qsemaphore.h b/src/corelib/thread/qsemaphore.h index a92740c8ce..9de23173e8 100644 --- a/src/corelib/thread/qsemaphore.h +++ b/src/corelib/thread/qsemaphore.h @@ -71,8 +71,6 @@ private: class QSemaphoreReleaser { - QSemaphore *m_sem = nullptr; - int m_n; public: QSemaphoreReleaser() = default; explicit QSemaphoreReleaser(QSemaphore &sem, int n = 1) Q_DECL_NOTHROW @@ -106,6 +104,10 @@ public: m_sem = nullptr; return old; } + +private: + QSemaphore *m_sem = nullptr; + int m_n; }; #endif // QT_NO_THREAD -- cgit v1.2.3 From 26141086963d1c6ea9451e17c831d748690cf44d Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Mon, 13 Nov 2017 23:55:44 -0800 Subject: qmake: properly filter simulator devices by minimum deployment target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes an issue where a build error may be introduced by a simulator being selected whose OS version is lower than the application's minimum deployment target. Task-number: QTBUG-64456 Change-Id: Ic7c834a1473c183ebb910bc01a416fe1e23a5a14 Reviewed-by: Eike Ziller Reviewed-by: Tor Arne Vestbø --- mkspecs/features/uikit/device_destinations.sh | 6 +- mkspecs/features/uikit/devices.pl | 56 ------------------ mkspecs/features/uikit/devices.py | 82 +++++++++++++++++++++++++++ mkspecs/features/uikit/xcodebuild.mk | 4 +- mkspecs/features/uikit/xcodebuild.prf | 6 +- 5 files changed, 91 insertions(+), 63 deletions(-) delete mode 100755 mkspecs/features/uikit/devices.pl create mode 100755 mkspecs/features/uikit/devices.py diff --git a/mkspecs/features/uikit/device_destinations.sh b/mkspecs/features/uikit/device_destinations.sh index 162ad01aaf..649dd399a7 100755 --- a/mkspecs/features/uikit/device_destinations.sh +++ b/mkspecs/features/uikit/device_destinations.sh @@ -40,10 +40,12 @@ ############################################################################# DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -booted_simulator=$($DIR/devices.pl "$1" "Booted" "NOT unavailable" | tail -n 1) +scheme=$1 +shift +booted_simulator=$($DIR/devices.py --state booted $@ | tail -n 1) echo "SIMULATOR_DEVICES = $booted_simulator" -xcodebuild test -scheme $2 -destination 'id=0' -destination-timeout 1 2>&1| sed -n 's/{ \(platform:.*\) }/\1/p' | while read destination; do +xcodebuild test -scheme $scheme -destination 'id=0' -destination-timeout 1 2>&1| sed -n 's/{ \(platform:.*\) }/\1/p' | while read destination; do id=$(echo $destination | sed -n -E 's/.*id:([^ ,]+).*/\1/p') [[ $id == *"placeholder"* ]] && continue diff --git a/mkspecs/features/uikit/devices.pl b/mkspecs/features/uikit/devices.pl deleted file mode 100755 index 8d69a97273..0000000000 --- a/mkspecs/features/uikit/devices.pl +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/perl - -############################################################################# -## -## Copyright (C) 2017 The Qt Company Ltd. -## Contact: https://www.qt.io/licensing/ -## -## This file is the build configuration utility of the Qt Toolkit. -## -## $QT_BEGIN_LICENSE:LGPL$ -## Commercial License Usage -## Licensees holding valid commercial Qt licenses may use this file in -## accordance with the commercial license agreement provided with the -## Software or, alternatively, in accordance with the terms contained in -## a written agreement between you and The Qt Company. For licensing terms -## and conditions see https://www.qt.io/terms-conditions. For further -## information use the contact form at https://www.qt.io/contact-us. -## -## GNU Lesser General Public License Usage -## Alternatively, this file may be used under the terms of the GNU Lesser -## General Public License version 3 as published by the Free Software -## Foundation and appearing in the file LICENSE.LGPL3 included in the -## packaging of this file. Please review the following information to -## ensure the GNU Lesser General Public License version 3 requirements -## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -## -## GNU General Public License Usage -## Alternatively, this file may be used under the terms of the GNU -## General Public License version 2.0 or (at your option) the GNU General -## Public license version 3 or any later version approved by the KDE Free -## Qt Foundation. The licenses are as published by the Free Software -## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -## included in the packaging of this file. Please review the following -## information to ensure the GNU General Public License requirements will -## be met: https://www.gnu.org/licenses/gpl-2.0.html and -## https://www.gnu.org/licenses/gpl-3.0.html. -## -## $QT_END_LICENSE$ -## -############################################################################# - -$output = `xcrun simctl list devices --json 2>&1`; -$output =~ s/\n//g; - -BLOCK: -foreach $block ($output =~ /{.*?}/g) { - foreach $filter (@ARGV) { - if ($filter =~ /^NOT\s(.*)/) { - $block =~ /$1/ && next BLOCK; - } else { - $block =~ /$filter/ || next BLOCK; - } - } - $block =~ /udid[:|\s|\"]+(.*)\"/; - print "$1\n"; -} diff --git a/mkspecs/features/uikit/devices.py b/mkspecs/features/uikit/devices.py new file mode 100755 index 0000000000..0443e838f2 --- /dev/null +++ b/mkspecs/features/uikit/devices.py @@ -0,0 +1,82 @@ +#!/usr/bin/python + +############################################################################# +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is the build configuration utility of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function + +import argparse +import json +import subprocess +from distutils.version import StrictVersion + +def is_suitable_runtime(runtimes, runtime_name, platform, min_version): + for runtime in runtimes: + identifier = runtime["identifier"] + if (runtime["name"] == runtime_name or identifier == runtime_name) \ + and "unavailable" not in runtime["availability"] \ + and identifier.startswith("com.apple.CoreSimulator.SimRuntime.{}".format(platform)) \ + and StrictVersion(runtime["version"]) >= min_version: + return True + return False + +def simctl_runtimes(): + return json.loads(subprocess.check_output( + ["/usr/bin/xcrun", "simctl", "list", "runtimes", "--json"]))["runtimes"] + +def simctl_devices(): + return json.loads(subprocess.check_output( + ["/usr/bin/xcrun", "simctl", "list", "devices", "--json"]))["devices"] + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument('--platform', choices=['iOS', 'tvOS', 'watchOS'], required=True) + parser.add_argument('--minimum-deployment-target', type=StrictVersion, default='0.0') + parser.add_argument('--state', + choices=['booted', 'shutdown', 'creating', 'booting', 'shutting-down'], action='append') + args = parser.parse_args() + + runtimes = simctl_runtimes() + device_dict = simctl_devices() + for runtime_name in device_dict: + if is_suitable_runtime(runtimes, runtime_name, args.platform, args.minimum_deployment_target): + for device in device_dict[runtime_name]: + if "unavailable" not in device["availability"] \ + and (args.state is None or device["state"].lower() in args.state): + print(device["udid"]) diff --git a/mkspecs/features/uikit/xcodebuild.mk b/mkspecs/features/uikit/xcodebuild.mk index 0b3ad632b6..435b9dbdf2 100644 --- a/mkspecs/features/uikit/xcodebuild.mk +++ b/mkspecs/features/uikit/xcodebuild.mk @@ -63,7 +63,7 @@ ifneq ($(filter check%,$(MAKECMDGOALS)),) ifeq ($(DEVICES),) $(info Enumerating test destinations (you may override this by setting DEVICES explicitly), please wait...) DESTINATIONS_INCLUDE = /tmp/device_destinations.mk - $(shell $(MAKEFILE_DIR)device_destinations.sh '$(EXPORT_DEVICE_FILTER)' $(TARGET) > $(DESTINATIONS_INCLUDE)) + $(shell $(MAKEFILE_DIR)device_destinations.sh $(TARGET) $(EXPORT_DEVICE_FILTER) > $(DESTINATIONS_INCLUDE)) include $(DESTINATIONS_INCLUDE) endif endif @@ -72,7 +72,7 @@ endif %-device: DEVICES = $(HARDWARE_DEVICES) GENERIC_DEVICE_DESTINATION := $(EXPORT_GENERIC_DEVICE_DESTINATION) -GENERIC_SIMULATOR_DESTINATION := "id=$(shell $(MAKEFILE_DIR)devices.pl '$(EXPORT_DEVICE_FILTER)' "NOT unavailable" | tail -n 1)" +GENERIC_SIMULATOR_DESTINATION := "id=$(shell $(MAKEFILE_DIR)devices.py $(EXPORT_DEVICE_FILTER) | tail -n 1)" %-simulator: DESTINATION = $(if $(DESTINATION_ID),"id=$(DESTINATION_ID)",$(GENERIC_SIMULATOR_DESTINATION)) %-device: DESTINATION = $(if $(DESTINATION_ID),"id=$(DESTINATION_ID)",$(GENERIC_DEVICE_DESTINATION)) diff --git a/mkspecs/features/uikit/xcodebuild.prf b/mkspecs/features/uikit/xcodebuild.prf index a766b9ea5c..7a6b2acfc2 100644 --- a/mkspecs/features/uikit/xcodebuild.prf +++ b/mkspecs/features/uikit/xcodebuild.prf @@ -40,15 +40,15 @@ CONFIG += no_default_goal_deps DEVICE_SDK = $${device.sdk} SIMULATOR_SDK = $${simulator.sdk} ios { - DEVICE_FILTER = "iPhone|iPad" + DEVICE_FILTER = --platform iOS --minimum-deployment-target $$QMAKE_IOS_DEPLOYMENT_TARGET GENERIC_DEVICE_DESTINATION = "generic/platform=iOS" } tvos { - DEVICE_FILTER = "Apple TV" + DEVICE_FILTER = --platform tvOS --minimum-deployment-target $$QMAKE_TVOS_DEPLOYMENT_TARGET GENERIC_DEVICE_DESTINATION = "generic/platform=tvOS" } watchos { - DEVICE_FILTER = "Apple Watch" + DEVICE_FILTER = --platform watchOS --minimum-deployment-target $$QMAKE_WATCHOS_DEPLOYMENT_TARGET GENERIC_DEVICE_DESTINATION = "generic/platform=watchOS" } QMAKE_EXTRA_VARIABLES += DEVICE_SDK SIMULATOR_SDK DEVICE_FILTER GENERIC_DEVICE_DESTINATION -- cgit v1.2.3 From 66bace390ba4c0d20f006f02dbcba45e30d08590 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 8 Nov 2017 16:18:31 +0100 Subject: tst_qnetworkreply::getFromUnreachableIp - fix win64 also MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Looking at the failures in grafana it appears this test is also failing on Windows 64. The same fix applies then, and we use Q_OS_WIN now. Change-Id: Iafcfd6d1e747f3c816878cad072fbfae3aee19ca Reviewed-by: MÃ¥rten Nordheim Reviewed-by: Edward Welbourne --- tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index b86750a900..3a752c0748 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -6766,9 +6766,9 @@ void tst_QNetworkReply::getFromUnreachableIp() { QNetworkAccessManager manager; -#ifdef Q_OS_WIN32 +#ifdef Q_OS_WIN // This test assumes that attempt to connect to 255.255.255.255 fails more - // or less fast/immediately. This is not what we observe on Windows x86: + // or less fast/immediately. This is not what we observe on Windows: // WSAConnect on non-blocking socket returns SOCKET_ERROR, WSAGetLastError // returns WSAEWOULDBLOCK (expected) and getsockopt most of the time returns // NOERROR; so socket engine starts a timer (30 s.) and waits for a timeout/ @@ -6806,7 +6806,7 @@ void tst_QNetworkReply::getFromUnreachableIp() #else // bearermanagement QSKIP("This test is non-deterministic on Windows x86"); #endif // !bearermanagement -#endif // Q_OS_WIN32 +#endif // Q_OS_WIN QNetworkRequest request(QUrl("http://255.255.255.255/42/23/narf/narf/narf")); QNetworkReplyPtr reply(manager.get(request)); -- cgit v1.2.3 From 2884c652b5b2d186eb1c43fd8ecb82df83a581c9 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Tue, 14 Nov 2017 11:17:40 +0100 Subject: A brute-force solution to get QRandomGenerator build on Integrity Task-number: QTBUG-64451 Change-Id: Ife11c3448f54609ba6e85a269a3b5376c43a075f Reviewed-by: Thiago Macieira --- src/corelib/global/qrandom.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index 58458d6984..72ac8d332b 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -411,11 +411,12 @@ struct QRandomGenerator::SystemAndGlobalGenerators void confirmLiteral() { -#if defined(Q_COMPILER_CONSTEXPR) && !defined(Q_CC_MSVC) +#if defined(Q_COMPILER_CONSTEXPR) && !defined(Q_CC_MSVC) && !defined(Q_OS_INTEGRITY) // Currently fails to compile with MSVC 2017, saying QBasicMutex is not // a literal type. Disassembly with MSVC 2013 and 2015 shows it is // actually a literal; MSVC 2017 has a bug relating to this, so we're - // withhold judgement for now. + // withhold judgement for now. Integrity's compiler is unable to + // guarantee g's alignment for some reason. constexpr SystemAndGlobalGenerators g = {}; Q_UNUSED(g); -- cgit v1.2.3 From fd6d2eb2c35a44935c3f5885fcb941f7f02ccde0 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Mon, 13 Nov 2017 21:34:30 +0100 Subject: test: blacklist tst_QNetworkAccessManager_And_QProgressDialog::downloadCheck(with-zeroCopy) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit on Windows. Task-number: QTBUG-64471 Change-Id: I8ec7e86b7734eda606c5a5bf07bd39ed4bb91336 Reviewed-by: Tony Sarajärvi --- tests/auto/other/qnetworkaccessmanager_and_qprogressdialog/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/auto/other/qnetworkaccessmanager_and_qprogressdialog/BLACKLIST diff --git a/tests/auto/other/qnetworkaccessmanager_and_qprogressdialog/BLACKLIST b/tests/auto/other/qnetworkaccessmanager_and_qprogressdialog/BLACKLIST new file mode 100644 index 0000000000..aea819fc2e --- /dev/null +++ b/tests/auto/other/qnetworkaccessmanager_and_qprogressdialog/BLACKLIST @@ -0,0 +1,2 @@ +[downloadCheck:with-zeroCopy] +windows -- cgit v1.2.3 From 3dab19ffed61a69166045d6e90e1e114d81f85a8 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 13 Nov 2017 13:03:36 +0100 Subject: OCI: Match the constraints on the index_name column When looking for the primary index, it is possible that the constraint_name in the all_ind_columns table does not match that of the index_name. Whereas the index_name will match in this case, so the query should set the where clause on the index_name in both tables. Task-number: QTBUG-64427 Change-Id: I1bf1fb580e620b9f75f2fde1ecf408842e377365 Reviewed-by: Jesus Fernandez --- src/plugins/sqldrivers/oci/qsql_oci.cpp | 2 +- tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/plugins/sqldrivers/oci/qsql_oci.cpp b/src/plugins/sqldrivers/oci/qsql_oci.cpp index a4793351de..9ce2fc1b55 100644 --- a/src/plugins/sqldrivers/oci/qsql_oci.cpp +++ b/src/plugins/sqldrivers/oci/qsql_oci.cpp @@ -2603,7 +2603,7 @@ QSqlIndex QOCIDriver::primaryIndex(const QString& tablename) const QString stmt(QLatin1String("select b.column_name, b.index_name, a.table_name, a.owner " "from all_constraints a, all_ind_columns b " "where a.constraint_type='P' " - "and b.index_name = a.constraint_name " + "and b.index_name = a.index_name " "and b.index_owner = a.owner")); bool buildIndex = false; diff --git a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp index 81206a5856..7bfa29ec8e 100644 --- a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp +++ b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp @@ -100,6 +100,9 @@ void tst_QSqlDriver::cleanupTestCase() foreach (const QString &dbName, dbs.dbNames) { QSqlDatabase db = QSqlDatabase::database(dbName); tst_Databases::safeDropTable(db, qTableName("relTEST1", __FILE__, db)); + const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriver::Oracle) + tst_Databases::safeDropTable(db, qTableName("clobTable", __FILE__, db)); } dbs.close(); } @@ -214,6 +217,20 @@ void tst_QSqlDriver::primaryIndex() QCOMPARE(index.count(), 1); //mysql will always find the table name regardless of casing else QCOMPARE(index.count(), 0); + + // Test getting a primary index for a table with a clob in it - QTBUG-64427 + if (dbType == QSqlDriver::Oracle) { + const QString clobTable(qTableName("clobTable", __FILE__, db)); + QSqlQuery qry(db); + QVERIFY_SQL(qry, exec("CREATE TABLE " + clobTable + " (id INTEGER, clobField CLOB)")); + QVERIFY_SQL(qry, exec("CREATE UNIQUE INDEX " + clobTable + "IDX ON " + clobTable + " (id)")); + QVERIFY_SQL(qry, exec("ALTER TABLE " + clobTable + " ADD CONSTRAINT " + clobTable + + "PK PRIMARY KEY(id)")); + QVERIFY_SQL(qry, exec("ALTER TABLE " + clobTable + " MODIFY (id NOT NULL ENABLE)")); + const QSqlIndex primaryIndex = db.driver()->primaryIndex(clobTable); + QCOMPARE(primaryIndex.count(), 1); + QCOMPARE(primaryIndex.fieldName(0), QStringLiteral("ID")); + } } void tst_QSqlDriver::formatValue() -- cgit v1.2.3 From 7465329fe18315d50c4e6325cfd7c9fc1e203812 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 25 Oct 2017 13:24:49 +0200 Subject: QAbstractButton: don't clear 'pressed' flag unless left button is released As it stood, we would set 'pressed' to false regardless of which button that was released. This would end up wrong if pressing the left button, and at the same time, did a click with the right button. This would clear the flag prematurely, and cause a release signal not to be emitted when later releasing the left button. tst_QAbstractButton: adding autotest Adding tests to simulate the bug report's cases: 1) left press button 2) click right/middle key 3) move mouse out of button's boundary 4) test if the released() signal triggered properly Taks-number: QTBUG-53244 Change-Id: Ifc0d5f52a917ac9cd2df5e86c0475abcda47e425 Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qabstractbutton.cpp | 3 +- .../qabstractbutton/tst_qabstractbutton.cpp | 32 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp index dbd94e890d..5854472ff0 100644 --- a/src/widgets/widgets/qabstractbutton.cpp +++ b/src/widgets/widgets/qabstractbutton.cpp @@ -991,13 +991,14 @@ void QAbstractButton::mousePressEvent(QMouseEvent *e) void QAbstractButton::mouseReleaseEvent(QMouseEvent *e) { Q_D(QAbstractButton); - d->pressed = false; if (e->button() != Qt::LeftButton) { e->ignore(); return; } + d->pressed = false; + if (!d->down) { // refresh is required by QMacStyle to resume the default button animation d->refresh(); diff --git a/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp b/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp index 9efa8cf47e..bc7756d32f 100644 --- a/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp +++ b/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp @@ -68,6 +68,7 @@ private slots: void shortcutEvents(); void stopRepeatTimer(); + void mouseReleased(); // QTBUG-53244 #ifdef QT_KEYPAD_NAVIGATION void keyNavigation(); #endif @@ -563,6 +564,37 @@ void tst_QAbstractButton::stopRepeatTimer() QCOMPARE(button.timerEventCount(), 0); } +void tst_QAbstractButton::mouseReleased() // QTBUG-53244 +{ + MyButton button(nullptr); + button.setObjectName("button"); + button.setGeometry(0, 0, 20, 20); + QSignalSpy spyPress(&button, &QAbstractButton::pressed); + QSignalSpy spyRelease(&button, &QAbstractButton::released); + + QTest::mousePress(&button, Qt::LeftButton); + QCOMPARE(spyPress.count(), 1); + QCOMPARE(button.isDown(), true); + QCOMPARE(spyRelease.count(), 0); + + QTest::mouseClick(&button, Qt::RightButton); + QCOMPARE(spyPress.count(), 1); + QCOMPARE(button.isDown(), true); + QCOMPARE(spyRelease.count(), 0); + + QPointF posOutOfWidget = QPointF(30, 30); + QMouseEvent me(QEvent::MouseMove, + posOutOfWidget, Qt::NoButton, + Qt::MouseButtons(Qt::LeftButton), + Qt::NoModifier); // mouse press and move + + qApp->sendEvent(&button, &me); + // should emit released signal once mouse is dragging out of boundary + QCOMPARE(spyPress.count(), 1); + QCOMPARE(button.isDown(), false); + QCOMPARE(spyRelease.count(), 1); +} + #ifdef QT_KEYPAD_NAVIGATION void tst_QAbstractButton::keyNavigation() { -- cgit v1.2.3 From 7416fc5e80446ab25b44803f9f1858d9822e6be7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 8 Nov 2017 01:02:28 +0100 Subject: Cocoa: Set NSImage (point) size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit when converting from QPixmap. This will make the image display correctly when used by native API. Task-number: QTBUG-60769 Change-Id: Iec3160affbe2902d34a219b6816f503dc2f56f74 Reviewed-by: Tor Arne Vestbø --- src/gui/painting/qcoregraphics.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/painting/qcoregraphics.mm b/src/gui/painting/qcoregraphics.mm index a234a12bf0..e1601d87dc 100644 --- a/src/gui/painting/qcoregraphics.mm +++ b/src/gui/painting/qcoregraphics.mm @@ -110,6 +110,7 @@ NSImage *qt_mac_create_nsimage(const QPixmap &pm) QImage image = pm.toImage(); CGImageRef cgImage = qt_mac_toCGImage(image); NSImage *nsImage = qt_mac_cgimage_to_nsimage(cgImage); + nsImage.size = (pm.size() / pm.devicePixelRatioF()).toCGSize(); CGImageRelease(cgImage); return nsImage; } -- cgit v1.2.3 From c8a5f331c8fdbf243ccb467f7bc3c9f62bd47c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Sun, 12 Nov 2017 18:54:04 +0100 Subject: QMenu: Update menu action sizes if popup is (not)caused from menu bar Menu width differs if it contains key shortcuts or not. Amends 6634c424f8ca0e3aed2898507d5f9f4b774c4602 Task-number: QTBUG-49435 Task-number: QTBUG-61181 Task-number: QTBUG-64449 Change-Id: I8c479af550128069ca91dd089dfc7bd8c24c66ba Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qmenu.cpp | 6 ++++++ src/widgets/widgets/qmenu_p.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index ded218de73..463254efa9 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -2339,6 +2339,12 @@ void QMenu::popup(const QPoint &p, QAction *atAction) d->updateLayoutDirection(); d->adjustMenuScreen(p); + const bool contextMenu = d->isContextMenu(); + if (d->lastContextMenu != contextMenu) { + d->itemsDirty = true; + d->lastContextMenu = contextMenu; + } + #if QT_CONFIG(menubar) // if this menu is part of a chain attached to a QMenuBar, set the // _NET_WM_WINDOW_TYPE_DROPDOWN_MENU X11 window type diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index bdf576b980..a81d8ffafb 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -272,6 +272,7 @@ public: QMenuPrivate() : itemsDirty(false), hasCheckableItems(false), + lastContextMenu(false), collapsibleSeparators(true), toolTipsVisible(false), delayedPopupGuard(false), @@ -464,6 +465,7 @@ public: mutable bool itemsDirty : 1; mutable bool hasCheckableItems : 1; + bool lastContextMenu : 1; bool collapsibleSeparators : 1; bool toolTipsVisible : 1; bool delayedPopupGuard : 1; -- cgit v1.2.3 From 26986276531b7f0a3f950d4b3960d5302010d204 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 19 Oct 2017 15:35:25 +0700 Subject: QMenu: Refactor insertion of action in QPA menu First, remove a bit of code duplication around the creation of the platform menu item. Then, we move copyActionToPlatformItem() inside QMenuPrivate to get rid of one parameter. Change-Id: I5a33103566367f2313930479844365e79773d82f Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qmenu.cpp | 108 +++++++++++++++++++++--------------------- src/widgets/widgets/qmenu_p.h | 3 ++ 2 files changed, 57 insertions(+), 54 deletions(-) diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 463254efa9..c5b912e35b 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -234,9 +234,6 @@ void QMenuPrivate::setPlatformMenu(QPlatformMenu *menu) } } -// forward declare function -static void copyActionToPlatformItem(const QAction *action, QPlatformMenuItem *item, QPlatformMenu *itemsMenu); - void QMenuPrivate::syncPlatformMenu() { Q_Q(QMenu); @@ -246,19 +243,64 @@ void QMenuPrivate::syncPlatformMenu() QPlatformMenuItem *beforeItem = Q_NULLPTR; const QList actions = q->actions(); for (QList::const_reverse_iterator it = actions.rbegin(), end = actions.rend(); it != end; ++it) { - QPlatformMenuItem *menuItem = platformMenu->createMenuItem(); - QAction *action = *it; - menuItem->setTag(reinterpret_cast(action)); - QObject::connect(menuItem, SIGNAL(activated()), action, SLOT(trigger()), Qt::QueuedConnection); - QObject::connect(menuItem, SIGNAL(hovered()), action, SIGNAL(hovered()), Qt::QueuedConnection); - copyActionToPlatformItem(action, menuItem, platformMenu.data()); - platformMenu->insertMenuItem(menuItem, beforeItem); + QPlatformMenuItem *menuItem = insertActionInPlatformMenu(*it, beforeItem); beforeItem = menuItem; } platformMenu->syncSeparatorsCollapsible(collapsibleSeparators); platformMenu->setEnabled(q->isEnabled()); } +void QMenuPrivate::copyActionToPlatformItem(const QAction *action, QPlatformMenuItem *item) +{ + item->setText(action->text()); + item->setIsSeparator(action->isSeparator()); + if (action->isIconVisibleInMenu()) { + item->setIcon(action->icon()); + if (QWidget *w = action->parentWidget()) { + QStyleOption opt; + opt.init(w); + item->setIconSize(w->style()->pixelMetric(QStyle::PM_SmallIconSize, &opt, w)); + } else { + QStyleOption opt; + item->setIconSize(qApp->style()->pixelMetric(QStyle::PM_SmallIconSize, &opt, 0)); + } + } else { + item->setIcon(QIcon()); + } + item->setVisible(action->isVisible()); +#if QT_CONFIG(shortcut) + item->setShortcut(action->shortcut()); +#endif + item->setCheckable(action->isCheckable()); + item->setChecked(action->isChecked()); + item->setHasExclusiveGroup(action->actionGroup() && action->actionGroup()->isExclusive()); + item->setFont(action->font()); + item->setRole((QPlatformMenuItem::MenuRole) action->menuRole()); + item->setEnabled(action->isEnabled()); + + if (action->menu()) { + if (!action->menu()->platformMenu()) + action->menu()->setPlatformMenu(platformMenu->createSubMenu()); + item->setMenu(action->menu()->platformMenu()); + } else { + item->setMenu(0); + } +} + +QPlatformMenuItem * QMenuPrivate::insertActionInPlatformMenu(const QAction *action, QPlatformMenuItem *beforeItem) +{ + QPlatformMenuItem *menuItem = platformMenu->createMenuItem(); + Q_ASSERT(menuItem); + + menuItem->setTag(reinterpret_cast(action)); + QObject::connect(menuItem, &QPlatformMenuItem::activated, action, &QAction::trigger, Qt::QueuedConnection); + QObject::connect(menuItem, &QPlatformMenuItem::hovered, action, &QAction::hovered, Qt::QueuedConnection); + copyActionToPlatformItem(action, menuItem); + platformMenu->insertMenuItem(menuItem, beforeItem); + + return menuItem; +} + int QMenuPrivate::scrollerHeight() const { Q_Q(const QMenu); @@ -3483,43 +3525,6 @@ QMenu::timerEvent(QTimerEvent *e) } } -static void copyActionToPlatformItem(const QAction *action, QPlatformMenuItem *item, QPlatformMenu *itemsMenu) -{ - item->setText(action->text()); - item->setIsSeparator(action->isSeparator()); - if (action->isIconVisibleInMenu()) { - item->setIcon(action->icon()); - if (QWidget *w = action->parentWidget()) { - QStyleOption opt; - opt.init(w); - item->setIconSize(w->style()->pixelMetric(QStyle::PM_SmallIconSize, &opt, w)); - } else { - QStyleOption opt; - item->setIconSize(qApp->style()->pixelMetric(QStyle::PM_SmallIconSize, &opt, 0)); - } - } else { - item->setIcon(QIcon()); - } - item->setVisible(action->isVisible()); -#ifndef QT_NO_SHORTCUT - item->setShortcut(action->shortcut()); -#endif - item->setCheckable(action->isCheckable()); - item->setChecked(action->isChecked()); - item->setHasExclusiveGroup(action->actionGroup() && action->actionGroup()->isExclusive()); - item->setFont(action->font()); - item->setRole((QPlatformMenuItem::MenuRole) action->menuRole()); - item->setEnabled(action->isEnabled()); - - if (action->menu()) { - if (!action->menu()->platformMenu()) - action->menu()->setPlatformMenu(itemsMenu->createSubMenu()); - item->setMenu(action->menu()->platformMenu()); - } else { - item->setMenu(0); - } -} - /*! \reimp */ @@ -3573,15 +3578,10 @@ void QMenu::actionEvent(QActionEvent *e) if (!d->platformMenu.isNull()) { if (e->type() == QEvent::ActionAdded) { - QPlatformMenuItem *menuItem = d->platformMenu->createMenuItem(); - menuItem->setTag(reinterpret_cast(e->action())); - QObject::connect(menuItem, SIGNAL(activated()), e->action(), SLOT(trigger())); - QObject::connect(menuItem, SIGNAL(hovered()), e->action(), SIGNAL(hovered())); - copyActionToPlatformItem(e->action(), menuItem, d->platformMenu); QPlatformMenuItem *beforeItem = e->before() ? d->platformMenu->menuItemForTag(reinterpret_cast(e->before())) : nullptr; - d->platformMenu->insertMenuItem(menuItem, beforeItem); + d->insertActionInPlatformMenu(e->action(), beforeItem); } else if (e->type() == QEvent::ActionRemoved) { QPlatformMenuItem *menuItem = d->platformMenu->menuItemForTag(reinterpret_cast(e->action())); d->platformMenu->removeMenuItem(menuItem); @@ -3589,7 +3589,7 @@ void QMenu::actionEvent(QActionEvent *e) } else if (e->type() == QEvent::ActionChanged) { QPlatformMenuItem *menuItem = d->platformMenu->menuItemForTag(reinterpret_cast(e->action())); if (menuItem) { - copyActionToPlatformItem(e->action(), menuItem, d->platformMenu); + d->copyActionToPlatformItem(e->action(), menuItem); d->platformMenu->syncMenuItem(menuItem); } } diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index a81d8ffafb..ce5134958e 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -295,6 +295,9 @@ public: QPlatformMenu *createPlatformMenu(); void setPlatformMenu(QPlatformMenu *menu); void syncPlatformMenu(); + void copyActionToPlatformItem(const QAction *action, QPlatformMenuItem *item); + QPlatformMenuItem *insertActionInPlatformMenu(const QAction *action, QPlatformMenuItem *beforeItem); + #ifdef Q_OS_OSX void moveWidgetToPlatformItem(QWidget *w, QPlatformMenuItem* item); #endif -- cgit v1.2.3 From d7dce54ba0c018c4db92a291d322167dcf308d75 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 7 Nov 2017 11:35:46 +0700 Subject: QMacStyle: Rename Cocoa controls enum names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For easier sorting and grouping by actual Cocoa NSControl class. We also shorten the names and move the types inside QMacStylePrivate. Change-Id: Iac093fd359da66abd263aca841b870ea84337f50 Reviewed-by: Morten Johan Sørvig --- src/plugins/styles/mac/qmacstyle_mac.mm | 131 +++++++++++++++-------------- src/plugins/styles/mac/qmacstyle_mac_p_p.h | 56 ++++++------ 2 files changed, 99 insertions(+), 88 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index b24ecee102..9c5ede6d47 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -1849,36 +1849,36 @@ ThemeDrawState QMacStylePrivate::getDrawState(QStyle::State flags) return tds; } -static QCocoaWidget cocoaWidgetFromHIThemeButtonKind(ThemeButtonKind kind) + QMacStylePrivate::CocoaControl QMacStylePrivate::cocoaControlFromHIThemeButtonKind(ThemeButtonKind kind) { - QCocoaWidget w; + CocoaControl w; switch (kind) { case kThemePopupButton: case kThemePopupButtonSmall: case kThemePopupButtonMini: - w.first = QCocoaPopupButton; + w.first = Button_PopupButton; break; case kThemeComboBox: - w.first = QCocoaComboBox; + w.first = ComboBox; break; case kThemeArrowButton: - w.first = QCocoaDisclosureButton; + w.first = Button_Disclosure; break; case kThemeCheckBox: case kThemeCheckBoxSmall: case kThemeCheckBoxMini: - w.first = QCocoaCheckBox; + w.first = Button_CheckBox; break; case kThemeRadioButton: case kThemeRadioButtonSmall: case kThemeRadioButtonMini: - w.first = QCocoaRadioButton; + w.first = Button_RadioButton; break; case kThemePushButton: case kThemePushButtonSmall: case kThemePushButtonMini: - w.first = QCocoaPushButton; + w.first = Button_PushButton; break; default: break; @@ -1914,13 +1914,13 @@ static NSButton *makeButton(NSButtonType type, NSBezelStyle style) return b; } -NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget) const +NSView *QMacStylePrivate::cocoaControl(CocoaControl widget) const { NSView *bv = cocoaControls.value(widget, nil); if (!bv) { switch (widget.first) { - case QCocoaBox: { + case Box: { NSBox *bc = [[NSBox alloc] init]; bc.title = @""; bc.titlePosition = NSNoTitle; @@ -1929,48 +1929,48 @@ NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget) const bv = bc; break; } - case QCocoaCheckBox: + case Button_CheckBox: bv = makeButton(NSSwitchButton, NSRegularSquareBezelStyle); break; - case QCocoaDisclosureButton: + case Button_Disclosure: bv = makeButton(NSOnOffButton, NSDisclosureBezelStyle); break; - case QCocoaPopupButton: - case QCocoaPullDownButton: { + case Button_PopupButton: + case Button_PullDown: { NSPopUpButton *bc = [[NSPopUpButton alloc] init]; bc.title = @""; - if (widget.first == QCocoaPullDownButton) + if (widget.first == Button_PullDown) bc.pullsDown = YES; bv = bc; break; } - case QCocoaPushButton: + case Button_PushButton: bv = makeButton(NSMomentaryLightButton, NSRoundedBezelStyle); break; - case QCocoaRadioButton: + case Button_RadioButton: bv = makeButton(NSRadioButton, NSRegularSquareBezelStyle); break; - case QCocoaComboBox: + case ComboBox: bv = [[NSComboBox alloc] init]; break; - case QCocoaProgressIndicator: + case ProgressIndicator_Determinate: bv = [[NSProgressIndicator alloc] init]; break; - case QCocoaIndeterminateProgressIndicator: + case ProgressIndicator_Indeterminate: bv = [[QIndeterminateProgressIndicator alloc] init]; break; - case QCocoaHorizontalScroller: + case Scroller_Horizontal: bv = [[NSScroller alloc] initWithFrame:NSMakeRect(0, 0, 200, 20)]; break; - case QCocoaVerticalScroller: + case Scroller_Vertical: // Cocoa sets the orientation from the view's frame // at construction time, and it cannot be changed later. bv = [[NSScroller alloc] initWithFrame:NSMakeRect(0, 0, 20, 200)]; break; - case QCocoaHorizontalSlider: + case Slider_Horizontal: bv = [[NSSlider alloc] initWithFrame:NSMakeRect(0, 0, 200, 20)]; break; - case QCocoaVerticalSlider: + case Slider_Vertical: // Cocoa sets the orientation from the view's frame // at construction time, and it cannot be changed later. bv = [[NSSlider alloc] initWithFrame:NSMakeRect(0, 0, 20, 200)]; @@ -1991,10 +1991,10 @@ NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget) const default: break; } - } else if (widget.first == QCocoaProgressIndicator || - widget.first == QCocoaIndeterminateProgressIndicator) { + } else if (widget.first == ProgressIndicator_Determinate || + widget.first == ProgressIndicator_Indeterminate) { auto *pi = static_cast(bv); - pi.indeterminate = (widget.first == QCocoaIndeterminateProgressIndicator); + pi.indeterminate = (widget.first == ProgressIndicator_Indeterminate); switch (widget.second) { case QStyleHelper::SizeSmall: pi.controlSize = NSSmallControlSize; @@ -2013,15 +2013,15 @@ NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget) const return bv; } -NSCell *QMacStylePrivate::cocoaCell(QCocoaWidget widget) const +NSCell *QMacStylePrivate::cocoaCell(CocoaControl widget) const { NSCell *cell = cocoaCells[widget]; if (!cell) { switch (widget.first) { - case QCocoaStepper: + case Stepper: cell = [[NSStepperCell alloc] init]; break; - case QCocoaDisclosureButton: { + case Button_Disclosure: { NSButtonCell *bc = [[NSButtonCell alloc] init]; bc.buttonType = NSOnOffButton; bc.bezelStyle = NSDisclosureBezelStyle; @@ -2049,31 +2049,31 @@ NSCell *QMacStylePrivate::cocoaCell(QCocoaWidget widget) const return cell; } -void QMacStylePrivate::drawNSViewInRect(QCocoaWidget widget, NSView *view, const QRect &qtRect, QPainter *p, bool isQWidget, QCocoaDrawRectBlock drawRectBlock) const +void QMacStylePrivate::drawNSViewInRect(CocoaControl widget, NSView *view, const QRect &qtRect, QPainter *p, bool isQWidget, DrawRectBlock drawRectBlock) const { QPoint offset; - if (widget == QCocoaWidget(QCocoaRadioButton, QStyleHelper::SizeLarge)) + if (widget == CocoaControl(Button_RadioButton, QStyleHelper::SizeLarge)) offset.setY(2); - else if (widget == QCocoaWidget(QCocoaRadioButton, QStyleHelper::SizeSmall)) + else if (widget == CocoaControl(Button_RadioButton, QStyleHelper::SizeSmall)) offset = QPoint(-1, 2); - else if (widget == QCocoaWidget(QCocoaRadioButton, QStyleHelper::SizeMini)) + else if (widget == CocoaControl(Button_RadioButton, QStyleHelper::SizeMini)) offset.setY(2); - else if (widget == QCocoaWidget(QCocoaPopupButton, QStyleHelper::SizeSmall) - || widget == QCocoaWidget(QCocoaCheckBox, QStyleHelper::SizeLarge)) + else if (widget == CocoaControl(Button_PopupButton, QStyleHelper::SizeSmall) + || widget == CocoaControl(Button_CheckBox, QStyleHelper::SizeLarge)) offset.setY(1); - else if (widget == QCocoaWidget(QCocoaCheckBox, QStyleHelper::SizeSmall)) + else if (widget == CocoaControl(Button_CheckBox, QStyleHelper::SizeSmall)) offset.setX(-1); - else if (widget == QCocoaWidget(QCocoaCheckBox, QStyleHelper::SizeMini)) + else if (widget == CocoaControl(Button_CheckBox, QStyleHelper::SizeMini)) offset = QPoint(7, 5); - else if (widget == QCocoaWidget(QCocoaPopupButton, QStyleHelper::SizeMini)) + else if (widget == CocoaControl(Button_PopupButton, QStyleHelper::SizeMini)) offset = QPoint(2, -1); - else if (widget == QCocoaWidget(QCocoaPullDownButton, QStyleHelper::SizeLarge)) + else if (widget == CocoaControl(Button_PullDown, QStyleHelper::SizeLarge)) offset = isQWidget ? QPoint(3, -1) : QPoint(-1, -3); - else if (widget == QCocoaWidget(QCocoaPullDownButton, QStyleHelper::SizeSmall)) + else if (widget == CocoaControl(Button_PullDown, QStyleHelper::SizeSmall)) offset = QPoint(2, 1); - else if (widget == QCocoaWidget(QCocoaPullDownButton, QStyleHelper::SizeMini)) + else if (widget == CocoaControl(Button_PullDown, QStyleHelper::SizeMini)) offset = QPoint(5, 0); - else if (widget == QCocoaWidget(QCocoaComboBox, QStyleHelper::SizeLarge)) + else if (widget == CocoaControl(ComboBox, QStyleHelper::SizeLarge)) offset = QPoint(3, 0); QMacCGContext ctx(p); @@ -2162,7 +2162,7 @@ void QMacStylePrivate::drawColorlessButton(const CGRect &macRect, HIThemeButtonD if (!combo && !button && bdi->value == kThemeButtonOff) { pm = activePixmap; } else if ((combo && !editableCombo) || button) { - QCocoaWidget cw = cocoaWidgetFromHIThemeButtonKind(bdi->kind); + CocoaControl cw = cocoaControlFromHIThemeButtonKind(bdi->kind); NSButton *bc = (NSButton *)cocoaControl(cw); [bc highlight:pressed]; bc.enabled = bdi->state != kThemeStateUnavailable && bdi->state != kThemeStateUnavailableInactive; @@ -3211,7 +3211,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai if (groupBox->features & QStyleOptionFrame::Flat) { QCommonStyle::drawPrimitive(pe, groupBox, p, w); } else { - const auto cw = QCocoaWidget(QCocoaBox, QStyleHelper::SizeDefault); + const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Box, QStyleHelper::SizeDefault); auto *box = static_cast(d->cocoaControl(cw)); d->drawNSViewInRect(cw, box, groupBox->rect, p, w != nullptr, ^(CGContextRef ctx, const CGRect &rect) { CGContextTranslateCTM(ctx, 0, rect.origin.y + rect.size.height); @@ -3397,7 +3397,8 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai case PE_IndicatorBranch: { if (!(opt->state & State_Children)) break; - NSButtonCell *triangleCell = static_cast(d->cocoaCell(QCocoaWidget(QCocoaDisclosureButton, QStyleHelper::SizeLarge))); + const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Button_Disclosure, QStyleHelper::SizeLarge); + NSButtonCell *triangleCell = static_cast(d->cocoaCell(cw)); [triangleCell setState:(opt->state & State_Open) ? NSOnState : NSOffState]; bool viewHasFocus = (w && w->hasFocus()) || (opt->state & State_HasFocus); [triangleCell setBackgroundStyle:((opt->state & State_Selected) && viewHasFocus) ? NSBackgroundStyleDark : NSBackgroundStyleLight]; @@ -3884,8 +3885,8 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter } if (hasMenu && bdi.kind != kThemeBevelButton) { - QCocoaWidget cw = cocoaWidgetFromHIThemeButtonKind(bdi.kind); - cw.first = QCocoaPullDownButton; + auto cw = QMacStylePrivate::cocoaControlFromHIThemeButtonKind(bdi.kind); + cw.first = QMacStylePrivate::Button_PullDown; NSPopUpButton *pdb = (NSPopUpButton *)d->cocoaControl(cw); [pdb highlight:(bdi.state == kThemeStatePressed)]; pdb.enabled = bdi.state != kThemeStateUnavailable && bdi.state != kThemeStateUnavailableInactive; @@ -4451,7 +4452,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter const QProgressStyleAnimation *animation = qobject_cast(d->animation(opt->styleObject)); QIndeterminateProgressIndicator *ipi = nil; if (isIndeterminate || animation) - ipi = static_cast(d->cocoaControl({ QCocoaIndeterminateProgressIndicator, aquaSize })); + ipi = static_cast(d->cocoaControl({ QMacStylePrivate::ProgressIndicator_Indeterminate, aquaSize })); if (isIndeterminate) { // QIndeterminateProgressIndicator derives from NSProgressIndicator. We use a single // instance that we start animating as soon as one of the progress bars is indeterminate. @@ -4478,7 +4479,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter [ipi stopAnimation]; } - const QCocoaWidget cw = { QCocoaProgressIndicator, aquaSize }; + const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::ProgressIndicator_Determinate, aquaSize); auto *pi = static_cast(d->cocoaControl(cw)); d->drawNSViewInRect(cw, pi, rect, p, w != nullptr, ^(CGContextRef ctx, const CGRect &rect) { d->setupVerticalInvertedXform(ctx, reverse, vertical, rect); @@ -5265,7 +5266,8 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex d->setupNSGraphicsContext(cg, NO /* flipped */); - const QCocoaWidget cw(isHorizontal ? QCocoaHorizontalScroller : QCocoaVerticalScroller, cocoaSize); + const auto controlType = isHorizontal ? QMacStylePrivate::Scroller_Horizontal : QMacStylePrivate::Scroller_Vertical; + const auto cw = QMacStylePrivate::CocoaControl(controlType, cocoaSize); NSScroller *scroller = static_cast(d->cocoaControl(cw)); if (isTransient) { @@ -5347,8 +5349,9 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex case CC_Slider: if (const QStyleOptionSlider *sl = qstyleoption_cast(opt)) { const bool isHorizontal = sl->orientation == Qt::Horizontal; + const auto ct = isHorizontal ? QMacStylePrivate::Slider_Horizontal : QMacStylePrivate::Slider_Vertical; const auto cs = d->effectiveAquaSizeConstrain(opt, widget); - const auto cw = QCocoaWidget(isHorizontal ? QCocoaHorizontalSlider : QCocoaVerticalSlider, cs); + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); auto *slider = static_cast(d->cocoaControl(cw)); if (!setupSlider(slider, sl)) break; @@ -5483,7 +5486,8 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex d->setupNSGraphicsContext(cg, NO); const auto aquaSize = d->effectiveAquaSizeConstrain(opt, widget); - NSStepperCell *cell = static_cast(d->cocoaCell(QCocoaWidget(QCocoaStepper, aquaSize))); + const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Stepper, aquaSize); + NSStepperCell *cell = static_cast(d->cocoaCell(cw)); cell.enabled = (sb->state & State_Enabled); const CGRect newRect = [cell drawingRectForBounds:updown.toCGRect()]; @@ -5518,7 +5522,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex if (tds != kThemeStateInactive) QMacStylePrivate::drawCombobox(rect, bdi, p); else if (!widget && combo->editable) { - QCocoaWidget cw = cocoaWidgetFromHIThemeButtonKind(bdi.kind); + const auto cw = QMacStylePrivate::cocoaControlFromHIThemeButtonKind(bdi.kind); NSView *cb = d->cocoaControl(cw); QRect r = combo->rect.adjusted(3, 0, 0, 0); d->drawNSViewInRect(cw, cb, r, p, widget != 0); @@ -5822,8 +5826,9 @@ QStyle::SubControl QMacStyle::hitTestComplexControl(ComplexControl cc, const bool hasTicks = sl->tickPosition != QSlider::NoTicks; const bool isHorizontal = sl->orientation == Qt::Horizontal; + const auto ct = isHorizontal ? QMacStylePrivate::Slider_Horizontal : QMacStylePrivate::Slider_Vertical; const auto cs = d->effectiveAquaSizeConstrain(opt, widget); - const auto cw = QCocoaWidget(isHorizontal ? QCocoaHorizontalSlider : QCocoaVerticalSlider, cs); + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); auto *slider = static_cast(d->cocoaControl(cw)); if (!setupSlider(slider, sl)) break; @@ -5848,9 +5853,10 @@ QStyle::SubControl QMacStyle::hitTestComplexControl(ComplexControl cc, break; } - const auto controlSize = d->effectiveAquaSizeConstrain(opt, widget); const bool isHorizontal = sb->orientation == Qt::Horizontal; - const auto cw = QCocoaWidget(isHorizontal ? QCocoaHorizontalScroller : QCocoaVerticalScroller, controlSize); + const auto ct = isHorizontal ? QMacStylePrivate::Scroller_Horizontal : QMacStylePrivate::Scroller_Vertical; + const auto cs = d->effectiveAquaSizeConstrain(opt, widget); + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); auto *scroller = static_cast(d->cocoaControl(cw)); if (!setupScroller(scroller, sb)) { sc = SC_None; @@ -5956,8 +5962,9 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op // And nothing else since 10.7 if (part != NSScrollerNoPart) { - const auto controlSize = d->effectiveAquaSizeConstrain(opt, widget); - const auto cw = QCocoaWidget(isHorizontal ? QCocoaHorizontalScroller : QCocoaVerticalScroller, controlSize); + const auto ct = isHorizontal ? QMacStylePrivate::Scroller_Horizontal : QMacStylePrivate::Scroller_Vertical; + const auto cs = d->effectiveAquaSizeConstrain(opt, widget); + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); auto *scroller = static_cast(d->cocoaControl(cw)); if (setupScroller(scroller, sb)) ret = QRectF::fromCGRect([scroller rectForPart:part]).toRect(); @@ -5968,8 +5975,9 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op if (const QStyleOptionSlider *sl = qstyleoption_cast(opt)) { const bool hasTicks = sl->tickPosition != QSlider::NoTicks; const bool isHorizontal = sl->orientation == Qt::Horizontal; + const auto ct = isHorizontal ? QMacStylePrivate::Slider_Horizontal : QMacStylePrivate::Slider_Vertical; const auto cs = d->effectiveAquaSizeConstrain(opt, widget); - const auto cw = QCocoaWidget(isHorizontal ? QCocoaHorizontalSlider : QCocoaVerticalSlider, cs); + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); auto *slider = static_cast(d->cocoaControl(cw)); if (!setupSlider(slider, sl)) break; @@ -6230,7 +6238,8 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op Q_UNREACHABLE(); } - NSStepperCell *cell = static_cast(d->cocoaCell(QCocoaWidget(QCocoaStepper, aquaSize))); + const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Stepper, aquaSize); + NSStepperCell *cell = static_cast(d->cocoaCell(cw)); const CGRect outRect = [cell drawingRectForBounds:ret.toCGRect()]; ret = QRectF::fromCGRect(outRect).toRect(); diff --git a/src/plugins/styles/mac/qmacstyle_mac_p_p.h b/src/plugins/styles/mac/qmacstyle_mac_p_p.h index 528edfcda1..9c38831c0a 100644 --- a/src/plugins/styles/mac/qmacstyle_mac_p_p.h +++ b/src/plugins/styles/mac/qmacstyle_mac_p_p.h @@ -167,28 +167,6 @@ QT_BEGIN_NAMESPACE #define CT1(c) CT2(c, c) #define CT2(c1, c2) ((uint(c1) << 16) | uint(c2)) -enum QCocoaWidgetKind { - QCocoaBox, // QGroupBox - QCocoaCheckBox, - QCocoaComboBox, // Editable QComboBox - QCocoaDisclosureButton, // Disclosure triangle, like in QTreeView - QCocoaPopupButton, // Non-editable QComboBox - QCocoaProgressIndicator, - QCocoaIndeterminateProgressIndicator, - QCocoaPullDownButton, // QPushButton with menu - QCocoaPushButton, - QCocoaRadioButton, - QCocoaHorizontalScroller, - QCocoaVerticalScroller, - QCocoaHorizontalSlider, - QCocoaVerticalSlider, - QCocoaStepper // QSpinBox buttons -}; - -typedef QPair QCocoaWidget; - -typedef void (^QCocoaDrawRectBlock)(CGContextRef, const CGRect &); - #define SIZE(large, small, mini) \ (controlSize == QStyleHelper::SizeLarge ? (large) : controlSize == QStyleHelper::SizeSmall ? (small) : (mini)) @@ -207,6 +185,28 @@ class QMacStylePrivate : public QCommonStylePrivate { Q_DECLARE_PUBLIC(QMacStyle) public: + enum CocoaControlType { + Box, // QGroupBox + Button_CheckBox, + Button_Disclosure, // Disclosure triangle, like in QTreeView + Button_PopupButton, // Non-editable QComboBox + Button_PullDown, // QPushButton with menu + Button_PushButton, + Button_RadioButton, + ComboBox, // Editable QComboBox + ProgressIndicator_Determinate, + ProgressIndicator_Indeterminate, + Scroller_Horizontal, + Scroller_Vertical, + Slider_Horizontal, + Slider_Vertical, + Stepper // QSpinBox buttons + }; + + typedef QPair CocoaControl; + + typedef void (^DrawRectBlock)(CGContextRef, const CGRect &); + QMacStylePrivate(); ~QMacStylePrivate(); @@ -260,15 +260,17 @@ public: void setAutoDefaultButton(QObject *button) const; - NSView *cocoaControl(QCocoaWidget widget) const; - NSCell *cocoaCell(QCocoaWidget widget) const; + NSView *cocoaControl(CocoaControl widget) const; + NSCell *cocoaCell(CocoaControl widget) const; + + static CocoaControl cocoaControlFromHIThemeButtonKind(ThemeButtonKind kind); void setupNSGraphicsContext(CGContextRef cg, bool flipped) const; void restoreNSGraphicsContext(CGContextRef cg) const; void setupVerticalInvertedXform(CGContextRef cg, bool reverse, bool vertical, const CGRect &rect) const; - void drawNSViewInRect(QCocoaWidget widget, NSView *view, const QRect &rect, QPainter *p, bool isQWidget = true, QCocoaDrawRectBlock drawRectBlock = nil) const; + void drawNSViewInRect(CocoaControl widget, NSView *view, const QRect &rect, QPainter *p, bool isQWidget = true, DrawRectBlock drawRectBlock = nil) const; void resolveCurrentNSView(QWindow *window); void drawFocusRing(QPainter *p, const QRect &targetRect, int hMargin, int vMargin, qreal radius = 0) const; @@ -284,8 +286,8 @@ public: mutable QPointer focusWidget; QT_MANGLE_NAMESPACE(NotificationReceiver) *receiver; NSView *backingStoreNSView; - mutable QHash cocoaControls; - mutable QHash cocoaCells; + mutable QHash cocoaControls; + mutable QHash cocoaCells; QFont smallSystemFont; QFont miniSystemFont; -- cgit v1.2.3 From dbc1c790431aab1d45ca8c77886dbd6438c139de Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 7 Nov 2017 14:05:21 +0700 Subject: QMacStyle: Remove unused code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I6e71871b19ce12daddd4cfbbe7c1d9beede13a9b Reviewed-by: Morten Johan Sørvig --- src/plugins/styles/mac/qmacstyle_mac.mm | 66 ------------------------------ src/plugins/styles/mac/qmacstyle_mac_p.h | 4 -- src/plugins/styles/mac/qmacstyle_mac_p_p.h | 4 -- 3 files changed, 74 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 9c5ede6d47..3ae13c3282 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -569,7 +569,6 @@ static inline ThemeTabDirection getTabDirection(QTabBar::Shape shape) case QTabBar::TriangularSouth: ttd = kThemeTabSouth; break; - default: // Added to remove the warning, since all values are taken care of, really! case QTabBar::RoundedNorth: case QTabBar::TriangularNorth: ttd = kThemeTabNorth; @@ -622,47 +621,6 @@ static QString qt_mac_removeMnemonics(const QString &original) return returnText; } -OSStatus qt_mac_shape2QRegionHelper(int inMessage, HIShapeRef, const CGRect *inRect, void *inRefcon) -{ - QRegion *region = static_cast(inRefcon); - if (!region) - return paramErr; - - switch (inMessage) { - case kHIShapeEnumerateRect: - *region += QRect(inRect->origin.x, inRect->origin.y, - inRect->size.width, inRect->size.height); - break; - case kHIShapeEnumerateInit: - // Assume the region is already setup correctly - case kHIShapeEnumerateTerminate: - default: - break; - } - return noErr; -} - -/*! - \internal - Create's a mutable shape, it's the caller's responsibility to release. - WARNING: this function clamps the coordinates to SHRT_MIN/MAX on 10.4 and below. -*/ -HIMutableShapeRef qt_mac_toHIMutableShape(const QRegion ®ion) -{ - HIMutableShapeRef shape = HIShapeCreateMutable(); - if (region.rectCount() < 2 ) { - QRect qtRect = region.boundingRect(); - CGRect cgRect = CGRectMake(qtRect.x(), qtRect.y(), qtRect.width(), qtRect.height()); - HIShapeUnionWithRect(shape, &cgRect); - } else { - for (const QRect &qtRect : region) { - CGRect cgRect = CGRectMake(qtRect.x(), qtRect.y(), qtRect.width(), qtRect.height()); - HIShapeUnionWithRect(shape, &cgRect); - } - } - return shape; -} - bool qt_macWindowIsTextured(const QWidget *window) { if (QWindow *w = window->windowHandle()) @@ -1518,18 +1476,6 @@ void QMacStylePrivate::initHIThemePushButton(const QStyleOptionButton *btn, } } -#if QT_CONFIG(pushbutton) -bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option) -{ - QMacStyle *macStyle = qobject_cast(pushButton->style()); - if (!macStyle) - return false; - HIThemeButtonDrawInfo bdi; - macStyle->d_func()->initHIThemePushButton(option, pushButton, kThemeStateActive, &bdi); - return bdi.kind == kThemeBevelButton; -} -#endif - /** Creates a HIThemeButtonDrawInfo structure that specifies the correct button kind and other details to use for drawing the given combobox. Which button @@ -6817,16 +6763,4 @@ int QMacStyle::layoutSpacing(QSizePolicy::ControlType control1, return_SIZE(10, 8, 6); // guess } -/* -FontHash::FontHash() -{ - QHash::operator=(QGuiApplicationPrivate::platformIntegration()->fontDatabase()->defaultFonts()); -} - -Q_GLOBAL_STATIC(FontHash, app_fonts) -FontHash *qt_app_fonts_hash() -{ - return app_fonts(); -} -*/ QT_END_NAMESPACE diff --git a/src/plugins/styles/mac/qmacstyle_mac_p.h b/src/plugins/styles/mac/qmacstyle_mac_p.h index 6011baeea2..d6874001d3 100644 --- a/src/plugins/styles/mac/qmacstyle_mac_p.h +++ b/src/plugins/styles/mac/qmacstyle_mac_p.h @@ -117,10 +117,6 @@ public: private: Q_DISABLE_COPY(QMacStyle) Q_DECLARE_PRIVATE(QMacStyle) - -#if QT_CONFIG(pushbutton) - friend bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option); -#endif }; QT_END_NAMESPACE diff --git a/src/plugins/styles/mac/qmacstyle_mac_p_p.h b/src/plugins/styles/mac/qmacstyle_mac_p_p.h index 9c38831c0a..b893e851fd 100644 --- a/src/plugins/styles/mac/qmacstyle_mac_p_p.h +++ b/src/plugins/styles/mac/qmacstyle_mac_p_p.h @@ -177,10 +177,6 @@ QT_BEGIN_NAMESPACE return sizes[controlSize]; \ } while (false) -#if QT_CONFIG(pushbutton) -bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option); -#endif - class QMacStylePrivate : public QCommonStylePrivate { Q_DECLARE_PUBLIC(QMacStyle) -- cgit v1.2.3 From 9af0601fd91d9a0fa6266e978c8b742a38140b7f Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 7 Nov 2017 14:15:39 +0700 Subject: QMacStyle: Replace HITheme info structs with QMSP::CocoaControl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is not yet a full replacement, but a scaffolding stage until we can remove all traces of HITheme info structs. Change-Id: I10eb6a60662c6b102bc687e335d0d1bedd6a4a12 Reviewed-by: Morten Johan Sørvig --- src/plugins/styles/mac/qmacstyle_mac.mm | 164 ++++++++++++++++------------- src/plugins/styles/mac/qmacstyle_mac_p_p.h | 6 +- 2 files changed, 92 insertions(+), 78 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 3ae13c3282..a8cb361969 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -1483,6 +1483,7 @@ void QMacStylePrivate::initHIThemePushButton(const QStyleOptionButton *btn, explicit user style settings, etc. */ void QMacStylePrivate::initComboboxBdi(const QStyleOptionComboBox *combo, HIThemeButtonDrawInfo *bdi, + CocoaControl *cw, const QWidget *widget, const ThemeDrawState &tds) const { bdi->version = qt_mac_hitheme_version; @@ -1496,6 +1497,8 @@ void QMacStylePrivate::initComboboxBdi(const QStyleOptionComboBox *combo, HIThem bdi->state = tds; QStyleHelper::WidgetSizePolicy aSize = aquaSizeConstrain(combo, widget); + cw->first = combo->editable ? ComboBox : Button_PopupButton; + cw->second = aSize; switch (aSize) { case QStyleHelper::SizeMini: bdi->kind = combo->editable ? ThemeButtonKind(kThemeComboBoxMini) @@ -1525,21 +1528,29 @@ void QMacStylePrivate::initComboboxBdi(const QStyleOptionComboBox *combo, HIThem // them forever). So anyway, the height threshold should be smaller // in this case, or the style gets confused when it needs to render // or return any subcontrol size of the poor thing. - if (h < 9) + if (h < 9) { bdi->kind = kThemeComboBoxMini; - else if (h < 22) + cw->second = QStyleHelper::SizeMini; + } else if (h < 22) { bdi->kind = kThemeComboBoxSmall; - else + cw->second = QStyleHelper::SizeSmall; + } else { bdi->kind = kThemeComboBox; + cw->second = QStyleHelper::SizeLarge; + } } else #endif { - if (h < 21) + if (h < 21) { bdi->kind = kThemeComboBoxMini; - else if (h < 26) + cw->second = QStyleHelper::SizeMini; + } else if (h < 26) { bdi->kind = kThemeComboBoxSmall; - else + cw->second = QStyleHelper::SizeSmall; + } else { bdi->kind = kThemeComboBox; + cw->second = QStyleHelper::SizeLarge; + } } } else { // Even if we specify that we want the kThemePopupButton, Carbon @@ -1547,12 +1558,16 @@ void QMacStylePrivate::initComboboxBdi(const QStyleOptionComboBox *combo, HIThem // do the same size check explicit to have the size of the inner // text field be correct. Therefore, do this even if the user specifies // the use of LargeButtons explicit. - if (h < 21) + if (h < 21) { bdi->kind = kThemePopupButtonMini; - else if (h < 26) + cw->second = QStyleHelper::SizeMini; + } else if (h < 26) { bdi->kind = kThemePopupButtonSmall; - else + cw->second = QStyleHelper::SizeSmall; + } else { bdi->kind = kThemePopupButton; + cw->second = QStyleHelper::SizeLarge; + } } break; } @@ -1562,51 +1577,54 @@ void QMacStylePrivate::initComboboxBdi(const QStyleOptionComboBox *combo, HIThem Carbon draws comboboxes (and other views) outside the rect given as argument. Use this function to obtain the corresponding inner rect for drawing the same combobox so that it stays inside the given outerBounds. */ -CGRect QMacStylePrivate::comboboxInnerBounds(const CGRect &outerBounds, int buttonKind) +CGRect QMacStylePrivate::comboboxInnerBounds(const CGRect &outerBounds, const CocoaControl &cocoaWidget) { CGRect innerBounds = outerBounds; // Carbon draw parts of the view outside the rect. // So make the rect a bit smaller to compensate // (I wish HIThemeGetButtonBackgroundBounds worked) - switch (buttonKind){ - case kThemePopupButton: - innerBounds.origin.x += 2; - innerBounds.origin.y += 2; - innerBounds.size.width -= 5; - innerBounds.size.height -= 6; - break; - case kThemePopupButtonSmall: - innerBounds.origin.x += 3; - innerBounds.origin.y += 3; - innerBounds.size.width -= 6; - innerBounds.size.height -= 7; - break; - case kThemePopupButtonMini: - innerBounds.origin.x += 2; - innerBounds.origin.y += 2; - innerBounds.size.width -= 5; - innerBounds.size.height -= 6; - break; - case kThemeComboBox: - innerBounds.origin.x += 3; - innerBounds.origin.y += 2; - innerBounds.size.width -= 6; - innerBounds.size.height -= 8; - break; - case kThemeComboBoxSmall: - innerBounds.origin.x += 3; - innerBounds.origin.y += 3; - innerBounds.size.width -= 7; - innerBounds.size.height -= 8; - break; - case kThemeComboBoxMini: - innerBounds.origin.x += 3; - innerBounds.origin.y += 3; - innerBounds.size.width -= 4; - innerBounds.size.height -= 8; - break; - default: - break; + if (cocoaWidget.first == Button_PopupButton) { + switch (cocoaWidget.second) { + case QStyleHelper::SizeSmall: + innerBounds.origin.x += 3; + innerBounds.origin.y += 3; + innerBounds.size.width -= 6; + innerBounds.size.height -= 7; + break; + case QStyleHelper::SizeMini: + innerBounds.origin.x += 2; + innerBounds.origin.y += 2; + innerBounds.size.width -= 5; + innerBounds.size.height -= 6; + break; + case QStyleHelper::SizeLarge: + case QStyleHelper::SizeDefault: + innerBounds.origin.x += 2; + innerBounds.origin.y += 2; + innerBounds.size.width -= 5; + innerBounds.size.height -= 6; + } + } else if (cocoaWidget.first == ComboBox) { + switch (cocoaWidget.second) { + case QStyleHelper::SizeSmall: + innerBounds.origin.x += 3; + innerBounds.origin.y += 3; + innerBounds.size.width -= 7; + innerBounds.size.height -= 8; + break; + case QStyleHelper::SizeMini: + innerBounds.origin.x += 3; + innerBounds.origin.y += 3; + innerBounds.size.width -= 4; + innerBounds.size.height -= 8; + break; + case QStyleHelper::SizeLarge: + case QStyleHelper::SizeDefault: + innerBounds.origin.x += 3; + innerBounds.origin.y += 2; + innerBounds.size.width -= 6; + innerBounds.size.height -= 8; + } } return innerBounds; @@ -1650,11 +1668,11 @@ QRect QMacStylePrivate::comboboxEditBounds(const QRect &outerBounds, const HIThe create it manually by drawing a small Carbon combo onto a pixmap (use pixmap cache), chop it up, and copy it back onto the widget. Othervise, draw the combobox supplied by Carbon directly. */ -void QMacStylePrivate::drawCombobox(const CGRect &outerBounds, const HIThemeButtonDrawInfo &bdi, QPainter *p) +void QMacStylePrivate::drawCombobox(const CGRect &outerBounds, const HIThemeButtonDrawInfo &bdi, const CocoaControl &cw, QPainter *p) { if (!(bdi.kind == kThemeComboBox && outerBounds.size.height > 28)){ // We have an unscaled combobox, or popup-button; use Carbon directly. - const CGRect innerBounds = QMacStylePrivate::comboboxInnerBounds(outerBounds, bdi.kind); + const CGRect innerBounds = QMacStylePrivate::comboboxInnerBounds(outerBounds, cw); HIThemeDrawButton(&innerBounds, &bdi, QMacCGContext(p), kHIThemeOrientationNormal, 0); } else { QPixmap buffer; @@ -2045,7 +2063,7 @@ void QMacStylePrivate::resolveCurrentNSView(QWindow *window) backingStoreNSView = window ? (NSView *)window->winId() : nil; } -void QMacStylePrivate::drawColorlessButton(const CGRect &macRect, HIThemeButtonDrawInfo *bdi, +void QMacStylePrivate::drawColorlessButton(const CGRect &macRect, HIThemeButtonDrawInfo *bdi, const CocoaControl &cw, QPainter *p, const QStyleOption *opt) const { int xoff = 0, @@ -2093,7 +2111,7 @@ void QMacStylePrivate::drawColorlessButton(const CGRect &macRect, HIThemeButtonD // Carbon combos don't scale. Therefore we draw it // ourselves, if a scaled version is needed. QPainter tmpPainter(&activePixmap); - QMacStylePrivate::drawCombobox(macRect, *bdi, &tmpPainter); + QMacStylePrivate::drawCombobox(macRect, *bdi, cw, &tmpPainter); } else { QMacCGContext cg(&activePixmap); CGRect newRect = CGRectMake(xoff, yoff, macRect.size.width, macRect.size.height); @@ -3332,10 +3350,11 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai else bdi.value = kThemeButtonOff; CGRect macRect = opt->rect.toCGRect(); + const QMacStylePrivate::CocoaControl cw = QMacStylePrivate::cocoaControlFromHIThemeButtonKind(bdi.kind); if (!drawColorless) HIThemeDrawButton(&macRect, &bdi, cg, kHIThemeOrientationNormal, 0); else - d->drawColorlessButton(macRect, &bdi, p, opt); + d->drawColorlessButton(macRect, &bdi, cw, p, opt); break; } case PE_FrameFocusRect: // Use the our own focus widget stuff. @@ -3830,9 +3849,10 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter newRect.size.width -= QMacStylePrivate::PushButtonRightOffset - 4; } - if (hasMenu && bdi.kind != kThemeBevelButton) { - auto cw = QMacStylePrivate::cocoaControlFromHIThemeButtonKind(bdi.kind); + QMacStylePrivate::CocoaControl cw = QMacStylePrivate::cocoaControlFromHIThemeButtonKind(bdi.kind); + if (hasMenu) cw.first = QMacStylePrivate::Button_PullDown; + if (hasMenu && bdi.kind != kThemeBevelButton) { NSPopUpButton *pdb = (NSPopUpButton *)d->cocoaControl(cw); [pdb highlight:(bdi.state == kThemeStatePressed)]; pdb.enabled = bdi.state != kThemeStateUnavailable && bdi.state != kThemeStateUnavailableInactive; @@ -3840,7 +3860,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter rect.adjust(0, 0, cw.second == QStyleHelper::SizeSmall ? -4 : cw.second == QStyleHelper::SizeMini ? -9 : -6, 0); d->drawNSViewInRect(cw, pdb, rect, p, w != 0); } else if (hasMenu && bdi.state == kThemeStatePressed) - d->drawColorlessButton(newRect, &bdi, p, opt); + d->drawColorlessButton(newRect, &bdi, cw, p, opt); else HIThemeDrawButton(&newRect, &bdi, cg, kHIThemeOrientationNormal, 0); @@ -5461,19 +5481,20 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex case CC_ComboBox: if (const QStyleOptionComboBox *combo = qstyleoption_cast(opt)){ HIThemeButtonDrawInfo bdi; - d->initComboboxBdi(combo, &bdi, widget, tds); + QMacStylePrivate::CocoaControl cw; + d->initComboboxBdi(combo, &bdi, &cw, widget, tds); CGRect rect = combo->rect.toCGRect(); if (combo->editable) rect.origin.y += tds == kThemeStateInactive ? 1 : 2; if (tds != kThemeStateInactive) - QMacStylePrivate::drawCombobox(rect, bdi, p); + QMacStylePrivate::drawCombobox(rect, bdi, cw, p); else if (!widget && combo->editable) { const auto cw = QMacStylePrivate::cocoaControlFromHIThemeButtonKind(bdi.kind); NSView *cb = d->cocoaControl(cw); QRect r = combo->rect.adjusted(3, 0, 0, 0); d->drawNSViewInRect(cw, cb, r, p, widget != 0); } else - d->drawColorlessButton(rect, &bdi, p, opt); + d->drawColorlessButton(rect, &bdi, cw, p, opt); } break; case CC_TitleBar: @@ -6017,7 +6038,8 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op case CC_ComboBox: if (const QStyleOptionComboBox *combo = qstyleoption_cast(opt)) { HIThemeButtonDrawInfo bdi; - d->initComboboxBdi(combo, &bdi, widget, d->getDrawState(opt->state)); + QMacStylePrivate::CocoaControl cw; + d->initComboboxBdi(combo, &bdi, &cw, widget, d->getDrawState(opt->state)); switch (sc) { case SC_ComboBoxEditField:{ @@ -6032,7 +6054,7 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op break; } case SC_ComboBoxListBoxPopup:{ if (combo->editable) { - const CGRect inner = QMacStylePrivate::comboboxInnerBounds(combo->rect.toCGRect(), bdi.kind); + const CGRect inner = QMacStylePrivate::comboboxInnerBounds(combo->rect.toCGRect(), cw); QRect editRect = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi); const int comboTop = combo->rect.top(); ret = QRect(qRound(inner.origin.x), @@ -6509,20 +6531,10 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, // We compensate for this by adding some extra space here to make room for the frame when drawing: if (const QStyleOptionComboBox *combo = qstyleoption_cast(opt)){ const auto widgetSize = d->aquaSizeConstrain(opt, widget); - int bkind = 0; - switch (widgetSize) { - default: - case QStyleHelper::SizeLarge: - bkind = combo->editable ? kThemeComboBox : kThemePopupButton; - break; - case QStyleHelper::SizeSmall: - bkind = combo->editable ? int(kThemeComboBoxSmall) : int(kThemePopupButtonSmall); - break; - case QStyleHelper::SizeMini: - bkind = combo->editable ? kThemeComboBoxMini : kThemePopupButtonMini; - break; - } - const CGRect diffRect = QMacStylePrivate::comboboxInnerBounds(CGRectZero, bkind); + QMacStylePrivate::CocoaControl cw; + cw.first = combo->editable ? QMacStylePrivate::ComboBox : QMacStylePrivate::Button_PopupButton; + cw.second = widgetSize; + const CGRect diffRect = QMacStylePrivate::comboboxInnerBounds(CGRectZero, cw); sz.rwidth() -= qRound(diffRect.size.width); sz.rheight() -= qRound(diffRect.size.height); } else if (ct == CT_PushButton || ct == CT_ToolButton){ diff --git a/src/plugins/styles/mac/qmacstyle_mac_p_p.h b/src/plugins/styles/mac/qmacstyle_mac_p_p.h index b893e851fd..01b0a15427 100644 --- a/src/plugins/styles/mac/qmacstyle_mac_p_p.h +++ b/src/plugins/styles/mac/qmacstyle_mac_p_p.h @@ -231,6 +231,7 @@ public: // Utility functions void drawColorlessButton(const CGRect &macRect, HIThemeButtonDrawInfo *bdi, + const CocoaControl &cw, QPainter *p, const QStyleOption *opt) const; QSize pushButtonSizeFromContents(const QStyleOptionButton *btn) const; @@ -239,13 +240,14 @@ public: const HIThemeButtonDrawInfo *bdi) const; void initComboboxBdi(const QStyleOptionComboBox *combo, HIThemeButtonDrawInfo *bdi, + CocoaControl *cw, const QWidget *widget, const ThemeDrawState &tds) const; - static CGRect comboboxInnerBounds(const CGRect &outerBounds, int buttonKind); + static CGRect comboboxInnerBounds(const CGRect &outerBounds, const CocoaControl &cocoaWidget); static QRect comboboxEditBounds(const QRect &outerBounds, const HIThemeButtonDrawInfo &bdi); - static void drawCombobox(const CGRect &outerBounds, const HIThemeButtonDrawInfo &bdi, QPainter *p); + static void drawCombobox(const CGRect &outerBounds, const HIThemeButtonDrawInfo &bdi, const CocoaControl &cw, QPainter *p); static void drawTableHeader(const CGRect &outerBounds, bool drawTopBorder, bool drawLeftBorder, const HIThemeButtonDrawInfo &bdi, QPainter *p); bool contentFitsInPushButton(const QStyleOptionButton *btn, HIThemeButtonDrawInfo *bdi, -- cgit v1.2.3 From 1939cb02104d8e5ca0e4169e18b8e1f400090921 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 7 Nov 2017 16:37:12 +0700 Subject: QMacStyle: Make backingStoreNSView mutable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even thought the resolve function is effectively not const, it's more straightforward to call. Change-Id: I7c881183862c3c0b326daf001b2f9e569153ee76 Reviewed-by: Morten Johan Sørvig --- src/plugins/styles/mac/qmacstyle_mac.mm | 8 ++++---- src/plugins/styles/mac/qmacstyle_mac_p_p.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index a8cb361969..c7f573cc08 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -2058,7 +2058,7 @@ void QMacStylePrivate::drawNSViewInRect(CocoaControl widget, NSView *view, const restoreNSGraphicsContext(ctx); } -void QMacStylePrivate::resolveCurrentNSView(QWindow *window) +void QMacStylePrivate::resolveCurrentNSView(QWindow *window) const { backingStoreNSView = window ? (NSView *)window->winId() : nil; } @@ -3095,7 +3095,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai QMacCGContext cg(p); QWindow *window = w && w->window() ? w->window()->windowHandle() : QStyleHelper::styleObjectWindow(opt->styleObject); - const_cast(d)->resolveCurrentNSView(window); + d->resolveCurrentNSView(window); switch (pe) { case PE_IndicatorArrowUp: case PE_IndicatorArrowDown: @@ -3593,7 +3593,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter QMacCGContext cg(p); QWindow *window = w && w->window() ? w->window()->windowHandle() : QStyleHelper::styleObjectWindow(opt->styleObject); - const_cast(d)->resolveCurrentNSView(window); + d->resolveCurrentNSView(window); switch (ce) { case CE_HeaderSection: if (const QStyleOptionHeader *header = qstyleoption_cast(opt)) { @@ -5126,7 +5126,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex QMacCGContext cg(p); QWindow *window = widget && widget->window() ? widget->window()->windowHandle() : QStyleHelper::styleObjectWindow(opt->styleObject); - const_cast(d)->resolveCurrentNSView(window); + d->resolveCurrentNSView(window); switch (cc) { case CC_ScrollBar: if (const QStyleOptionSlider *sb = qstyleoption_cast(opt)) { diff --git a/src/plugins/styles/mac/qmacstyle_mac_p_p.h b/src/plugins/styles/mac/qmacstyle_mac_p_p.h index 01b0a15427..045753989f 100644 --- a/src/plugins/styles/mac/qmacstyle_mac_p_p.h +++ b/src/plugins/styles/mac/qmacstyle_mac_p_p.h @@ -269,7 +269,7 @@ public: void setupVerticalInvertedXform(CGContextRef cg, bool reverse, bool vertical, const CGRect &rect) const; void drawNSViewInRect(CocoaControl widget, NSView *view, const QRect &rect, QPainter *p, bool isQWidget = true, DrawRectBlock drawRectBlock = nil) const; - void resolveCurrentNSView(QWindow *window); + void resolveCurrentNSView(QWindow *window) const; void drawFocusRing(QPainter *p, const QRect &targetRect, int hMargin, int vMargin, qreal radius = 0) const; @@ -283,7 +283,7 @@ public: mutable QPointer focusWidget; QT_MANGLE_NAMESPACE(NotificationReceiver) *receiver; - NSView *backingStoreNSView; + mutable NSView *backingStoreNSView; mutable QHash cocoaControls; mutable QHash cocoaCells; -- cgit v1.2.3 From 67e3d192398ccf06d4411acc86df7748b0de98a5 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 9 Nov 2017 13:21:23 +0700 Subject: QMacStyle: Render tool button even when a11y is missing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tool buttons were being skipped a couple cases (CE_ToolButtonLabel and CC_ToolButton) when accessibility was disabled. Although unlikely anyone would disable accessibility on macOS, we fall back to the non- toolbar rendering if that were to be the case. Change-Id: Ie8ee11475efbe4b418c34842317bafeba80c3c57 Reviewed-by: Morten Johan Sørvig --- src/plugins/styles/mac/qmacstyle_mac.mm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index c7f573cc08..1246f64a7d 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -3786,12 +3786,11 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter } else { QCommonStyle::drawControl(ce, &myTb, p, w); } - } else { + } else +#endif // QT_NO_ACCESSIBILITY + { QCommonStyle::drawControl(ce, &myTb, p, w); } -#else - Q_UNUSED(tb) -#endif } break; case CE_ToolBoxTabShape: @@ -5674,7 +5673,9 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex p->fillPath(path, brush); } proxy()->drawControl(CE_ToolButtonLabel, opt, p, widget); - } else { + } else +#endif // QT_NO_ACCESSIBILITY + { ThemeButtonKind bkind = kThemeBevelButton; switch (d->aquaSizeConstrain(opt, widget)) { case QStyleHelper::SizeDefault: @@ -5757,7 +5758,6 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex label.rect = buttonRect.adjusted(fw, fw, -fw, -fw); proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget); } -#endif } break; #if QT_CONFIG(dial) -- cgit v1.2.3 From c1780b932268ff070387de80a617c9763263a9f0 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 9 Nov 2017 21:41:24 +0800 Subject: QMacStyle: De-HITheme item views headers and a couple arrows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This one is all manual. The arrows were manual before and the header sections are now plain rectangles. Removes one usage of HIThemeDrawButton and related logic together with a cached pixmap and its rendering. Still broken in some places, but not worse than before. In particular, sunken or selected header sections will not render the left hand side section separator properly. Look can be improved in the header label with different shades for the selected or current rows/columns. Change-Id: I6b1c1f529909341bbf72e82e5a3fc61905c75fa8 Reviewed-by: Morten Johan Sørvig --- src/plugins/styles/mac/qmacstyle_mac.mm | 190 +++++++++-------------------- src/plugins/styles/mac/qmacstyle_mac_p_p.h | 2 - 2 files changed, 57 insertions(+), 135 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 1246f64a7d..c6ae7c1b79 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -311,6 +311,9 @@ static const QColor tabBarCloseButtonCrossSelected(115, 115, 115); static const int closeButtonSize = 14; static const qreal closeButtonCornerRadius = 2.0; +static const int headerSectionArrowHeight = 6; +static const int headerSectionSeparatorInset = 2; + #if QT_CONFIG(tabbar) static bool isVerticalTabs(const QTabBar::Shape shape) { return (shape == QTabBar::RoundedEast @@ -1715,69 +1718,6 @@ void QMacStylePrivate::drawCombobox(const CGRect &outerBounds, const HIThemeButt } } -/** - Carbon tableheaders don't scale (sight). So create it manually by drawing a small Carbon header - onto a pixmap (use pixmap cache), chop it up, and copy it back onto the widget. -*/ -void QMacStylePrivate::drawTableHeader(const CGRect &outerBounds, - bool drawTopBorder, bool drawLeftBorder, const HIThemeButtonDrawInfo &bdi, QPainter *p) -{ - static int headerHeight = qt_mac_aqua_get_metric(ListHeaderHeight); - - QPixmap buffer; - QString key = QString(QLatin1String("$qt_tableh%1-%2-%3")).arg(int(bdi.state)).arg(int(bdi.adornment)).arg(int(bdi.value)); - if (!QPixmapCache::find(key, buffer)) { - CGRect headerNormalRect = {{0., 0.}, {16., CGFloat(headerHeight)}}; - buffer = QPixmap(headerNormalRect.size.width, headerNormalRect.size.height); - buffer.fill(Qt::transparent); - QPainter buffPainter(&buffer); - HIThemeDrawButton(&headerNormalRect, &bdi, QMacCGContext(&buffPainter), kHIThemeOrientationNormal, 0); - buffPainter.end(); - QPixmapCache::insert(key, buffer); - } - const int buttonw = qRound(outerBounds.size.width); - const int buttonh = qRound(outerBounds.size.height); - const int framew = 1; - const int frameh_n = 4; - const int frameh_s = 3; - const int transh = buffer.height() - frameh_n - frameh_s; - int center = buttonh - frameh_s - int(transh / 2.0f) + 1; // Align bottom; - - int skipTopBorder = 0; - if (!drawTopBorder) - skipTopBorder = 1; - - p->translate(outerBounds.origin.x, outerBounds.origin.y); - - p->drawPixmap(QRect(QRect(0, -skipTopBorder, buttonw - framew , frameh_n)), buffer, QRect(framew, 0, 1, frameh_n)); - p->drawPixmap(QRect(0, buttonh - frameh_s, buttonw - framew, frameh_s), buffer, QRect(framew, buffer.height() - frameh_s, 1, frameh_s)); - // Draw upper and lower center blocks - p->drawPixmap(QRect(0, frameh_n - skipTopBorder, buttonw - framew, center - frameh_n + skipTopBorder), buffer, QRect(framew, frameh_n, 1, 1)); - p->drawPixmap(QRect(0, center, buttonw - framew, buttonh - center - frameh_s), buffer, QRect(framew, buffer.height() - frameh_s, 1, 1)); - // Draw right center block borders - p->drawPixmap(QRect(buttonw - framew, frameh_n - skipTopBorder, framew, center - frameh_n), buffer, QRect(buffer.width() - framew, frameh_n, framew, 1)); - p->drawPixmap(QRect(buttonw - framew, center, framew, buttonh - center - 1), buffer, QRect(buffer.width() - framew, buffer.height() - frameh_s, framew, 1)); - // Draw right corners - p->drawPixmap(QRect(buttonw - framew, -skipTopBorder, framew, frameh_n), buffer, QRect(buffer.width() - framew, 0, framew, frameh_n)); - p->drawPixmap(QRect(buttonw - framew, buttonh - frameh_s, framew, frameh_s), buffer, QRect(buffer.width() - framew, buffer.height() - frameh_s, framew, frameh_s)); - // Draw center transition block - p->drawPixmap(QRect(0, center - qRound(transh / 2.0f), buttonw - framew, buffer.height() - frameh_n - frameh_s), buffer, QRect(framew, frameh_n + 1, 1, transh)); - // Draw right center transition block border - p->drawPixmap(QRect(buttonw - framew, center - qRound(transh / 2.0f), framew, buffer.height() - frameh_n - frameh_s), buffer, QRect(buffer.width() - framew, frameh_n + 1, framew, transh)); - if (drawLeftBorder){ - // Draw left center block borders - p->drawPixmap(QRect(0, frameh_n - skipTopBorder, framew, center - frameh_n + skipTopBorder), buffer, QRect(0, frameh_n, framew, 1)); - p->drawPixmap(QRect(0, center, framew, buttonh - center - 1), buffer, QRect(0, buffer.height() - frameh_s, framew, 1)); - // Draw left corners - p->drawPixmap(QRect(0, -skipTopBorder, framew, frameh_n), buffer, QRect(0, 0, framew, frameh_n)); - p->drawPixmap(QRect(0, buttonh - frameh_s, framew, frameh_s), buffer, QRect(0, buffer.height() - frameh_s, framew, frameh_s)); - // Draw left center transition block border - p->drawPixmap(QRect(0, center - qRound(transh / 2.0f), framew, buffer.height() - frameh_n - frameh_s), buffer, QRect(0, frameh_n + 1, framew, transh)); - } - - p->translate(-outerBounds.origin.x, -outerBounds.origin.y); -} - QMacStylePrivate::QMacStylePrivate() : backingStoreNSView(nil) { @@ -3103,7 +3043,17 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai case PE_IndicatorArrowLeft: { p->save(); p->setRenderHint(QPainter::Antialiasing); - int xOffset = opt->direction == Qt::LeftToRight ? 2 : -1; + const int xOffset = 1; // FIXME: opt->direction == Qt::LeftToRight ? 2 : -1; + qreal halfSize = 0.5 * qMin(opt->rect.width(), opt->rect.height()); + const qreal penWidth = qMax(halfSize / 3.0, 1.25); +#if QT_CONFIG(toolbutton) + if (const QToolButton *tb = qobject_cast(w)) { + // When stroking the arrow, make sure it fits in the tool button + if (tb->arrowType() != Qt::NoArrow) + halfSize -= penWidth; + } +#endif + QMatrix matrix; matrix.translate(opt->rect.center().x() + xOffset, opt->rect.center().y() + 2); QPainterPath path; @@ -3121,13 +3071,15 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai matrix.rotate(-90); break; } - path.moveTo(0, 5); - path.lineTo(-4, -3); - path.lineTo(4, -3); p->setMatrix(matrix); - p->setPen(Qt::NoPen); - p->setBrush(QColor(0, 0, 0, 135)); - p->drawPath(path); + + path.moveTo(-halfSize, -halfSize * 0.5); + path.lineTo(0.0, halfSize * 0.5); + path.lineTo(halfSize, -halfSize * 0.5); + + const QPen arrowPen(opt->palette.text(), penWidth, + Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); + p->strokePath(path, arrowPen); p->restore(); break; } #if QT_CONFIG(tabbar) @@ -3597,66 +3549,11 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter switch (ce) { case CE_HeaderSection: if (const QStyleOptionHeader *header = qstyleoption_cast(opt)) { - HIThemeButtonDrawInfo bdi; - bdi.version = qt_mac_hitheme_version; State flags = header->state; QRect ir = header->rect; - bdi.kind = kThemeListHeaderButton; - bdi.adornment = kThemeAdornmentNone; - bdi.state = kThemeStateActive; - if (flags & State_On) - bdi.value = kThemeButtonOn; - else - bdi.value = kThemeButtonOff; - - if (header->orientation == Qt::Horizontal){ - switch (header->position) { - case QStyleOptionHeader::Beginning: - ir.adjust(-1, -1, 0, 0); - break; - case QStyleOptionHeader::Middle: - ir.adjust(-1, -1, 0, 0); - break; - case QStyleOptionHeader::OnlyOneSection: - case QStyleOptionHeader::End: - ir.adjust(-1, -1, 1, 0); - break; - default: - break; - } - - if (header->position != QStyleOptionHeader::Beginning - && header->position != QStyleOptionHeader::OnlyOneSection) { - bdi.adornment = header->direction == Qt::LeftToRight - ? kThemeAdornmentHeaderButtonLeftNeighborSelected - : kThemeAdornmentHeaderButtonRightNeighborSelected; - } - } - - if (flags & State_Active) { - if (!(flags & State_Enabled)) - bdi.state = kThemeStateUnavailable; - else if (flags & State_Sunken) - bdi.state = kThemeStatePressed; - } else { - if (flags & State_Enabled) - bdi.state = kThemeStateInactive; - else - bdi.state = kThemeStateUnavailableInactive; - } - - if (header->sortIndicator != QStyleOptionHeader::None) { - bdi.value = kThemeButtonOn; - if (header->sortIndicator == QStyleOptionHeader::SortDown) - bdi.adornment = kThemeAdornmentHeaderButtonSortUp; - } - if (flags & State_HasFocus) - bdi.adornment = kThemeAdornmentFocus; - - ir = visualRect(header->direction, header->rect, ir); - CGRect bounds = ir.toCGRect(); +#if 0 // FIXME: What's this solving exactly? bool noVerticalHeader = true; #if QT_CONFIG(tableview) if (w) @@ -3664,12 +3561,22 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter noVerticalHeader = !table->verticalHeader()->isVisible(); #endif - bool drawTopBorder = header->orientation == Qt::Horizontal; - bool drawLeftBorder = header->orientation == Qt::Vertical - || header->position == QStyleOptionHeader::OnlyOneSection - || (header->position == QStyleOptionHeader::Beginning && noVerticalHeader); - d->drawTableHeader(bounds, drawTopBorder, drawLeftBorder, bdi, p); + const bool drawLeftBorder = header->orientation == Qt::Vertical + || header->position == QStyleOptionHeader::OnlyOneSection + || (header->position == QStyleOptionHeader::Beginning && noVerticalHeader); +#endif + + const bool pressed = (flags & State_Sunken) && !(flags & State_On); + p->fillRect(ir, pressed ? header->palette.dark() : header->palette.button()); + p->setPen(QPen(header->palette.dark(), 1.0)); + if (header->orientation == Qt::Horizontal) + p->drawLine(QLineF(ir.right() + 0.5, ir.top() + headerSectionSeparatorInset, + ir.right() + 0.5, ir.bottom() - headerSectionSeparatorInset)); + else + p->drawLine(QLineF(ir.left() + headerSectionSeparatorInset, ir.bottom(), + ir.right() - headerSectionSeparatorInset, ir.bottom())); } + break; case CE_HeaderLabel: if (const QStyleOptionHeader *header = qstyleoption_cast(opt)) { @@ -4657,14 +4564,31 @@ QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt, // Subtract width needed for arrow, if there is one if (header->sortIndicator != QStyleOptionHeader::None) { if (opt->state & State_Horizontal) - rect.setWidth(rect.width() - (opt->rect.height() / 2) - (margin * 2)); + rect.setWidth(rect.width() - (headerSectionArrowHeight) - (margin * 2)); else - rect.setHeight(rect.height() - (opt->rect.width() / 2) - (margin * 2)); + rect.setHeight(rect.height() - (headerSectionArrowHeight) - (margin * 2)); } } rect = visualRect(opt->direction, opt->rect, rect); break; } + case SE_HeaderArrow: { + int h = opt->rect.height(); + int w = opt->rect.width(); + int x = opt->rect.x(); + int y = opt->rect.y(); + int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt, widget); + + if (opt->state & State_Horizontal) { + rect.setRect(x + w - margin * 2 - headerSectionArrowHeight, y + 5, + headerSectionArrowHeight, h - margin * 2 - 5); + } else { + rect.setRect(x + 5, y + h - margin * 2 - headerSectionArrowHeight, + w - margin * 2 - 5, headerSectionArrowHeight); + } + rect = visualRect(opt->direction, opt->rect, rect); + break; + } case SE_ProgressBarGroove: // Wrong in the secondary dimension, but accurate enough in the main dimension. rect = opt->rect; diff --git a/src/plugins/styles/mac/qmacstyle_mac_p_p.h b/src/plugins/styles/mac/qmacstyle_mac_p_p.h index 045753989f..078509d551 100644 --- a/src/plugins/styles/mac/qmacstyle_mac_p_p.h +++ b/src/plugins/styles/mac/qmacstyle_mac_p_p.h @@ -248,8 +248,6 @@ public: static QRect comboboxEditBounds(const QRect &outerBounds, const HIThemeButtonDrawInfo &bdi); static void drawCombobox(const CGRect &outerBounds, const HIThemeButtonDrawInfo &bdi, const CocoaControl &cw, QPainter *p); - static void drawTableHeader(const CGRect &outerBounds, bool drawTopBorder, bool drawLeftBorder, - const HIThemeButtonDrawInfo &bdi, QPainter *p); bool contentFitsInPushButton(const QStyleOptionButton *btn, HIThemeButtonDrawInfo *bdi, ThemeButtonKind buttonKindToCheck) const; void initHIThemePushButton(const QStyleOptionButton *btn, const QWidget *widget, -- cgit v1.2.3 From 7c334301bd32376538390027f7481c4b5f3eab49 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 10 Nov 2017 16:25:49 +0100 Subject: HTTP/2 - fix header processing httpReply->setHeaderField does not simply append (name|value) pairs, it first erases all entries with the same name. This is quite wrong when we have _several_ 'Set-Cookie' headers, for example. Found while trying to login into a facebook account :) Task-number: QTBUG-64359 Change-Id: I51416ca3ba3d92b9414e4649e493d9cd88f6d9a0 Reviewed-by: Edward Welbourne --- src/network/access/qhttp2protocolhandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp index 114feb91b7..9dfcec8311 100644 --- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -1069,7 +1069,7 @@ void QHttp2ProtocolHandler::updateStream(Stream &stream, const HPack::HttpHeader QByteArray binder(", "); if (name == "set-cookie") binder = "\n"; - httpReply->setHeaderField(name, value.replace('\0', binder)); + httpReplyPrivate->fields.append(qMakePair(name, value.replace('\0', binder))); } } -- cgit v1.2.3 From 55f8d7dfe5589f85b0fa8a0705b1821f69b2cb34 Mon Sep 17 00:00:00 2001 From: Mikkel Krautz Date: Mon, 13 Feb 2017 21:35:02 +0100 Subject: qsslsocket_mac: handle 'OrLater' SslProtocols in verifySessionProtocol() The verifySessionProtocol() method in the SecureTransport backend did not properly handle TlsV1_0OrLater, TlsV1_1OrLater and TlsV1_2OrLater. This commit teaches verifySessionProtocol() about them. It also adds TlsV1_0OrLater, TlsV1_1OrLater and TlsV1_2OrLater to the protocolServerSide() test in tst_qsslsocket. Backport from 5.10 to 5.9 (LTS). Reviewed-by: Timur Pocheptsov (cherry picked from commit 9c765522d1c4f8090b5f5d391b1740fc4bd67664) Change-Id: I58c53bdf43e0f19b4506f3696d793f657eb4dc6f Reviewed-by: Edward Welbourne --- src/network/ssl/qsslsocket_mac.cpp | 6 +++ .../auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | 46 +++++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index 0aef6a2a99..2ba988fb70 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -1108,6 +1108,12 @@ bool QSslSocketBackendPrivate::verifySessionProtocol() const protocolOk = (sessionProtocol() >= QSsl::SslV3); else if (configuration.protocol == QSsl::SecureProtocols) protocolOk = (sessionProtocol() >= QSsl::TlsV1_0); + else if (configuration.protocol == QSsl::TlsV1_0OrLater) + protocolOk = (sessionProtocol() >= QSsl::TlsV1_0); + else if (configuration.protocol == QSsl::TlsV1_1OrLater) + protocolOk = (sessionProtocol() >= QSsl::TlsV1_1); + else if (configuration.protocol == QSsl::TlsV1_2OrLater) + protocolOk = (sessionProtocol() >= QSsl::TlsV1_2); else protocolOk = (sessionProtocol() == configuration.protocol); diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index 1545743ee9..c74d3b5375 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -1098,6 +1098,9 @@ public: QString m_interFile; QString ciphers; +signals: + void socketError(QAbstractSocket::SocketError); + protected: void incomingConnection(qintptr socketDescriptor) { @@ -1107,6 +1110,7 @@ protected: socket->setProtocol(protocol); if (ignoreSslErrors) connect(socket, SIGNAL(sslErrors(QList)), this, SLOT(ignoreErrorSlot())); + connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(socketError(QAbstractSocket::SocketError))); QFile file(m_keyFile); QVERIFY(file.open(QIODevice::ReadOnly)); @@ -1242,6 +1246,37 @@ void tst_QSslSocket::protocolServerSide_data() #if !defined(OPENSSL_NO_SSL3) QTest::newRow("any-ssl3") << QSsl::AnyProtocol << QSsl::SslV3 << true; #endif + +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) + QTest::newRow("tls1.0orlater-ssl2") << QSsl::TlsV1_0OrLater << QSsl::SslV2 << false; +#endif +#if !defined(OPENSSL_NO_SSL3) + QTest::newRow("tls1.0orlater-ssl3") << QSsl::TlsV1_0OrLater << QSsl::SslV3 << false; +#endif + QTest::newRow("tls1.0orlater-tls1.0") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_0 << true; + QTest::newRow("tls1.0orlater-tls1.1") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_1 << true; + QTest::newRow("tls1.0orlater-tls1.2") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_2 << true; + +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) + QTest::newRow("tls1.1orlater-ssl2") << QSsl::TlsV1_1OrLater << QSsl::SslV2 << false; +#endif +#if !defined(OPENSSL_NO_SSL3) + QTest::newRow("tls1.1orlater-ssl3") << QSsl::TlsV1_1OrLater << QSsl::SslV3 << false; +#endif + QTest::newRow("tls1.1orlater-tls1.0") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_0 << false; + QTest::newRow("tls1.1orlater-tls1.1") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_1 << true; + QTest::newRow("tls1.1orlater-tls1.2") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_2 << true; + +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) + QTest::newRow("tls1.2orlater-ssl2") << QSsl::TlsV1_2OrLater << QSsl::SslV2 << false; +#endif +#if !defined(OPENSSL_NO_SSL3) + QTest::newRow("tls1.2orlater-ssl3") << QSsl::TlsV1_2OrLater << QSsl::SslV3 << false; +#endif + QTest::newRow("tls1.2orlater-tls1.0") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_0 << false; + QTest::newRow("tls1.2orlater-tls1.1") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_1 << false; + QTest::newRow("tls1.2orlater-tls1.2") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_2 << true; + QTest::newRow("any-tls1.0") << QSsl::AnyProtocol << QSsl::TlsV1_0 << true; QTest::newRow("any-tls1ssl3") << QSsl::AnyProtocol << QSsl::TlsV1SslV3 << true; QTest::newRow("any-secure") << QSsl::AnyProtocol << QSsl::SecureProtocols << true; @@ -1264,6 +1299,7 @@ void tst_QSslSocket::protocolServerSide() QVERIFY(server.listen()); QEventLoop loop; + connect(&server, SIGNAL(socketError(QAbstractSocket::SocketError)), &loop, SLOT(quit())); QTimer::singleShot(5000, &loop, SLOT(quit())); QSslSocket client; @@ -1281,7 +1317,15 @@ void tst_QSslSocket::protocolServerSide() QFETCH(bool, works); QAbstractSocket::SocketState expectedState = (works) ? QAbstractSocket::ConnectedState : QAbstractSocket::UnconnectedState; - QCOMPARE(int(client.state()), int(expectedState)); + // Determine whether the client or the server caused the event loop + // to quit due to a socket error, and investigate the culprit. + if (server.socket->error() != QAbstractSocket::UnknownSocketError) { + QVERIFY(client.error() == QAbstractSocket::UnknownSocketError); + QCOMPARE(int(server.socket->state()), int(expectedState)); + } else if (client.error() != QAbstractSocket::UnknownSocketError) { + QVERIFY(server.socket->error() == QAbstractSocket::UnknownSocketError); + QCOMPARE(int(client.state()), int(expectedState)); + } QCOMPARE(client.isEncrypted(), works); } -- cgit v1.2.3 From f6c9f0312888317c0cd6a85cd3f238bb4e0295c5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 13 Nov 2017 15:48:07 +0100 Subject: tst_QNetworkReply: Blacklist putToFtp for Windows Task-number: QTBUG-62860 Change-Id: I9cea1414ae3761284f5ac9fab9d0db03c239b65f Reviewed-by: Timur Pocheptsov --- tests/auto/network/access/qnetworkreply/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index acea0a5aad..57f33d5863 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -30,6 +30,8 @@ linux [ioHttpRedirectPostPut] linux windows +[putToFtp] +windows ci [putWithServerClosingConnectionImmediately] windows [qtbug28035browserDoesNotLoadQtProjectOrgCorrectly] -- cgit v1.2.3 From 2caebf42a70cceb21b46b08e341c3cbf928b1fc8 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Tue, 14 Nov 2017 19:26:56 +0200 Subject: QIODevice: do not clear error string on close Keeping a description of the last device error is a more informative to the user than forcing the string to 'Unknown error'. Change-Id: Ie98fe1c94f24279fb633ce950bbe16450b0efdbd Reviewed-by: Thiago Macieira Reviewed-by: Edward Welbourne --- src/corelib/io/qiodevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 82fc34c537..0a3e83206b 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -775,6 +775,7 @@ bool QIODevice::open(OpenMode mode) d->writeBuffers.clear(); d->setReadChannelCount(isReadable() ? 1 : 0); d->setWriteChannelCount(isWritable() ? 1 : 0); + d->errorString.clear(); #if defined QIODEVICE_DEBUG printf("%p QIODevice::open(0x%x)\n", this, quint32(mode)); #endif @@ -801,7 +802,6 @@ void QIODevice::close() emit aboutToClose(); #endif d->openMode = NotOpen; - d->errorString.clear(); d->pos = 0; d->transactionStarted = false; d->transactionPos = 0; -- cgit v1.2.3 From a4113d0c644edba1c39d9d268a259e95ae51c61e Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 17 Nov 2017 10:35:58 +0100 Subject: qfloat16(float) constructor: explicit cast on aarch64 to avoid warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The warning was global/qfloat16.h: In constructor ‘qfloat16::qfloat16(float)’: global/qfloat16.h:124:18: error: conversion to ‘__fp16’ from ‘float’ may alter its value [-Werror=float-conversion] __fp16 f16 = f; ^ cc1plus: all warnings being treated as errors The warning was added by fb5976038162d93d60c7f76376bbb4df38e83ba9. Change-Id: I489348c4d5d672bfa5d4db99c837696a2a69a27e Reviewed-by: Thiago Macieira --- src/corelib/global/qfloat16.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h index 10598adb1d..a36852fc22 100644 --- a/src/corelib/global/qfloat16.h +++ b/src/corelib/global/qfloat16.h @@ -121,7 +121,7 @@ inline qfloat16::qfloat16(float f) Q_DECL_NOTHROW __m128i packhalf = _mm_cvtps_ph(packsingle, 0); b16 = _mm_extract_epi16(packhalf, 0); #elif defined (__ARM_FP16_FORMAT_IEEE) - __fp16 f16 = f; + __fp16 f16 = __fp16(f); memcpy(&b16, &f16, sizeof(quint16)); #else quint32 u; -- cgit v1.2.3