summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-11-20 13:48:33 +0100
committerOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-11-20 13:48:33 +0100
commitbb3872d60975724a50ff910b6dd108d1944db597 (patch)
treece1c96729a1a4691a322b36cfd5429c020403ccc
parentb72b5cd76004e54dc00c0f1133f4d59192ef154a (diff)
parent8e387e7fa758ded3f0d096dcf5fe13a22521dad7 (diff)
Merge 5.10 into 5.10.0
-rw-r--r--.gitignore6
-rw-r--r--examples/corelib/ipc/localfortuneserver/server.cpp2
-rw-r--r--examples/corelib/json/savegame/game.cpp12
-rw-r--r--examples/corelib/threads/queuedcustomtype/main.cpp1
-rw-r--r--examples/corelib/threads/queuedcustomtype/renderthread.cpp6
-rw-r--r--examples/corelib/threads/semaphores/semaphores.cpp3
-rw-r--r--examples/corelib/threads/waitconditions/waitconditions.cpp4
-rw-r--r--examples/corelib/tools/contiguouscache/randomlistmodel.cpp3
-rw-r--r--examples/embedded/flickable/main.cpp2
-rw-r--r--examples/network/fortuneserver/server.cpp2
-rw-r--r--examples/network/threadedfortuneserver/fortuneserver.cpp4
-rw-r--r--examples/network/threadedfortuneserver/main.cpp1
-rw-r--r--examples/network/torrent/main.cpp1
-rw-r--r--examples/network/torrent/torrentclient.cpp22
-rw-r--r--examples/opengl/hellowindow/hellowindow.cpp7
-rw-r--r--examples/opengl/legacy/overpainting/bubble.cpp10
-rw-r--r--examples/opengl/legacy/overpainting/glwidget.cpp12
-rw-r--r--examples/opengl/qopenglwidget/bubble.cpp8
-rw-r--r--examples/opengl/qopenglwidget/glwidget.cpp11
-rw-r--r--examples/opengl/qopenglwidget/mainwindow.cpp5
-rw-r--r--examples/qtconcurrent/imagescaling/imagescaling.cpp28
-rw-r--r--examples/qtconcurrent/imagescaling/imagescaling.h4
-rw-r--r--examples/qtconcurrent/map/main.cpp12
-rw-r--r--examples/qtconcurrent/progressdialog/main.cpp34
-rw-r--r--examples/qtconcurrent/wordcount/main.cpp27
-rw-r--r--examples/touch/pinchzoom/main.cpp1
-rw-r--r--examples/touch/pinchzoom/mouse.cpp15
-rw-r--r--examples/widgets/animation/animatedtiles/main.cpp5
-rw-r--r--examples/widgets/animation/moveblocks/main.cpp4
-rw-r--r--examples/widgets/animation/stickman/lifecycle.cpp3
-rw-r--r--examples/widgets/animation/sub-attaq/main.cpp2
-rw-r--r--examples/widgets/animation/sub-attaq/states.cpp7
-rw-r--r--examples/widgets/animation/sub-attaq/submarine_p.h5
-rw-r--r--examples/widgets/doc/src/collidingmice-example.qdoc10
-rw-r--r--examples/widgets/doc/src/dragdroprobot.qdoc2
-rw-r--r--examples/widgets/doc/src/elasticnodes.qdoc9
-rw-r--r--examples/widgets/draganddrop/puzzle/mainwindow.cpp4
-rw-r--r--examples/widgets/graphicsview/boxes/qtbox.cpp2
-rw-r--r--examples/widgets/graphicsview/boxes/scene.cpp10
-rw-r--r--examples/widgets/graphicsview/collidingmice/main.cpp1
-rw-r--r--examples/widgets/graphicsview/collidingmice/mouse.cpp15
-rw-r--r--examples/widgets/graphicsview/dragdroprobot/coloritem.cpp4
-rw-r--r--examples/widgets/graphicsview/dragdroprobot/main.cpp1
-rw-r--r--examples/widgets/graphicsview/elasticnodes/graphwidget.cpp3
-rw-r--r--examples/widgets/graphicsview/elasticnodes/main.cpp1
-rw-r--r--examples/widgets/itemviews/puzzle/mainwindow.cpp2
-rw-r--r--examples/widgets/itemviews/puzzle/piecesmodel.cpp3
-rw-r--r--examples/widgets/mainwindows/mainwindow/toolbar.cpp4
-rw-r--r--examples/widgets/statemachine/rogue/window.cpp4
-rw-r--r--examples/widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp2
-rw-r--r--examples/widgets/tools/undo/mainwindow.cpp11
-rw-r--r--examples/widgets/tools/undoframework/diagramitem.cpp3
-rw-r--r--examples/widgets/widgets/tetrix/main.cpp1
-rw-r--r--examples/widgets/widgets/tetrix/tetrixpiece.cpp2
-rw-r--r--examples/widgets/widgets/tooltips/main.cpp1
-rw-r--r--examples/widgets/widgets/tooltips/sortingbox.cpp4
-rw-r--r--header.BSD-OLD40
-rw-r--r--header.FDL-OLD27
-rwxr-xr-xmkspecs/features/uikit/device_destinations.sh6
-rwxr-xr-xmkspecs/features/uikit/devices.py (renamed from mkspecs/features/uikit/devices.pl)58
-rw-r--r--mkspecs/features/uikit/xcodebuild.mk4
-rw-r--r--mkspecs/features/uikit/xcodebuild.prf6
-rw-r--r--mkspecs/macx-xcode/default.xcscheme1
-rw-r--r--src/3rdparty/libpng/ANNOUNCE77
-rw-r--r--src/3rdparty/libpng/CHANGES51
-rw-r--r--src/3rdparty/libpng/LICENSE4
-rw-r--r--src/3rdparty/libpng/README2
-rw-r--r--src/3rdparty/libpng/libpng-manual.txt21
-rw-r--r--src/3rdparty/libpng/png.c32
-rw-r--r--src/3rdparty/libpng/png.h28
-rw-r--r--src/3rdparty/libpng/pngconf.h2
-rw-r--r--src/3rdparty/libpng/pnglibconf.h4
-rw-r--r--src/3rdparty/libpng/pngread.c14
-rw-r--r--src/3rdparty/libpng/pngrtran.c22
-rw-r--r--src/3rdparty/libpng/pngrutil.c47
-rw-r--r--src/3rdparty/libpng/pngtrans.c6
-rw-r--r--src/3rdparty/libpng/pngwrite.c2
-rw-r--r--src/3rdparty/libpng/qt_attribution.json2
-rw-r--r--src/corelib/global/qcompilerdetection.h6
-rw-r--r--src/corelib/global/qfloat16.h2
-rw-r--r--src/corelib/global/qrandom.cpp926
-rw-r--r--src/corelib/global/qrandom.h183
-rw-r--r--src/corelib/global/qrandom_p.h18
-rw-r--r--src/corelib/io/qfilesystemwatcher_win.cpp4
-rw-r--r--src/corelib/io/qiodevice.cpp2
-rw-r--r--src/corelib/io/qprocess_win.cpp7
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp34
-rw-r--r--src/corelib/io/qtemporaryfile.cpp2
-rw-r--r--src/corelib/thread/qmutex.h6
-rw-r--r--src/corelib/thread/qsemaphore.h6
-rw-r--r--src/corelib/tools/qhash.cpp1
-rw-r--r--src/corelib/tools/qsimd.cpp26
-rw-r--r--src/corelib/tools/qversionnumber.cpp4
-rw-r--r--src/gui/image/qpixmap_blitter.cpp3
-rw-r--r--src/gui/kernel/qhighdpiscaling_p.h3
-rw-r--r--src/gui/kernel/qopenglcontext.cpp1
-rw-r--r--src/gui/kernel/qwindow.cpp5
-rw-r--r--src/gui/opengl/qopenglgradientcache.cpp3
-rw-r--r--src/gui/painting/qcoregraphics.mm1
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp3
-rw-r--r--src/gui/painting/qtextureglyphcache.cpp3
-rw-r--r--src/gui/text/qfont.cpp22
-rw-r--r--src/network/access/qhttp2protocolhandler.cpp2
-rw-r--r--src/network/kernel/kernel.pri2
-rw-r--r--src/network/kernel/qdnslookup.cpp11
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp20
-rw-r--r--src/opengl/gl2paintengineex/qglgradientcache.cpp3
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp30
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h6
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm32
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm16
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm11
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm15
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm1
-rw-r--r--src/plugins/platforms/offscreen/qoffscreenintegration.cpp32
-rw-r--r--src/plugins/platforms/offscreen/qoffscreenintegration.h3
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowssystemtrayicon.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp2
-rw-r--r--src/plugins/sqldrivers/oci/qsql_oci.cpp2
-rw-r--r--src/plugins/sqldrivers/psql/qsql_psql.cpp191
-rw-r--r--src/plugins/sqldrivers/psql/qsql_psql_p.h24
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm567
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac_p.h4
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac_p_p.h72
-rw-r--r--src/testlib/qtesthelpers_p.h112
-rw-r--r--src/testlib/testlib.pro3
-rw-r--r--src/widgets/itemviews/qheaderview.cpp8
-rw-r--r--src/widgets/itemviews/qlistview.cpp15
-rw-r--r--src/widgets/kernel/qshortcut.cpp2
-rw-r--r--src/widgets/kernel/qwidget.cpp2
-rw-r--r--src/widgets/widgets/qabstractbutton.cpp3
-rw-r--r--src/widgets/widgets/qmainwindow.cpp1
-rw-r--r--src/widgets/widgets/qmenu.cpp114
-rw-r--r--src/widgets/widgets/qmenu_p.h151
-rw-r--r--src/widgets/widgets/qmenubar.cpp54
-rw-r--r--src/widgets/widgets/qmenubar_p.h4
-rw-r--r--tests/auto/auto.pro2
-rw-r--r--tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp4
-rw-r--r--tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST2
-rw-r--r--tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp395
-rw-r--r--tests/auto/corelib/io/largefile/tst_largefile.cpp4
-rw-r--r--tests/auto/corelib/io/qfile/tst_qfile.cpp25
-rw-r--r--tests/auto/corelib/io/qstandardpaths/BLACKLIST3
-rw-r--r--tests/auto/corelib/io/qtemporarydir/qtemporarydir.pro2
-rw-r--r--tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp13
-rw-r--r--tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.pro2
-rw-r--r--tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp16
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp4
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp1
-rw-r--r--tests/auto/corelib/plugin/quuid/testProcessUniqueness/main.cpp3
-rw-r--r--tests/auto/corelib/thread/qfuture/tst_qfuture.cpp3
-rw-r--r--tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp11
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp5
-rw-r--r--tests/auto/gui/image/qimage/tst_qimage.cpp3
-rw-r--r--tests/auto/gui/painting/qpainter/tst_qpainter.cpp3
-rw-r--r--tests/auto/gui/painting/qpathclipper/tst_qpathclipper.cpp5
-rw-r--r--tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp19
-rw-r--r--tests/auto/network/access/hpack/tst_hpack.cpp12
-rw-r--r--tests/auto/network/access/http2/tst_http2.cpp2
-rw-r--r--tests/auto/network/access/qftp/tst_qftp.cpp3
-rw-r--r--tests/auto/network/access/qnetworkdiskcache/tst_qnetworkdiskcache.cpp14
-rw-r--r--tests/auto/network/access/qnetworkreply/BLACKLIST32
-rw-r--r--tests/auto/network/access/qnetworkreply/test/test.pro3
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp65
-rw-r--r--tests/auto/network/socket/qtcpsocket/qtcpsocket.pro6
-rw-r--r--tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp8
-rw-r--r--tests/auto/network/socket/qudpsocket/qudpsocket.pro3
-rw-r--r--tests/auto/network/socket/qudpsocket/test/test.pro1
-rw-r--r--tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp171
-rw-r--r--tests/auto/opengl/qglthreads/tst_qglthreads.cpp20
-rw-r--r--tests/auto/other/compiler/tst_compiler.cpp10
-rw-r--r--tests/auto/other/networkselftest/tst_networkselftest.cpp3
-rw-r--r--tests/auto/other/qaccessibility/qaccessibility.pro2
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp12
-rw-r--r--tests/auto/other/qnetworkaccessmanager_and_qprogressdialog/BLACKLIST2
-rw-r--r--tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp19
-rw-r--r--tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp2
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp3
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro2
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp31
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp30
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsview/qgraphicsview.pro2
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp12
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/qabstractitemview.pro2
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp15
-rw-r--r--tests/auto/widgets/itemviews/qcolumnview/qcolumnview.pro2
-rw-r--r--tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp11
-rw-r--r--tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp4
-rw-r--r--tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp23
-rw-r--r--tests/auto/widgets/itemviews/qlistview/qlistview.pro2
-rw-r--r--tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp14
-rw-r--r--tests/auto/widgets/itemviews/qtableview/qtableview.pro2
-rw-r--r--tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp14
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/qtreeview.pro2
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp14
-rw-r--r--tests/auto/widgets/kernel/qaction/tst_qaction.cpp52
-rw-r--r--tests/auto/widgets/kernel/qboxlayout/qboxlayout.pro2
-rw-r--r--tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp10
-rw-r--r--tests/auto/widgets/kernel/qformlayout/qformlayout.pro2
-rw-r--r--tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp12
-rw-r--r--tests/auto/widgets/kernel/qgridlayout/qgridlayout.pro2
-rw-r--r--tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp12
-rw-r--r--tests/auto/widgets/kernel/qlayout/qlayout.pro2
-rw-r--r--tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp10
-rw-r--r--tests/auto/widgets/kernel/qwidget/BLACKLIST2
-rw-r--r--tests/auto/widgets/kernel/qwidget/qwidget.pro2
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp29
-rw-r--r--tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro2
-rw-r--r--tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp10
-rw-r--r--tests/auto/widgets/kernel/qwidgetaction/qwidgetaction.pro2
-rw-r--r--tests/auto/widgets/kernel/qwidgetaction/tst_qwidgetaction.cpp10
-rw-r--r--tests/auto/widgets/styles/qstyle/qstyle.pro2
-rw-r--r--tests/auto/widgets/styles/qstyle/tst_qstyle.cpp12
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro2
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp7
-rw-r--r--tests/auto/widgets/util/qcompleter/qcompleter.pro2
-rw-r--r--tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp10
-rw-r--r--tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp32
-rw-r--r--tests/auto/widgets/widgets/qabstractslider/qabstractslider.pro2
-rw-r--r--tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp12
-rw-r--r--tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro2
-rw-r--r--tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp13
-rw-r--r--tests/auto/widgets/widgets/qcombobox/qcombobox.pro2
-rw-r--r--tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp10
-rw-r--r--tests/auto/widgets/widgets/qlineedit/qlineedit.pro2
-rw-r--r--tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp28
-rw-r--r--tests/auto/widgets/widgets/qmenu/qmenu.pro2
-rw-r--r--tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp14
-rw-r--r--tests/auto/widgets/widgets/qmenubar/BLACKLIST2
-rw-r--r--tests/auto/widgets/widgets/qmenubar/qmenubar.pro2
-rw-r--r--tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp90
-rw-r--r--tests/auto/widgets/widgets/qscrollbar/qscrollbar.pro2
-rw-r--r--tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp11
-rw-r--r--tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp32
-rw-r--r--tests/benchmarks/corelib/tools/qalgorithms/tst_qalgorithms.cpp2
-rw-r--r--tests/benchmarks/corelib/tools/qcryptographichash/main.cpp6
-rw-r--r--tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp16
-rw-r--r--tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp2
-rw-r--r--tests/benchmarks/gui/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp5
-rw-r--r--tests/benchmarks/gui/painting/qtbench/benchmarktests.h9
-rw-r--r--tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp3
-rw-r--r--tests/manual/cocoa/menurama/mainwindow.cpp5
-rw-r--r--tests/manual/cocoa/menurama/mainwindow.ui1
-rw-r--r--tests/manual/cocoa/nativewidgets/main.cpp2
-rw-r--r--tests/manual/textrendering/textperformance/main.cpp21
-rw-r--r--tests/manual/windowchildgeometry/controllerwidget.cpp18
251 files changed, 3131 insertions, 2143 deletions
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
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<Character> 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<Character> 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<Block>();
//! [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 <QRandomGenerator>
+
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 <QRandomGenerator>
#include <stdlib.h>
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 <QRandomGenerator>
+
#include <stdlib.h>
//! [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<TorrentPiece *> 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 <QOpenGLContext>
#include <QOpenGLFunctions>
+#include <QRandomGenerator>
#include <qmath.h>
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> &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 <QRandomGenerator>
+
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 <QMouseEvent>
+#include <QRandomGenerator>
#include <QTime>
#include <math.h>
@@ -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 <QPaintEngine>
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
+#include <QRandomGenerator>
#include <QCoreApplication>
#include <qmath.h>
@@ -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 <QSlider>
#include <QLabel>
#include <QCheckBox>
+#include <QRandomGenerator>
#include <QSpinBox>
#include <QScrollArea>
@@ -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/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 <qmath.h>
-const int imageSize = 100;
+#include <qmath.h>
-QImage scale(const QString &imageFileName)
-{
- QImage image(imageFileName);
- return image.scaled(QSize(imageSize, imageSize), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
-}
+#include <functional>
Images::Images(QWidget *parent)
: QWidget(parent)
@@ -65,19 +60,19 @@ Images::Images(QWidget *parent)
resize(800, 600);
imageScaling = new QFutureWatcher<QImage>(this);
- connect(imageScaling, SIGNAL(resultReadyAt(int)), SLOT(showImage(int)));
- connect(imageScaling, SIGNAL(finished()), SLOT(finished()));
+ connect(imageScaling, &QFutureWatcher<QImage>::resultReadyAt, this, &Images::showImage);
+ connect(imageScaling, &QFutureWatcher<QImage>::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<QImage>::cancel);
pauseButton = new QPushButton(tr("Pause/Resume"));
pauseButton->setEnabled(false);
- connect(pauseButton, SIGNAL(clicked()), imageScaling, SLOT(togglePaused()));
+ connect(pauseButton, &QPushButton::clicked, imageScaling, &QFutureWatcher<QImage>::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<QImage(const QString&)> 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 <QGuiApplication>
#include <qtconcurrentmap.h>
-QImage scale(const QImage &image)
-{
- qDebug() << "Scaling image in thread" << QThread::currentThread();
- return image.scaled(QSize(100, 100), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
-}
+#include <functional>
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<QImage(const QImage&)> 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<QImage> 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 <QtWidgets>
#include <QtConcurrent>
-using namespace QtConcurrent;
-
-const int iterations = 20;
+#include <functional>
-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<int> 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<void> 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<void>::finished, &dialog, &QProgressDialog::reset);
+ QObject::connect(&dialog, &QProgressDialog::canceled, &futureWatcher, &QFutureWatcher<void>::cancel);
+ QObject::connect(&futureWatcher, &QFutureWatcher<void>::progressRangeChanged, &dialog, &QProgressDialog::setRange);
+ QObject::connect(&futureWatcher, &QFutureWatcher<void>::progressValueChanged, &dialog, &QProgressDialog::setValue);
+
+ // Our function to compute
+ std::function<void(int&)> 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<QString, int> 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);
}
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 <QGraphicsScene>
#include <QPainter>
+#include <QRandomGenerator>
#include <QStyleOption>
#include <qmath.h>
@@ -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 <QtWidgets>
#include <QtCore/qmath.h>
+#include <QtCore/qrandom.h>
#include <QtCore/qstate.h>
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 <QtCore/QStateMachine>
#include <QtWidgets/QKeyEventTransition>
#include <QtCore/QFinalState>
+#include <QtCore/QRandomGenerator>
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 <QtCore/QPropertyAnimation>
+#include <QtCore/QRandomGenerator>
#include <QtWidgets/QGraphicsScene>
//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 <QDebug>
#include "scene.h"
+#include <QtCore/QRandomGenerator>
#include <QtGui/qmatrix4x4.h>
#include <QtGui/qvector3d.h>
#include <qmath.h>
@@ -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 <QGraphicsScene>
#include <QPainter>
+#include <QRandomGenerator>
#include <QStyleOption>
#include <qmath.h>
@@ -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 <math.h>
#include <QKeyEvent>
+#include <QRandomGenerator>
//! [0]
GraphWidget::GraphWidget(QWidget *parent)
@@ -247,7 +248,7 @@ void GraphWidget::shuffle()
{
foreach (QGraphicsItem *item, scene()->items()) {
if (qgraphicsitem_cast<Node *>(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 <QIcon>
#include <QMimeData>
+#include <QRandomGenerator>
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 <QRandomGenerator>
+
#include <QMainWindow>
#include <QMenu>
#include <QPainter>
@@ -257,7 +259,7 @@ void ToolBar::randomize()
QList<QAction *> randomized;
QList<QAction *> 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 <QUndoStack>
#include <QFileDialog>
#include <QMessageBox>
+#include <QRandomGenerator>
#include <QTextStream>
#include <QToolButton>
#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<int>(qrand()) % 256,
- static_cast<int>(qrand()) % 256, static_cast<int>(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/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$
-**
-****************************************************************************/
-
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.py
index 8d69a97273..0443e838f2 100755
--- a/mkspecs/features/uikit/devices.pl
+++ b/mkspecs/features/uikit/devices.py
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/python
#############################################################################
##
@@ -39,18 +39,44 @@
##
#############################################################################
-$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";
-}
+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
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">
<BuildableProductRunnable>
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
<glennrp at users.sourceforge.net>
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",
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
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;
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
index 9abb9ece7f..72ac8d332b 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 <qobjectdefs.h>
+#include <qmutex.h>
#include <qthreadstorage.h>
-#include <private/qsimd_p.h>
-
-#include <random>
#include <errno.h>
@@ -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,14 +121,21 @@ static QT_FUNCTION_TARGET(RDRND) qssize_t qt_random_cpu(void *buffer, qssize_t c
out:
return ptr - reinterpret_cast<unsigned *>(buffer);
}
+#else
+static qssize_t qt_random_cpu(void *, qssize_t)
+{
+ return 0;
+}
#endif
-namespace {
-#if QT_CONFIG(getentropy)
-class SystemRandom
+enum {
+ // may be "overridden" by a member enum
+ FillBufferNoexcept = true
+};
+
+struct QRandomGenerator::SystemGenerator
{
-public:
- enum { EfficientBufferFill = true };
+#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
@@ -147,96 +153,93 @@ 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);
+ enum { FillBufferNoexcept = false };
-void SystemRandom::closeDevice()
-{
- int fd = s_fdp1.loadAcquire() - 1;
- if (fd >= 0)
- qt_safe_close(fd);
-}
+ 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;
+ }
-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;
+ int opened_fdp1;
+ if (fdp1.testAndSetOrdered(0, fd + 1, opened_fdp1))
+ return fd;
+
+ // 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 = self().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;
-}
+ Q_DECL_CONSTEXPR 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<qssize_t>(n, 0); // ignore any errors
-}
-#endif // Q_OS_UNIX
+ qint64 n = qt_safe_read(fd, buffer, count);
+ return qMax<qssize_t>(n, 0); // ignore any errors
+ }
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
-class SystemRandom
-{
-public:
- enum { EfficientBufferFill = true };
- 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:
- enum { EfficientBufferFill = false };
- 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();
+ 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 <typename T> 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<quint32 *>(begin), reinterpret_cast<quint32 *>(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) {}
@@ -255,6 +258,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) {}
@@ -350,31 +354,25 @@ 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
+Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, quint32 *end)
+ Q_DECL_NOEXCEPT_EXPR(FillBufferNoexcept)
{
-#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;
-}
+ quint32 *buffer = begin;
+ qssize_t count = end - begin;
-static void fill_internal(quint32 *buffer, qssize_t count)
- Q_DECL_NOEXCEPT_EXPR(noexcept(SystemRandom::fillBuffer(buffer, count)))
-{
if (Q_UNLIKELY(uint(qt_randomdevice_control) & SetRandomData)) {
uint value = uint(qt_randomdevice_control) & RandomDataMask;
std::fill_n(buffer, count, value);
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)
@@ -386,147 +384,262 @@ 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<quint32 *>(buffer), 1)))
+struct QRandomGenerator::SystemAndGlobalGenerators
{
- 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);
+ // 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<sizeof(QRandomGenerator64), 64>::type global_;
+
+#ifdef Q_COMPILER_CONSTEXPR
+ constexpr SystemAndGlobalGenerators()
+ : globalPRNGMutex{}, system_{0}, sys{}, global_{}
+ {}
+#endif
- quint32 *ptr = reinterpret_cast<quint32 *>(buffer);
- quint32 * const end = reinterpret_cast<quint32 *>(bufferEnd);
+ void confirmLiteral()
+ {
+#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. Integrity's compiler is unable to
+ // guarantee g's alignment for some reason.
+
+ constexpr SystemAndGlobalGenerators g = {};
+ Q_UNUSED(g);
+ Q_STATIC_ASSERT(std::is_literal_type<SystemAndGlobalGenerators>::value);
+#endif
+ }
-#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;
+ static SystemAndGlobalGenerators *self()
+ {
+ static SystemAndGlobalGenerators g;
+ Q_STATIC_ASSERT(sizeof(g) > sizeof(QRandomGenerator64));
+ return &g;
+ }
- // 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;
+ 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<QRandomGenerator64 *>(&self()->system_);
+ }
- if (ptr != end) {
- // refill the buffer and try again
- fill_internal(state.buffer, ThreadState::BufferCount);
- state.idx = 0;
+ 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<QRandomGenerator64 *>(&self()->global_);
+ }
- itemsToCopy = end - ptr;
- memcpy(ptr, state.buffer + state.idx, size_t(itemsToCopy) * sizeof(*ptr));
- ptr = end;
- }
+ static void securelySeed(QRandomGenerator *rng)
+ {
+ // force reconstruction, just to be pedantic
+ new (rng) QRandomGenerator{System{}};
- // 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;
+ rng->type = MersenneTwister;
+ new (&rng->storage.engine()) RandomEngine(self()->sys);
}
-#endif // Q_COMPILER_THREAD_LOCAL && !QT_BOOTSTRAPPED
- if (ptr != end) {
- // fill directly in the user buffer
- fill_internal(ptr, end - ptr);
- }
+ 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
+ \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::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
+ 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.
+ 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.
- \warning This class is not suitable for bulk data creation. See below for the
- technical reasons.
+ \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
- \section1 Frequency and entropy exhaustion
+ 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(), like all generators created by
+ QRandomGenerator::securelySeeded(), is always seeded from
+ QRandomGenerator::system(), so it's not possible to make it produce
+ identical sequences.
+
+ \section1 Bulk data
+
+ 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.
+
+ 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
- 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.
+ \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{<random>}, 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);
+ 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. Exceptions to the requirements are
+ the following:
- // equivalent to:
- for (auto &v : block)
- v = rng();
- \endcode
+ \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
@@ -535,57 +648,129 @@ static Q_NEVER_INLINE void fill(void *buffer, void *bufferEnd)
[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 seedValue)
+
+ 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 seed(), securelySeeded()
*/
/*!
- \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()()
+ \sa seed(), securelySeeded()
*/
/*!
- \fn result_type QRandomGenerator::operator()()
+ \fn QRandomGenerator::QRandomGenerator(const quint32 *seedBuffer, qssize_t len)
+ \overload
- Generates a 32-bit random quantity and returns it.
+ 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.
- \sa QRandomGenerator::generate(), QRandomGenerator::generate64()
+ This constructor is equivalent to:
+ \code
+ std::seed_seq sseq(seedBuffer, seedBuffer + len);
+ QRandomGenerator generator(sseq);
+ \endcode
+
+ \sa seed(), securelySeeded()
*/
/*!
- \fn double QRandomGenerator::entropy() const
+ \fn QRandomGenerator::QRandomGenerator(const quint32 *begin, const quin32 *end)
+ \overload
+
+ 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.
- Returns the estimate of the entropy in the random generator source.
+ This constructor is equivalent to:
+ \code
+ std::seed_seq sseq(begin, end);
+ QRandomGenerator generator(sseq);
+ \endcode
+
+ \sa seed(), securelySeeded()
+ */
+
+/*!
+ \fn QRandomGenerator::QRandomGenerator(std::seed_seq &sseq)
+ \overload
- 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.
+ 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.
- Since QRandomGenerator attempts to use a hardware Random Number Generator,
- this function always returns 0.0.
+ \sa seed(), securelySeeded()
+ */
+
+/*!
+ \fn QRandomGenerator::QRandomGenerator(const QRandomGenerator &other)
+
+ 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.
+
+ 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.
+
+ For that reason, it is not adviseable to create a copy of
+ QRandomGenerator::global(). If one needs an exclusive deterministic
+ generator, consider instead using securelySeeded() to obtain a new object
+ 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
+
+ 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()
*/
/*!
@@ -593,7 +778,7 @@ static Q_NEVER_INLINE void fill(void *buffer, void *bufferEnd)
Returns the minimum value that QRandomGenerator may ever generate. That is, 0.
- \sa max(), QRandomGenerator64::max()
+ \sa max(), QRandomGenerator64::min()
*/
/*!
@@ -606,13 +791,38 @@ static Q_NEVER_INLINE void fill(void *buffer, void *bufferEnd)
*/
/*!
+ \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)
Generates 32-bit quantities and stores them in the range between \a begin
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
@@ -625,7 +835,7 @@ static Q_NEVER_INLINE void fill(void *buffer, void *bufferEnd)
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
@@ -703,26 +913,26 @@ static Q_NEVER_INLINE void fill(void *buffer, void *bufferEnd)
*/
/*!
- \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:
@@ -741,11 +951,11 @@ static Q_NEVER_INLINE void fill(void *buffer, void *bufferEnd)
*/
/*!
- \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.
@@ -754,13 +964,13 @@ static Q_NEVER_INLINE void fill(void *buffer, void *bufferEnd)
*/
/*!
- \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
@@ -778,11 +988,11 @@ static Q_NEVER_INLINE void fill(void *buffer, void *bufferEnd)
*/
/*!
- \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.
@@ -791,6 +1001,72 @@ static Q_NEVER_INLINE void fill(void *buffer, void *bufferEnd)
*/
/*!
+ \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 <random> 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 securelySeeded(), global()
+*/
+
+/*!
+ \fn QRandomGenerator *QRandomGenerator::global()
+ \threadsafe
+
+ Returns a pointer to a shared QRandomGenerator that was seeded using
+ 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:
+
+ \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 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
\since 5.10
@@ -811,10 +1087,11 @@ static Q_NEVER_INLINE void fill(void *buffer, void *bufferEnd)
*/
/*!
- \fn QRandomGenerator64::QRandomGenerator64()
- \internal
- Defaulted constructor, does nothing.
- */
+ \fn QRandomGenerator64::QRandomGenerator64(const QRandomGenerator &other)
+ \internal
+
+ Creates a copy.
+*/
/*!
\typedef QRandomGenerator64::result_type
@@ -849,80 +1126,119 @@ static Q_NEVER_INLINE void fill(void *buffer, void *bufferEnd)
\sa QRandomGenerator::generate(), QRandomGenerator::generate64()
*/
-/*!
- \fn double QRandomGenerator64::entropy() const
+Q_DECL_CONSTEXPR QRandomGenerator::Storage::Storage()
+ : dummy(0)
+{
+ // nothing
+}
- Returns the estimate of the entropy in the random generator source.
+inline QRandomGenerator64::QRandomGenerator64(System s)
+ : QRandomGenerator(s)
+{
+}
- 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.
+QRandomGenerator64 *QRandomGenerator64::system()
+{
+ auto self = SystemAndGlobalGenerators::system();
+ Q_ASSERT(self->type == SystemRNG);
+ return self;
+}
- Since QRandomGenerator64 attempts to use a hardware Random Number Generator,
- this function always returns 0.0.
- */
+QRandomGenerator64 *QRandomGenerator64::global()
+{
+ auto self = SystemAndGlobalGenerators::globalNoInit();
-/*!
- \fn result_type QRandomGenerator64::min()
+ // 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;
- Returns the minimum value that QRandomGenerator64 may ever generate. That is, 0.
+ SystemAndGlobalGenerators::PRNGLocker locker(self);
+ if (self->type == SystemRNG)
+ SystemAndGlobalGenerators::securelySeed(self);
- \sa max(), QRandomGenerator::max()
- */
+ return self;
+}
-/*!
- \fn result_type QRandomGenerator64::max()
+QRandomGenerator64 QRandomGenerator64::securelySeeded()
+{
+ QRandomGenerator64 result(System{});
+ SystemAndGlobalGenerators::securelySeed(&result);
+ return result;
+}
- Returns the maximum value that QRandomGenerator64 may ever generate. That is,
- \c {std::numeric_limits<result_type>::max()}.
+/// \internal
+inline QRandomGenerator::QRandomGenerator(System)
+ : type(SystemRNG)
+{
+ // don't touch storage
+}
- \sa min(), QRandomGenerator::max()
- */
+QRandomGenerator::QRandomGenerator(const QRandomGenerator &other)
+ : type(other.type)
+{
+ Q_ASSERT(this != system());
+ Q_ASSERT(this != SystemAndGlobalGenerators::globalNoInit());
-/*!
- Generates one 32-bit random value and returns it.
+ if (type != SystemRNG) {
+ SystemAndGlobalGenerators::PRNGLocker lock(&other);
+ storage.engine() = other.storage.engine();
+ }
+}
- 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:
+QRandomGenerator &QRandomGenerator::operator=(const QRandomGenerator &other)
+{
+ if (Q_UNLIKELY(this == system()) || Q_UNLIKELY(this == SystemAndGlobalGenerators::globalNoInit()))
+ qFatal("Attempted to overwrite a QRandomGenerator to system() or global().");
- \code
- int value = QRandomGenerator::generate() & std::numeric_limits<int>::max();
- \endcode
+ if ((type = other.type) != SystemRNG) {
+ SystemAndGlobalGenerators::PRNGLocker lock(&other);
+ storage.engine() = other.storage.engine();
+ }
+ return *this;
+}
- \sa generate64(), generateDouble()
- */
-quint32 QRandomGenerator::generate()
+QRandomGenerator::QRandomGenerator(std::seed_seq &sseq) Q_DECL_NOTHROW
+ : type(MersenneTwister)
{
- quint32 ret;
- fill(&ret, &ret + 1);
- return ret;
+ Q_ASSERT(this != system());
+ Q_ASSERT(this != SystemAndGlobalGenerators::globalNoInit());
+
+ new (&storage.engine()) RandomEngine(sseq);
}
-/*!
- Generates one 64-bit random value and returns it.
+QRandomGenerator::QRandomGenerator(const quint32 *begin, const quint32 *end)
+ : type(MersenneTwister)
+{
+ Q_ASSERT(this != system());
+ Q_ASSERT(this != SystemAndGlobalGenerators::globalNoInit());
- 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:
+ std::seed_seq s(begin, end);
+ new (&storage.engine()) RandomEngine(s);
+}
- \code
- qint64 value = QRandomGenerator::generate64() & std::numeric_limits<qint64>::max();
- \endcode
+void QRandomGenerator::discard(unsigned long long z)
+{
+ if (Q_UNLIKELY(type == SystemRNG))
+ return;
- \sa generate(), generateDouble(), QRandomGenerator64
- */
-quint64 QRandomGenerator::generate64()
+ SystemAndGlobalGenerators::PRNGLocker lock(this);
+ storage.engine().discard(z);
+}
+
+bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
{
- quint64 ret;
- fill(&ret, &ret + 1);
- return ret;
+ 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)
+ using PRNGLocker = QRandomGenerator::SystemAndGlobalGenerators::PRNGLocker;
+ PRNGLocker locker(&rng1 == QRandomGenerator::global() ? &rng1 : &rng2);
+ return rng1.storage.engine() == rng2.storage.engine();
}
/*!
@@ -931,9 +1247,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<quint32 *>(buffer);
+ quint32 *end = static_cast<quint32 *>(bufferEnd);
+
+ if (type == SystemRNG || Q_UNLIKELY(uint(qt_randomdevice_control) & (UseSystemRNG|SetRandomData)))
+ return SystemGenerator::self().generate(begin, end);
+
+ SystemAndGlobalGenerators::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..bde64646a4 100644
--- a/src/corelib/global/qrandom.h
+++ b/src/corelib/global/qrandom.h
@@ -42,6 +42,7 @@
#include <QtCore/qglobal.h>
#include <algorithm> // for std::generate
+#include <random> // for std::mt19937
QT_BEGIN_NAMESPACE
@@ -51,19 +52,43 @@ class QRandomGenerator
template <typename UInt> using IfValidUInt =
typename std::enable_if<std::is_unsigned<UInt>::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 seedValue = 1)
+ : QRandomGenerator(&seedValue, 1)
+ {}
+ template <qssize_t N> 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);
+
+ 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;
+ 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 +102,161 @@ 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 <typename UInt, IfValidUInt<UInt> = 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 <typename UInt, size_t N, IfValidUInt<UInt> = 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 <typename ForwardIterator>
void generate(ForwardIterator begin, ForwardIterator end)
{
- auto generator = static_cast<quint32 (*)()>(&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; }
+ 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<result_type>::min)(); }
static Q_DECL_CONSTEXPR result_type max() { return (std::numeric_limits<result_type>::max)(); }
+ static inline Q_DECL_CONST_FUNCTION QRandomGenerator *system();
+ static inline Q_DECL_CONST_FUNCTION QRandomGenerator *global();
+ static inline QRandomGenerator securelySeeded();
+
+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 SystemGenerator;
+ struct SystemAndGlobalGenerators;
+ typedef std::mt19937 RandomEngine;
+
+ union Storage {
+ uint dummy;
+#ifdef Q_COMPILER_UNRESTRICTED_UNIONS
+ RandomEngine twister;
+ RandomEngine &engine() { return twister; }
+ const RandomEngine &engine() const { return twister; }
+#else
+ std::aligned_storage<sizeof(RandomEngine), Q_ALIGNOF(RandomEngine)>::type buffer;
+ RandomEngine &engine() { return reinterpret_cast<RandomEngine &>(buffer); }
+ const RandomEngine &engine() const { return reinterpret_cast<const RandomEngine &>(buffer); }
+#endif
+
+ Q_STATIC_ASSERT_X(std::is_trivially_destructible<RandomEngine>::value,
+ "std::mersenne_twister not trivially destructible as expected");
+ Q_DECL_CONSTEXPR Storage();
+ };
+ uint type;
+ Storage storage;
};
-class QRandomGenerator64
+class QRandomGenerator64 : public QRandomGenerator
{
+ QRandomGenerator64(System);
public:
- static QRandomGenerator64 system() { return {}; }
- static QRandomGenerator64 global() { return {}; }
- QRandomGenerator64() = default;
+ // unshadow generate() overloads, since we'll override.
+ using QRandomGenerator::generate;
+ quint64 generate() { return generate64(); }
- static quint64 generate() { return QRandomGenerator::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 seedValue = 1)
+ : QRandomGenerator(seedValue)
+ {}
+ template <qssize_t N> 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) {}
+
+ 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<result_type>::min)(); }
static Q_DECL_CONSTEXPR result_type max() { return (std::numeric_limits<result_type>::max)(); }
+ 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
};
+inline QRandomGenerator *QRandomGenerator::system()
+{
+ return QRandomGenerator64::system();
+}
+
+inline QRandomGenerator *QRandomGenerator::global()
+{
+ return QRandomGenerator64::global();
+}
+
+QRandomGenerator QRandomGenerator::securelySeeded()
+{
+ return QRandomGenerator64::securelySeeded();
+}
QT_END_NAMESPACE
diff --git a/src/corelib/global/qrandom_p.h b/src/corelib/global/qrandom_p.h
index 6ac2904e1b..917a91098e 100644
--- a/src/corelib/global/qrandom_p.h
+++ b/src/corelib/global/qrandom_p.h
@@ -52,11 +52,12 @@
//
#include "qglobal_p.h"
+#include <private/qsimd_p.h>
QT_BEGIN_NAMESPACE
enum QRandomGeneratorControl {
- SkipMemfill = 1,
+ UseSystemRNG = 1,
SkipSystemRNG = 2,
SkipHWRNG = 4,
SetRandomData = 8,
@@ -65,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<uint> qt_randomdevice_control = Q_BASIC_ATOMIC_INITIALIZER(0U);
#elif defined(QT_BUILD_INTERNAL)
@@ -73,6 +79,16 @@ extern Q_CORE_EXPORT QBasicAtomicInteger<uint> 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/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<QEventDispatcherWin32 *>(QCoreApplication::eventDispatcher());
+ QEventDispatcherWin32 *winEventDispatcher = static_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance());
re.devNotify = RegisterDeviceNotification(winEventDispatcher->internalHwnd(),
&notify, 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",
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;
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 <qdir.h>
#include <qelapsedtimer.h>
#include <qfileinfo.h>
+#include <qrandom.h>
#include <qregexp.h>
#include <qwineventnotifier.h>
#include <private/qsystemlibrary_p.h>
@@ -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/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;
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/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())
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
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index ded9ad354e..501f0d345f 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -339,6 +339,7 @@ static void qt_initialize_qhash_seed()
*/
int qGlobalQHashSeed()
{
+ qt_initialize_qhash_seed();
return qt_qhash_seed.load();
}
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index 4c6f08c774..25340f2d02 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -652,32 +652,6 @@ Q_CORE_EXPORT QBasicAtomicInteger<unsigned> qt_cpu_features[2] = { Q_BASIC_ATOMI
void qDetectCpuFeatures()
{
-#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL)
-# if Q_CC_GNU < 403
- // GCC 4.2 (at least the one that comes with Apple's XCode, on Mac) is
- // known to be broken beyond repair in dealing with the inline assembly
- // above. It will generate bad code that could corrupt important registers
- // like the PIC register. The behaviour of code after this function would
- // be totally unpredictable.
- //
- // For that reason, simply forego the CPUID check at all and return the set
- // of features that we found at compile time, through the #defines from the
- // compiler. This should at least allow code to execute, even if none of
- // the specialized code found in Qt GUI and elsewhere will ever be enabled
- // (it's the user's fault for using a broken compiler).
- //
- // This also disables the runtime checking that the processor actually
- // contains all the features that the code required. Qt 4 ran for years
- // like that, so it shouldn't be a problem.
-
- qt_cpu_features[0].store(minFeature | quint32(QSimdInitialized));
-#ifndef Q_ATOMIC_INT64_IS_SUPPORTED
- qt_cpu_features[1].store(minFeature >> 32);
-#endif
-
- return;
-# endif
-#endif
quint64 f = detectProcessorFeatures();
QByteArray disable = qgetenv("QT_NO_CPU_FEATURE");
if (!disable.isEmpty()) {
diff --git a/src/corelib/tools/qversionnumber.cpp b/src/corelib/tools/qversionnumber.cpp
index 0f237bce87..b96e48252e 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()
*/
@@ -409,7 +409,7 @@ QString QVersionNumber::toString() const
#if QT_STRINGVIEW_LEVEL < 2
/*!
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
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 <qpainter.h>
#include <qimage.h>
+#include <qrandom.h>
#include <qscreen.h>
#include <private/qguiapplication_p.h>
@@ -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/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;
}
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 406fcdd226..6298dd5f45 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;
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 369f3ea3ab..fea55e459d 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -55,6 +55,7 @@
# include "qaccessible.h"
#endif
#include "qhighdpiscaling_p.h"
+#include "qshapedpixmapdndwindow_p.h"
#include <private/qevent_p.h>
@@ -379,7 +380,9 @@ void QWindowPrivate::setVisible(bool visible)
QGuiApplicationPrivate::showModalWindow(q);
else
QGuiApplicationPrivate::hideModalWindow(q);
- } 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<QShapedPixmapWindow *>(q)) {
QGuiApplicationPrivate::updateBlockedStatus(q);
}
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 <private/qopenglcontext_p.h>
#include <private/qrgba64_p.h>
#include <QtCore/qmutex.h>
+#include <QtCore/qrandom.h>
#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/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;
}
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 <qdebug.h>
#include <qbitmap.h>
#include <qmath.h>
+#include <qrandom.h>
// #include <private/qdatabuffer_p.h>
// #include <private/qpainter_p.h>
@@ -4229,7 +4230,7 @@ protected:
QSharedPointer<const CacheInfo> 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<CacheInfo>::create(gradient.stops(), opacity, gradient.interpolationMode());
generateGradientColorTable(gradient, cache_entry->buffer64, paletteSize(), opacity);
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/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index f0a5053196..438cd3de3a 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()
*/
diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp
index 4b330c491a..42f1343c52 100644
--- a/src/network/access/qhttp2protocolhandler.cpp
+++ b/src/network/access/qhttp2protocolhandler.cpp
@@ -1103,7 +1103,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)));
}
}
diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri
index 54b61f3ad3..b822a70e88 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 \
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 <qcoreapplication.h>
#include <qdatetime.h>
-#include <qthreadstorage.h>
+#include <qrandom.h>
#include <qurl.h>
#include <algorithm>
@@ -50,7 +50,6 @@
QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QDnsLookupThreadPool, theDnsLookupThreadPool);
-Q_GLOBAL_STATIC(QThreadStorage<bool *>, theDnsLookupSeedStorage);
static bool qt_qdnsmailexchangerecord_less_than(const QDnsMailExchangeRecord &r1, const QDnsMailExchangeRecord &r2)
{
@@ -85,7 +84,7 @@ static void qt_qdnsmailexchangerecord_sort(QList<QDnsMailExchangeRecord> &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<QDnsServiceRecord> &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<quintptr>(this));
- theDnsLookupSeedStorage()->setLocalData(new bool(true));
- }
qt_qdnsmailexchangerecord_sort(reply.mailExchangeRecords);
qt_qdnsservicerecord_sort(reply.serviceRecords);
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index 7556bb98f4..bd368ac42f 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;
@@ -1255,26 +1255,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<in6_pktinfo *>(WSA_CMSG_DATA(cmsgptr));
- QHostAddress target(reinterpret_cast<quint8 *>(&info->ipi6_addr));
- if (info->ipi6_ifindex)
- target.setScopeId(QString::number(info->ipi6_ifindex));
+
+ header->destinationAddress.setAddress(reinterpret_cast<quint8 *>(&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<in_pktinfo *>(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/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 <private/qdrawhelper_p.h>
#include <private/qgl_p.h>
#include <QtCore/qmutex.h>
+#include <QtCore/qrandom.h>
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/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
index 4a197fd6ef..73def00017 100644
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
+++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
@@ -1771,15 +1771,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;
}
@@ -1873,7 +1883,7 @@ glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs)
unlockFace();
if (isScalableBitmap())
- overall = scaledBitmapMetrics(overall);
+ overall = scaledBitmapMetrics(overall, QTransform());
return overall;
}
@@ -1912,7 +1922,7 @@ glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph)
unlockFace();
if (isScalableBitmap())
- overall = scaledBitmapMetrics(overall);
+ overall = scaledBitmapMetrics(overall, QTransform());
return overall;
}
@@ -1950,7 +1960,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;
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 &paramList)
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
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h
index 484f185fc0..5081fc78c6 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.h
+++ b/src/plugins/platforms/cocoa/qcocoamenu.h
@@ -93,6 +93,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 eeb4c01791..a54284dbae 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<QCocoaMenuItem *>(menuItem);
if (!m_menuItems.contains(cocoaItem)) {
@@ -443,8 +448,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) {
@@ -462,6 +468,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<QCocoaMenuItem*> 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();
@@ -183,11 +183,16 @@ 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<QCocoaMenu *>(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/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index 606f1ed215..eaf310ec51 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -149,10 +149,6 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
QMacAutoReleasePool pool;
m_menu = static_cast<QCocoaMenu *>(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 {
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index af44564968..d1f19f2de9 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -1442,6 +1442,21 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
applyContentBorderThickness(nsWindow);
+ // 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) {
+ [nsWindow setDynamicDepthLimit:NO];
+ [nsWindow setDepthLimit:NSWindowDepthTwentyfourBitRGB];
+ }
+
return nsWindow;
}
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 9708aa4ce6..28ffcf8718 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -1884,6 +1884,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];
}
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 <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatforminputcontextfactory_p.h>
#include <qpa/qplatforminputcontext.h>
+#include <qpa/qplatformtheme.h>
#include <qpa/qplatformservices.h>
@@ -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:
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 26779f0c01..e713debf5b 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -992,7 +992,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;
@@ -1201,6 +1203,8 @@ void QWindowsNativeFileDialogBase::onSelectionChange()
{
const QList<QUrl> current = selectedFiles();
m_data.setSelectedFiles(current);
+ qDebug() << __FUNCTION__ << current << current.size();
+
if (current.size() == 1)
emit currentChanged(current.front());
}
@@ -1397,7 +1401,7 @@ QList<QUrl> 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;
diff --git a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp
index 3ee591de8c..901d132ea5 100644
--- a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp
+++ b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp
@@ -354,7 +354,7 @@ HICON QWindowsSystemTrayIcon::createIcon(const QIcon &icon)
m_hIcon = nullptr;
if (icon.isNull())
return oldIcon;
- const QSize requestedSize(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
+ 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())
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 58e99ef3de..f90f189146 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -249,7 +249,7 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting)
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");
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/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp
index a3aa0f6593..0f4b7a80af 100644
--- a/src/plugins/sqldrivers/psql/qsql_psql.cpp
+++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp
@@ -181,13 +181,14 @@ public:
QPSQLDriver::Protocol getPSQLVersion();
bool setEncodingUtf8();
void setDatestyle();
+ void setByteaOutput();
void detectBackslashEscape();
};
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 +526,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())
@@ -698,11 +699,25 @@ 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
// 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;
@@ -724,11 +739,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;
}
@@ -738,76 +753,102 @@ 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::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_3) {
qWarning("This version of PostgreSQL is not supported and may not work.");
}
@@ -857,7 +898,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:
@@ -866,7 +907,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;
}
@@ -929,6 +970,7 @@ bool QPSQLDriver::open(const QString & db,
d->detectBackslashEscape();
d->isUtf8 = d->setEncodingUtf8();
d->setDatestyle();
+ d->setByteaOutput();
setOpen(true);
setOpenError(false);
@@ -993,12 +1035,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;
}
@@ -1085,8 +1122,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' "
@@ -1095,9 +1131,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' "
@@ -1106,15 +1140,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 "
@@ -1129,10 +1155,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));
@@ -1166,8 +1190,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 "
@@ -1175,8 +1198,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 "
@@ -1184,8 +1206,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 "
@@ -1196,15 +1217,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 "
@@ -1222,15 +1235,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);
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index b24ecee102..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
@@ -569,7 +572,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 +624,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<QRegion *>(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 &region)
-{
- 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 +1479,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<QMacStyle *>(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
@@ -1537,6 +1486,7 @@ bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOpti
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;
@@ -1550,6 +1500,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)
@@ -1579,21 +1531,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
@@ -1601,12 +1561,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;
}
@@ -1616,51 +1580,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;
@@ -1704,11 +1671,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;
@@ -1751,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)
{
@@ -1849,36 +1753,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 +1818,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 +1833,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 +1895,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<NSProgressIndicator *>(bv);
- pi.indeterminate = (widget.first == QCocoaIndeterminateProgressIndicator);
+ pi.indeterminate = (widget.first == ProgressIndicator_Indeterminate);
switch (widget.second) {
case QStyleHelper::SizeSmall:
pi.controlSize = NSSmallControlSize;
@@ -2013,15 +1917,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 +1953,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);
@@ -2094,12 +1998,12 @@ void QMacStylePrivate::drawNSViewInRect(QCocoaWidget widget, NSView *view, const
restoreNSGraphicsContext(ctx);
}
-void QMacStylePrivate::resolveCurrentNSView(QWindow *window)
+void QMacStylePrivate::resolveCurrentNSView(QWindow *window) const
{
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,
@@ -2147,7 +2051,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);
@@ -2162,7 +2066,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;
@@ -3131,7 +3035,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<QMacStylePrivate *>(d)->resolveCurrentNSView(window);
+ d->resolveCurrentNSView(window);
switch (pe) {
case PE_IndicatorArrowUp:
case PE_IndicatorArrowDown:
@@ -3139,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<const QToolButton *>(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;
@@ -3157,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)
@@ -3211,7 +3127,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<NSBox *>(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);
@@ -3386,10 +3302,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.
@@ -3397,7 +3314,8 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
case PE_IndicatorBranch: {
if (!(opt->state & State_Children))
break;
- NSButtonCell *triangleCell = static_cast<NSButtonCell *>(d->cocoaCell(QCocoaWidget(QCocoaDisclosureButton, QStyleHelper::SizeLarge)));
+ const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Button_Disclosure, QStyleHelper::SizeLarge);
+ NSButtonCell *triangleCell = static_cast<NSButtonCell *>(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];
@@ -3627,70 +3545,15 @@ 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<QMacStylePrivate *>(d)->resolveCurrentNSView(window);
+ d->resolveCurrentNSView(window);
switch (ce) {
case CE_HeaderSection:
if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(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)
@@ -3698,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<const QStyleOptionHeader *>(opt)) {
@@ -3820,12 +3693,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:
@@ -3883,9 +3755,10 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
newRect.size.width -= QMacStylePrivate::PushButtonRightOffset - 4;
}
+ QMacStylePrivate::CocoaControl cw = QMacStylePrivate::cocoaControlFromHIThemeButtonKind(bdi.kind);
+ if (hasMenu)
+ cw.first = QMacStylePrivate::Button_PullDown;
if (hasMenu && bdi.kind != kThemeBevelButton) {
- QCocoaWidget cw = cocoaWidgetFromHIThemeButtonKind(bdi.kind);
- cw.first = QCocoaPullDownButton;
NSPopUpButton *pdb = (NSPopUpButton *)d->cocoaControl(cw);
[pdb highlight:(bdi.state == kThemeStatePressed)];
pdb.enabled = bdi.state != kThemeStateUnavailable && bdi.state != kThemeStateUnavailableInactive;
@@ -3893,7 +3766,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);
@@ -4451,7 +4324,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
const QProgressStyleAnimation *animation = qobject_cast<QProgressStyleAnimation*>(d->animation(opt->styleObject));
QIndeterminateProgressIndicator *ipi = nil;
if (isIndeterminate || animation)
- ipi = static_cast<QIndeterminateProgressIndicator *>(d->cocoaControl({ QCocoaIndeterminateProgressIndicator, aquaSize }));
+ ipi = static_cast<QIndeterminateProgressIndicator *>(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 +4351,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<NSProgressIndicator *>(d->cocoaControl(cw));
d->drawNSViewInRect(cw, pi, rect, p, w != nullptr, ^(CGContextRef ctx, const CGRect &rect) {
d->setupVerticalInvertedXform(ctx, reverse, vertical, rect);
@@ -4691,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;
@@ -5159,7 +5049,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<QMacStylePrivate *>(d)->resolveCurrentNSView(window);
+ d->resolveCurrentNSView(window);
switch (cc) {
case CC_ScrollBar:
if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
@@ -5265,7 +5155,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<NSScroller *>(d->cocoaControl(cw));
if (isTransient) {
@@ -5347,8 +5238,9 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
case CC_Slider:
if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(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<NSSlider *>(d->cocoaControl(cw));
if (!setupSlider(slider, sl))
break;
@@ -5483,7 +5375,8 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
d->setupNSGraphicsContext(cg, NO);
const auto aquaSize = d->effectiveAquaSizeConstrain(opt, widget);
- NSStepperCell *cell = static_cast<NSStepperCell *>(d->cocoaCell(QCocoaWidget(QCocoaStepper, aquaSize)));
+ const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Stepper, aquaSize);
+ NSStepperCell *cell = static_cast<NSStepperCell *>(d->cocoaCell(cw));
cell.enabled = (sb->state & State_Enabled);
const CGRect newRect = [cell drawingRectForBounds:updown.toCGRect()];
@@ -5511,19 +5404,20 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
case CC_ComboBox:
if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(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) {
- 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);
} else
- d->drawColorlessButton(rect, &bdi, p, opt);
+ d->drawColorlessButton(rect, &bdi, cw, p, opt);
}
break;
case CC_TitleBar:
@@ -5703,7 +5597,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:
@@ -5786,7 +5682,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)
@@ -5822,8 +5717,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<NSSlider *>(d->cocoaControl(cw));
if (!setupSlider(slider, sl))
break;
@@ -5848,9 +5744,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<NSScroller *>(d->cocoaControl(cw));
if (!setupScroller(scroller, sb)) {
sc = SC_None;
@@ -5956,8 +5853,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<NSScroller *>(d->cocoaControl(cw));
if (setupScroller(scroller, sb))
ret = QRectF::fromCGRect([scroller rectForPart:part]).toRect();
@@ -5968,8 +5866,9 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op
if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(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<NSSlider *>(d->cocoaControl(cw));
if (!setupSlider(slider, sl))
break;
@@ -6063,7 +5962,8 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op
case CC_ComboBox:
if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(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:{
@@ -6078,7 +5978,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),
@@ -6230,7 +6130,8 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op
Q_UNREACHABLE();
}
- NSStepperCell *cell = static_cast<NSStepperCell *>(d->cocoaCell(QCocoaWidget(QCocoaStepper, aquaSize)));
+ const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Stepper, aquaSize);
+ NSStepperCell *cell = static_cast<NSStepperCell *>(d->cocoaCell(cw));
const CGRect outRect = [cell drawingRectForBounds:ret.toCGRect()];
ret = QRectF::fromCGRect(outRect).toRect();
@@ -6554,20 +6455,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<const QStyleOptionComboBox *>(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){
@@ -6808,16 +6699,4 @@ int QMacStyle::layoutSpacing(QSizePolicy::ControlType control1,
return_SIZE(10, 8, 6); // guess
}
-/*
-FontHash::FontHash()
-{
- QHash<QByteArray, QFont>::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 528edfcda1..078509d551 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<QCocoaWidgetKind, QStyleHelper::WidgetSizePolicy> QCocoaWidget;
-
-typedef void (^QCocoaDrawRectBlock)(CGContextRef, const CGRect &);
-
#define SIZE(large, small, mini) \
(controlSize == QStyleHelper::SizeLarge ? (large) : controlSize == QStyleHelper::SizeSmall ? (small) : (mini))
@@ -199,14 +177,32 @@ typedef void (^QCocoaDrawRectBlock)(CGContextRef, const CGRect &);
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)
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<CocoaControlType, QStyleHelper::WidgetSizePolicy> CocoaControl;
+
+ typedef void (^DrawRectBlock)(CGContextRef, const CGRect &);
+
QMacStylePrivate();
~QMacStylePrivate();
@@ -235,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;
@@ -243,15 +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 drawTableHeader(const CGRect &outerBounds, bool drawTopBorder, bool drawLeftBorder,
- const HIThemeButtonDrawInfo &bdi, QPainter *p);
+ static void drawCombobox(const CGRect &outerBounds, const HIThemeButtonDrawInfo &bdi, const CocoaControl &cw, QPainter *p);
bool contentFitsInPushButton(const QStyleOptionButton *btn, HIThemeButtonDrawInfo *bdi,
ThemeButtonKind buttonKindToCheck) const;
void initHIThemePushButton(const QStyleOptionButton *btn, const QWidget *widget,
@@ -260,16 +256,18 @@ 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 resolveCurrentNSView(QWindow *window);
+ void drawNSViewInRect(CocoaControl widget, NSView *view, const QRect &rect, QPainter *p, bool isQWidget = true, DrawRectBlock drawRectBlock = nil) const;
+ void resolveCurrentNSView(QWindow *window) const;
void drawFocusRing(QPainter *p, const QRect &targetRect, int hMargin, int vMargin, qreal radius = 0) const;
@@ -283,9 +281,9 @@ public:
mutable QPointer<QFocusFrame> focusWidget;
QT_MANGLE_NAMESPACE(NotificationReceiver) *receiver;
- NSView *backingStoreNSView;
- mutable QHash<QCocoaWidget, NSView *> cocoaControls;
- mutable QHash<QCocoaWidget, NSCell *> cocoaCells;
+ mutable NSView *backingStoreNSView;
+ mutable QHash<CocoaControl, NSView *> cocoaControls;
+ mutable QHash<CocoaControl, NSCell *> cocoaCells;
QFont smallSystemFont;
QFont miniSystemFont;
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 <QtCore/QFile>
+#include <QtCore/QString>
+#include <QtCore/QChar>
+#include <QtCore/QPoint>
+
+#ifdef QT_GUI_LIB
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
+#endif
+
+#ifdef QT_WIDGETS_LIB
+#include <QtWidgets/QWidget>
+#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/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index d6db7deee7..463ed7e58c 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -3376,7 +3376,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),
@@ -3551,6 +3551,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);
@@ -3593,6 +3595,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);
@@ -3607,6 +3611,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);
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index 0efee755a2..7f027595b7 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -2873,10 +2873,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);
+ }
}
}
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/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 3369548f18..2ee9d307c9 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -1374,6 +1374,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();
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/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index d97fedadab..00ee0a9d10 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -545,6 +545,7 @@ void QMainWindow::setMenuBar(QMenuBar *menuBar)
menuBar->setCornerWidget(cornerWidget, Qt::TopRightCorner);
}
oldMenuBar->hide();
+ oldMenuBar->setParent(nullptr);
oldMenuBar->deleteLater();
}
topLayout->setMenuBar(menuBar);
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index ded218de73..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<QAction*> actions = q->actions();
for (QList<QAction*>::const_reverse_iterator it = actions.rbegin(), end = actions.rend(); it != end; ++it) {
- QPlatformMenuItem *menuItem = platformMenu->createMenuItem();
- QAction *action = *it;
- menuItem->setTag(reinterpret_cast<quintptr>(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<quintptr>(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);
@@ -2339,6 +2381,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
@@ -3477,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
*/
@@ -3567,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<quintptr>(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<quintptr>(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<quintptr>(e->action()));
d->platformMenu->removeMenuItem(menuItem);
@@ -3583,7 +3589,7 @@ void QMenu::actionEvent(QActionEvent *e)
} else if (e->type() == QEvent::ActionChanged) {
QPlatformMenuItem *menuItem = d->platformMenu->menuItemForTag(reinterpret_cast<quintptr>(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 5869bc8420..ce5134958e 100644
--- a/src/widgets/widgets/qmenu_p.h
+++ b/src/widgets/widgets/qmenu_p.h
@@ -91,19 +91,10 @@ class QMenuSloppyState
Q_DISABLE_COPY(QMenuSloppyState)
public:
QMenuSloppyState()
- : m_menu(Q_NULLPTR)
- , m_enabled(false)
+ : 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(); }
@@ -252,44 +243,46 @@ public:
QMenu *subMenu() const { return m_sub_menu; }
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;
+ QMenu *m_menu = nullptr;
+ QAction *m_reset_action = nullptr;
+ QAction *m_origin_action = nullptr;
QRectF m_action_rect;
QPointF m_previous_point;
QPointer<QMenu> m_sub_menu;
- QMenuSloppyState *m_parent;
+ QMenuSloppyState *m_parent = nullptr;
+ QBasicTimer m_time;
+ 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;
+ 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),
-#ifdef QT_KEYPAD_NAVIGATION
- selectAction(0),
- cancelAction(0),
-#endif
- scroll(0), eventLoop(0), tearoff(0), tornoff(0), tearoffHighlighted(0),
- hasCheckableItems(0), doChildEffects(false), platformMenu(0),
- scrollUpTearOffItem(nullptr), scrollDownItem(nullptr)
+ QMenuPrivate() :
+ itemsDirty(false),
+ hasCheckableItems(false),
+ lastContextMenu(false),
+ collapsibleSeparators(true),
+ toolTipsVisible(false),
+ delayedPopupGuard(false),
+ hasReceievedEnter(false),
+ hasHadMouse(false),
+ aboutToHide(false),
+ tearoff(false),
+ tornoff(false),
+ tearoffHighlighted(false),
+ doChildEffects(false)
{ }
~QMenuPrivate()
@@ -302,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
@@ -312,8 +308,6 @@ public:
bool isContextMenu() const;
//item calculations
- mutable uint itemsDirty : 1;
- mutable uint maxIconWidth, tabWidth;
QRect actionRect(QAction *) const;
mutable QVector<QRect> actionRects;
@@ -322,31 +316,19 @@ 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;
+
+ 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)
{
@@ -366,9 +348,9 @@ public:
timer.stop();
}
- QMenu *parent;
+ QMenu *parent = nullptr;
+ QAction *action = nullptr;
QBasicTimer timer;
- QAction *action;
} delayState;
enum SelectionReason {
SelectedFromKeyboard,
@@ -385,19 +367,20 @@ public:
struct QMenuScroller {
enum ScrollLocation { ScrollStay, ScrollBottom, ScrollTop, ScrollCenter };
enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 };
- uint scrollFlags : 2, scrollDirection : 2;
- int scrollOffset;
+ int scrollOffset = 0;
QBasicTimer scrollTimer;
+ quint8 scrollFlags = ScrollNone;
+ quint8 scrollDirection = ScrollNone;
- QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { }
+ 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<QAction> syncAction;
//search buffer
@@ -423,18 +406,15 @@ public:
inline int indexOf(QAction *act) const { return q_func()->actions().indexOf(act); }
//tear off support
- uint tearoff : 1, tornoff : 1, tearoffHighlighted : 1;
QPointer<QTornOffMenu> tornPopup;
- mutable bool hasCheckableItems;
-
QMenuSloppyState sloppyState;
//default action
QPointer<QAction> defaultAction;
- QAction *menuAction;
- QAction *defaultMenuAction;
+ QAction *menuAction = nullptr;
+ QAction *defaultMenuAction = nullptr;
void setOverrideMenuAction(QAction *);
void _q_overrideMenuActionDestroyed();
@@ -452,9 +432,6 @@ public:
void adjustMenuScreen(const QPoint &p);
void updateLayoutDirection();
- //menu fading/scrolling effects
- bool doChildEffects;
-
QPointer<QPlatformMenu> platformMenu;
QPointer<QAction> actionAboutToTrigger;
@@ -473,12 +450,38 @@ 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 = 0;
+ mutable uint tabWidth = 0;
+ int motions = 0;
+ int mousePopupDelay = 0;
+
+ bool activationRecursionGuard = false;
+
+ mutable quint8 ncols = 0; // "255cols ought to be enough for anybody."
+
+ mutable bool itemsDirty : 1;
+ mutable bool hasCheckableItems : 1;
+ bool lastContextMenu : 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
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index cc6f39c439..ece2a0a9c9 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -1188,7 +1188,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;
@@ -1203,6 +1203,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<QAction *>(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<quintptr>(action);
+ if (menu->tag() != tag)
+ menu->setTag(tag);
+ menu->setText(action->text());
+ menu->setVisible(action->isVisible());
+ menu->setEnabled(action->isEnabled());
+}
+
/*!
\reimp
*/
@@ -1219,16 +1242,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<quintptr>(e->action()));
- menu->setText(e->action()->text());
+ QPlatformMenu *beforeMenu = d->findInsertionPlatformMenu(e->action());
d->platformMenuBar->insertMenu(menu, beforeMenu);
}
} else if (e->type() == QEvent::ActionRemoved) {
@@ -1236,7 +1252,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<quintptr>(e->action()));
+ QPlatformMenu *cur = d->platformMenuBar->menuForTag(reinterpret_cast<quintptr>(e->action()));
QPlatformMenu *menu = d->getPlatformMenu(e->action());
// the menu associated with the action can change, need to
@@ -1245,21 +1261,13 @@ void QMenuBar::actionEvent(QActionEvent *e)
if (cur)
d->platformMenuBar->removeMenu(cur);
if (menu) {
- menu->setTag(reinterpret_cast<quintptr>(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); }
};
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
}
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/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
diff --git a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp
index 4b38d46317..220ec9a2f8 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<bool>(statement), #statement, "1st try", __FILE__, __LINE__))\
- if (!QTest::qVerify(static_cast<bool>(statement), #statement, "2nd try", __FILE__, __LINE__))\
+ if (!static_cast<bool>(statement))\
+ if (!static_cast<bool>(statement))\
if (!QTest::qVerify(static_cast<bool>(statement), #statement, "3rd try", __FILE__, __LINE__))\
return;\
} while (0)
@@ -71,6 +71,15 @@ public slots:
void cleanup() { setRNGControl(0); }
private slots:
+ void basics();
+ void knownSequence();
+ void discard();
+ void copying();
+ void copyingGlobal();
+ void copyingSystem();
+ void systemRng();
+ void securelySeeding();
+
void generate32_data();
void generate32();
void generate64_data() { generate32_data(); }
@@ -110,19 +119,212 @@ 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);
+
+ rng = QRandomGenerator64::securelySeeded();
+ rng64 = QRandomGenerator::securelySeeded();
+
+ // 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<decltype(rng64.generate()) COMMA quint64>::value);
+ Q_STATIC_ASSERT(std::is_same<decltype(system64->generate()) COMMA quint64>::value);
+}
+
+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()
+{
+ QRandomGenerator &system = *QRandomGenerator::system();
+ 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()
+{
+ 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<int>::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::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<uint>("control");
- QTest::newRow("default") << 0U;
+ QTest::newRow("fixed") << (RandomValue32 & RandomDataMask);
+ QTest::newRow("global") << 0U;
#ifdef QT_BUILD_INTERNAL
- QTest::newRow("direct") << uint(SkipMemfill);
- 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
}
@@ -130,39 +332,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<quint32>::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()
@@ -191,7 +394,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));
@@ -200,7 +405,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<quint8 *>(buffer);
quint8 *end = ptr + sizeof(buffer);
@@ -225,20 +430,20 @@ void tst_QRandomGenerator::quality()
template <typename T> 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];
}());
}
@@ -246,18 +451,18 @@ template <typename T> 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;
@@ -274,11 +479,11 @@ void tst_QRandomGenerator::fillRangeULLong() { fillRange_template<qulonglong>();
template <typename T> 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
@@ -287,10 +492,10 @@ template <typename T> 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<quint32>::max();
}) == end(array);
@@ -304,12 +509,12 @@ void tst_QRandomGenerator::generateULLong() { generate_template<qulonglong>(); }
void tst_QRandomGenerator::generateNonContiguous()
{
QFETCH(uint, control);
- setRNGControl(control);
+ RandomGenerator rng(control);
QLinkedList<quint64> 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<quint32>::max();
}) == list.end();
@@ -327,7 +532,7 @@ void tst_QRandomGenerator::bounded_data()
QTest::addColumn<quint32>("sup");
QTest::addColumn<quint32>("expected");
- auto newRow = [](quint32 val, quint32 sup) {
+ auto newRow = [&](quint32 val, quint32 sup) {
// calculate the scaled value
quint64 scaled = val;
scaled <<= 32;
@@ -353,31 +558,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);
}
@@ -408,7 +613,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));
@@ -416,7 +623,7 @@ void tst_QRandomGenerator::boundedQuality()
{
// test the quality of the generator
QVector<quint32> 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);
@@ -442,24 +649,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,
@@ -475,7 +684,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;
@@ -504,12 +713,22 @@ void tst_QRandomGenerator::qualityReal()
template <typename Engine> 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()
@@ -534,12 +753,16 @@ void tst_QRandomGenerator::stdUniformIntDistribution_data()
QTest::addColumn<uint>("control");
QTest::addColumn<quint32>("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:
@@ -554,7 +777,7 @@ void tst_QRandomGenerator::stdUniformIntDistribution()
{
QFETCH(uint, control);
QFETCH(quint32, max);
- setRNGControl(control & (SkipHWRNG|SkipSystemRNG));
+ RandomGenerator rng(control);
{
QRandomGenerator rd;
@@ -622,21 +845,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<qreal COMMA 32>(rd);
+ QVERIFY_3TIMES([&] {
+ qreal value = std::generate_canonical<qreal COMMA 32>(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<qreal COMMA 32>(rd) !=
- std::generate_canonical<qreal COMMA 32>(rd));
+ QVERIFY_3TIMES(std::generate_canonical<qreal COMMA 32>(rng) !=
+ std::generate_canonical<qreal COMMA 32>(rng));
#endif
}
@@ -650,12 +871,16 @@ void tst_QRandomGenerator::stdUniformRealDistribution_data()
QTest::addColumn<double>("min");
QTest::addColumn<double>("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
@@ -671,7 +896,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;
@@ -696,13 +921,9 @@ void tst_QRandomGenerator::stdUniformRealDistribution()
}
}
-void tst_QRandomGenerator::stdRandomDistributions()
+template <typename Generator> 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);
@@ -724,6 +945,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<QRandomGenerator>();
+ stdRandomDistributions_template<QRandomGenerator64>();
+}
+
QTEST_APPLESS_MAIN(tst_QRandomGenerator)
#include "tst_qrandomgenerator.moc"
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 <QtAlgorithms>
#include <QFile>
#include <QFileInfo>
+#include <QRandomGenerator>
#include <qplatformdefs.h>
#include <QDebug>
@@ -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/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp
index 9026864b12..c173a87a41 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));
}
}
@@ -443,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");
@@ -457,15 +457,19 @@ 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());
+ 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());
@@ -2189,12 +2193,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<QTemporaryDir> m_dataDir;
+#endif
};
#endif
@@ -2203,6 +2215,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());
}
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
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 fcd9133099..76462be376 100644
--- a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
+++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
@@ -35,6 +35,7 @@
#include <qdir.h>
#include <qset.h>
#include <qtextcodec.h>
+#include <QtTest/private/qtesthelpers_p.h>
#ifdef Q_OS_WIN
# include <windows.h>
#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;
@@ -159,7 +150,7 @@ void tst_QTemporaryDir::fileTemplate_data()
QTest::newRow("4Xsuffix") << "qt_XXXXXX_XXXX" << "qt_" << "_XXXX";
QTest::newRow("4Xprefix") << "qt_XXXX" << "qt_XXXX" << "";
QTest::newRow("5Xprefix") << "qt_XXXXX" << "qt_XXXXX" << "";
- 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 11c24ca86f..f3ce902bbd 100644
--- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
+++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
@@ -38,6 +38,8 @@
#include <qset.h>
#include <qtextcodec.h>
+#include <QtTest/private/qtesthelpers_p.h>
+
#if defined(Q_OS_WIN)
# include <windows.h>
#endif
@@ -143,16 +145,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;
@@ -201,7 +193,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();
@@ -824,7 +816,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<unicode>") << QString() << unicode << true;
QTest::newRow("<unicode>XXXXXX") << unicode << QString() << true;
QTest::newRow("<unicode>XXXXXX<unicode>") << unicode << unicode << true;
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 <qresultstore.h>
#include <qthreadpool.h>
#include <qexception.h>
+#include <qrandom.h>
#include <private/qfutureinterface_p.h>
// 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 <qalgorithms.h>
#include <QStringList>
#include <QString>
+#include <QRandomGenerator>
#include <QVector>
#define Q_TEST_PERFORMANCE 0
@@ -133,7 +134,7 @@ QVector<DataType> generateData(QString dataSetType, const int length)
QVector<DataType> 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<ThreadData> 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 <qimagereader.h>
#include <qlist.h>
#include <qmatrix.h>
+#include <qrandom.h>
#include <stdio.h>
#include <qpainter.h>
@@ -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 <qdesktopwidget.h>
#endif
#include <qpixmap.h>
+#include <qrandom.h>
#include <private/qdrawhelper_p.h>
#include <qpainter.h>
@@ -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 <qpolygon.h>
#include <qdebug.h>
#include <qpainter.h>
+#include <qrandom.h>
#include <math.h>
@@ -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<uchar> 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 <QtTest/QtTest>
#include <QtNetwork/QtNetwork>
#include <qnetworkdiskcache.h>
+#include <qrandom.h>
#include <algorithm>
@@ -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/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST
index 1d56c78bbc..d6fc717e37 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,33 @@ ubuntu-14.04
*
[backgroundRequestInterruption:ftp, bg, nobg]
*
+[getErrors:ftp-host]
+linux
+[getFromHttpIntoBuffer]
+windows
+[getFromHttpIntoBuffer2]
+windows
+[headFromHttp]
+windows
+[ioGetFromHttpWithSocksProxy]
+windows
+[ioPostToHttpFromSocket]
+windows
+[ioHttpRedirectMultipartPost]
+linux
+[ioHttpRedirectPolicy]
+b2qt 64bit
+linux
+[ioHttpRedirectPostPut]
+linux
+windows
+[putToFtp]
+windows ci
+[putWithServerClosingConnectionImmediately]
+windows
+[qtbug28035browserDoesNotLoadQtProjectOrgCorrectly]
+windows
+[getFromUnreachableIp]
+windows msvc-2017
+[ioHttpRedirectErrors:too-many-redirects]
+rhel-6.6 ci
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..fffe853c14 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -33,6 +33,7 @@
#include <QtCore/QUrl>
#include <QtCore/QEventLoop>
#include <QtCore/QFile>
+#include <QtCore/QRandomGenerator>
#include <QtCore/QSharedPointer>
#include <QtCore/QScopedPointer>
#include <QtCore/QTemporaryFile>
@@ -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() {
@@ -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);
@@ -4852,7 +4863,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 +4943,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());
@@ -6755,6 +6766,48 @@ void tst_QNetworkReply::getFromUnreachableIp()
{
QNetworkAccessManager manager;
+#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:
+ // 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_WIN
+
QNetworkRequest request(QUrl("http://255.255.255.255/42/23/narf/narf/narf"));
QNetworkReplyPtr reply(manager.get(request));
@@ -8748,7 +8801,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/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))
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 <QProcess>
#endif
+#include <QRandomGenerator>
#include <QStringList>
#include <QTcpServer>
#include <QTcpSocket>
@@ -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/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
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 <qstringlist.h>
#include "../../../network-settings.h"
+#include "emulationdetector.h"
#ifndef QT_NO_BEARERMANAGEMENT
#include <QtNetwork/qnetworkconfigmanager.h>
@@ -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);
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 <QtNetwork/QtNetwork>
#include <QtCore/QDateTime>
#include <QtCore/QTextStream>
+#include <QtCore/QRandomGenerator>
#include <QtCore/QStandardPaths>
#include <QtCore/private/qiodevice_p.h>
@@ -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<Chat>()
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 dc8de72b2a..29fbffa541 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 <QtTest/private/qtesthelpers_p.h>
+
+using namespace QTestPrivate;
static inline bool verifyChild(QWidget *child, QAccessibleInterface *interface,
int index, const QRect &domain)
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
diff --git a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp
index 8f8cfe009d..7bfa29ec8e 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 +
@@ -98,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();
}
@@ -212,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()
diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
index 92e4b580e7..3ea13896d8 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();
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 <qlineedit.h>
#include <qlayout.h>
#include <qmenu.h>
+#include <qrandom.h>
#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/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 2abb6e3515..2220ef8d2f 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -28,10 +28,12 @@
#include <QtTest/QtTest>
+#include <QtTest/private/qtesthelpers_p.h>
#include <private/qgraphicsitem_p.h>
#include <private/qgraphicsview_p.h>
#include <private/qgraphicsscene_p.h>
+#include <QRandomGenerator>
#include <QStyleOptionGraphicsItem>
#include <QAbstractTextDocumentLayout>
#include <QBitmap>
@@ -127,17 +129,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
@@ -3595,12 +3586,12 @@ void tst_QGraphicsItem::group()
QList<QGraphicsItem *> 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 +4134,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();
@@ -4211,7 +4202,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();
@@ -7137,7 +7128,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/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 ac38819385..f624bb6a5f 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 <QtTest/private/qtesthelpers_p.h>
+
+using namespace QTestPrivate;
+
Q_DECLARE_METATYPE(ExpectedValueDescription)
Q_DECLARE_METATYPE(QList<int>)
Q_DECLARE_METATYPE(QList<QRectF>)
@@ -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 dc488fffc0..1ac66ed5cb 100644
--- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
+++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
@@ -28,6 +28,7 @@
#include <QtTest/QtTest>
+#include <QtTest/private/qtesthelpers_p.h>
#include <qabstractitemview.h>
#include <qstandarditemmodel.h>
@@ -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 <QtTest/QtTest>
+#include <QtTest/private/qtesthelpers_p.h>
#include <qitemdelegate.h>
#include <qcolumnview.h>
#include <private/qcolumnviewgrip_p.h>
@@ -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/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);
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 <QtTest/QtTest>
#include <QtCore/QtCore>
#include "viewstotest.cpp"
-#include <stdlib.h>
-
-#if defined(Q_OS_UNIX) || defined(Q_OS_WIN)
-#include <time.h>
-#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/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 2403eabd04..5e0d99f25e 100644
--- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
+++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
@@ -46,6 +46,10 @@
#include <QtWidgets/QStyleFactory>
#include <QtWidgets/QVBoxLayout>
+#include <QtTest/private/qtesthelpers_p.h>
+
+using namespace QTestPrivate;
+
#if defined(Q_OS_WIN)
# include <windows.h>
# include <QtGui/QGuiApplication>
@@ -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 <algorithm>
+#include <QtTest/private/qtesthelpers_p.h>
+
+using namespace QTestPrivate;
+
#ifdef QT_BUILD_INTERNAL
#define VERIFY_SPANS_CONSISTENCY(TEST_VIEW_) \
QVERIFY(static_cast<QTableViewPrivate*>(QObjectPrivate::get(TEST_VIEW_))->spans.checkConsistency())
@@ -46,16 +50,6 @@ typedef QList<int> IntList;
typedef QList<bool> 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 895b61fc51..929b80ba15 100644
--- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
+++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
@@ -33,6 +33,10 @@
#include <QtWidgets/QtWidgets>
#include <private/qtreeview_p.h>
+#include <QtTest/private/qtesthelpers_p.h>
+
+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/qaction/tst_qaction.cpp b/tests/auto/widgets/kernel/qaction/tst_qaction.cpp
index 4b3db6bd9c..ac0174d19a 100644
--- a/tests/auto/widgets/kernel/qaction/tst_qaction.cpp
+++ b/tests/auto/widgets/kernel/qaction/tst_qaction.cpp
@@ -26,7 +26,8 @@
**
****************************************************************************/
-
+#include <QDialog>
+#include <QMainWindow>
#include <QtTest/QtTest>
#include <qapplication.h>
@@ -64,6 +65,8 @@ private slots:
void repeat();
void setData();
void keysequence(); // QTBUG-53381
+ void disableShortcutsWithBlockedWidgets_data();
+ void disableShortcutsWithBlockedWidgets();
private:
int m_lastEventType;
@@ -459,5 +462,52 @@ void tst_QAction::setData() // QTBUG-62006
QCOMPARE(spy.count(), 1);
}
+void tst_QAction::disableShortcutsWithBlockedWidgets_data()
+{
+ QTest::addColumn<Qt::ShortcutContext>("shortcutContext");
+ QTest::addColumn<Qt::WindowModality>("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"
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 bcdd103531..7262817d23 100644
--- a/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp
+++ b/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp
@@ -31,13 +31,9 @@
#include <QtGui>
#include <QtWidgets>
-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 <QtTest/private/qtesthelpers_p.h>
+
+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 <QStyleFactory>
#include <QSharedPointer>
+#include <QtTest/private/qtesthelpers_p.h>
+
+using namespace QTestPrivate;
+
#include <qformlayout.h>
// 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 <QStyleFactory>
#include <QSharedPointer>
-// 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 <QtTest/private/qtesthelpers_p.h>
+
+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 <QRadioButton>
#include <private/qlayoutengine_p.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);
-}
+#include <QtTest/private/qtesthelpers_p.h>
+
+using namespace QTestPrivate;
class tst_QLayout : public QObject
{
diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST
index 0b1d7b4437..4cef2d57a4 100644
--- a/tests/auto/widgets/kernel/qwidget/BLACKLIST
+++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST
@@ -81,3 +81,5 @@ ubuntu-14.04
osx
[activateWindow]
osx-10.12 ci
+[multipleToplevelFocusCheck]
+linux
diff --git a/tests/auto/widgets/kernel/qwidget/qwidget.pro b/tests/auto/widgets/kernel/qwidget/qwidget.pro
index 0e95d454cf..c1908af2a2 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 30fc927f7d..cf2794903e 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -50,6 +50,7 @@
#include <qcalendarwidget.h>
#include <qmainwindow.h>
#include <qdockwidget.h>
+#include <qrandom.h>
#include <qtoolbar.h>
#include <qtoolbutton.h>
#include <QtGui/qpaintengine.h>
@@ -72,6 +73,9 @@
#endif
#include <QtTest/QTest>
+#include <QtTest/private/qtesthelpers_p.h>
+
+using namespace QTestPrivate;
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
# include <QtCore/qt_windows.h>
@@ -108,22 +112,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)
{
@@ -5396,19 +5384,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<QWidget *>(&w1));
- QTest::qWait(50);
QTest::mouseDClick(&w1, Qt::LeftButton);
QTRY_COMPARE(QApplication::focusWidget(), static_cast<QWidget *>(w1.edit));
@@ -9826,7 +9817,7 @@ void tst_QWidget::grab()
for (int row = 0; row < image.height(); ++row) {
QRgb *line = reinterpret_cast<QRgb *>(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/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 f7e1ffc6ba..b76c4d35a8 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 <qtoolbar.h>
#include <private/qwindow_p.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);
-}
+#include <QtTest/private/qtesthelpers_p.h>
+
+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 <qmainwindow.h>
#include <qmenubar.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);
-}
+#include <QtTest/private/qtesthelpers_p.h>
+
+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 d5ef2fe94b..cd8ba95b06 100644
--- a/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp
+++ b/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp
@@ -60,15 +60,9 @@
#include <algorithm>
-// 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 <QtTest/private/qtesthelpers_p.h>
+
+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 <QMetaObject>
#include <private/qstylesheetstyle_p.h>
+#include <QtTest/private/qtesthelpers_p.h>
-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 <QList>
#include <QPointer>
+#include <QtTest/private/qtesthelpers_p.h>
+
#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/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()
{
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 <QTime>
#include <QDebug>
+#include <QtTest/private/qtesthelpers_p.h>
+
+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 <QtTest/QtTest>
+#include <QtTest/private/qtesthelpers_p.h>
#include <qcoreapplication.h>
#include <qdebug.h>
@@ -38,16 +39,6 @@
#include "../../../shared/platforminputcontext.h"
#include <private/qinputmethod_p.h>
-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 7c63497291..b6007482ae 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 <private/qinputmethod_p.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);
-}
+#include <QtTest/private/qtesthelpers_p.h>
+
+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 71969ec695..21669e42cd 100644
--- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
+++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
@@ -28,6 +28,7 @@
#include <QtTest/QtTest>
+#include <QtTest/private/qtesthelpers_p.h>
#include "qlineedit.h"
#include "qapplication.h"
#include "qstringlist.h"
@@ -43,10 +44,6 @@
#include <private/qapplication_p.h>
#include "qclipboard.h"
-#ifdef Q_OS_MAC
-#include <cstdlib> // For the random function.
-#endif
-
#include <qlineedit.h>
#include <private/qlineedit_p.h>
#include <private/qwidgetlinecontrol_p.h>
@@ -74,16 +71,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
{
@@ -1949,17 +1937,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/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 5247d02427..91c12e292d 100644
--- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
+++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include <QtTest/QtTest>
+#include <QtTest/private/qtesthelpers_p.h>
#include <qapplication.h>
#include <QPushButton>
#include <QMainWindow>
@@ -48,15 +49,11 @@
#include <qpa/qplatformtheme.h>
+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/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/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 bc50e4f1d8..417fa9befa 100644
--- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
+++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
@@ -48,6 +48,22 @@ QT_FORWARD_DECLARE_CLASS(QMainWindow)
#include <qmenubar.h>
+#include <QtTest/private/qtesthelpers_p.h>
+
+using namespace QTestPrivate;
+
+// 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
{
@@ -61,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<QMenu *> menus;
@@ -621,6 +631,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();
@@ -655,6 +668,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();
@@ -688,6 +704,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();
@@ -1194,21 +1213,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 +1263,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 +1281,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 +1437,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 +1444,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());
}
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 5ef2c7bc50..278f5cdd68 100644
--- a/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp
+++ b/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp
@@ -33,16 +33,9 @@
#include <QScrollArea>
#include <QScreen>
-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 <QtTest/private/qtesthelpers_p.h>
-static inline void centerOnScreen(QWidget *w)
-{
- centerOnScreen(w, w->geometry().size());
-}
+using namespace QTestPrivate;
class tst_QScrollBar : public QObject
{
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 <qtcpserver.h>
#include <qtcpsocket.h>
#include <QtTest/QtTest>
+#include <QtCore/qatomic.h>
+#include <QtCore/qsemaphore.h>
#include <qfile.h>
#include <qstring.h>
#include <qdir.h>
@@ -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);
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<DataType> generateData(QString dataSetType, const int length)
QVector<DataType> 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 <QByteArray>
#include <QCryptographicHash>
#include <QFile>
+#include <QRandomGenerator>
#include <QString>
#include <QtTest>
@@ -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 <QFile>
+#include <QRandomGenerator>
#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 <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsWidget>
+#include <QRandomGenerator>
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 <QDebug>
#include <QStaticText>
#include <QPainter>
+#include <QRandomGenerator>
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 <QDebug>
#include <qtest.h>
#include <QtTest/QtTest>
+#include <QtCore/qrandom.h>
#include <QtNetwork/qnetworkreply.h>
#include <QtNetwork/qnetworkrequest.h>
#include <QtNetwork/qnetworkaccessmanager.h>
@@ -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/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 &quot;Dynamic Stuff&quot; then move left and right to other menus. Disa
<addaction name="menuSubmenu"/>
<addaction name="actionDisabled_Item"/>
<addaction name="menuDisabled_Submenu"/>
+ <addaction name="separator"/>
</widget>
<widget class="QMenu" name="menuDisabled_Stuff">
<property name="enabled">
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 <QDialog>
#include <QFontDatabase>
#include <QPainter>
+#include <QRandomGenerator>
#include <QTime>
#include <QTimer>
@@ -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 <controls.h>
-#if QT_VERSION >= 0x050000
-# include <QtWidgets>
-# include <QWindow>
-# include <QBackingStore>
-# include <QPaintDevice>
-# include <QPainter>
-#else
-# include <QtGui>
-#endif
-
+#include <QtWidgets>
+#include <QWindow>
+#include <QBackingStore>
+#include <QPaintDevice>
+#include <QPainter>
+#include <QRandomGenerator>
#include <QResizeEvent>
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"));