summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp2
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp20
-rw-r--r--src/3rdparty/freetype/qt_attribution.json8
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java2
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java5
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtSurface.java3
-rw-r--r--src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java3
-rw-r--r--src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch9
-rw-r--r--src/angle/patches/0016-ANGLE-Fix-resizing-of-windows.patch57
-rw-r--r--src/concurrent/doc/qtconcurrent.qdocconf2
-rw-r--r--src/corelib/animation/qabstractanimation.cpp4
-rw-r--r--src/corelib/configure.json19
-rw-r--r--src/corelib/doc/qtcore.qdocconf3
-rw-r--r--src/corelib/doc/snippets/qstring/main.cpp13
-rw-r--r--src/corelib/global/global.pri5
-rw-r--r--src/corelib/global/minimum-linux_p.h2
-rw-r--r--src/corelib/global/qconfig-bootstrapped.h5
-rw-r--r--src/corelib/global/qfloat16.cpp24
-rw-r--r--src/corelib/global/qfloat16.h4
-rw-r--r--src/corelib/global/qfloat16_f16c.c8
-rw-r--r--src/corelib/global/qfloat16_p.h4
-rw-r--r--src/corelib/global/qglobal.cpp11
-rw-r--r--src/corelib/global/qglobal.h6
-rw-r--r--src/corelib/global/qlogging.cpp10
-rw-r--r--src/corelib/global/qnamespace.h2
-rw-r--r--src/corelib/global/qoperatingsystemversion_win.cpp3
-rw-r--r--src/corelib/global/qoperatingsystemversion_win_p.h63
-rw-r--r--src/corelib/global/qrandom.cpp85
-rw-r--r--src/corelib/global/qrandom.h28
-rw-r--r--src/corelib/io/qfile.cpp3
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp78
-rwxr-xr-x[-rw-r--r--]src/corelib/io/qfilesystemengine_win.cpp64
-rw-r--r--src/corelib/io/qfilesystemmetadata_p.h4
-rw-r--r--src/corelib/io/qfsfileengine_p.h3
-rw-r--r--src/corelib/io/qloggingregistry.cpp4
-rw-r--r--src/corelib/io/qloggingregistry_p.h2
-rw-r--r--src/corelib/io/qprocess.cpp6
-rw-r--r--src/corelib/io/qresource.cpp4
-rw-r--r--src/corelib/io/qsettings.cpp2
-rw-r--r--src/corelib/io/qstandardpaths.cpp29
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp18
-rw-r--r--src/corelib/io/qtemporaryfile.cpp22
-rw-r--r--src/corelib/io/qtemporaryfile_p.h8
-rw-r--r--src/corelib/io/qurl.cpp110
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp8
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.h6
-rw-r--r--src/corelib/kernel/kernel.pri2
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp6
-rw-r--r--src/corelib/kernel/qjnihelpers.cpp2
-rw-r--r--src/corelib/kernel/qobject.cpp2
-rw-r--r--src/corelib/kernel/qppsobjectprivate_p.h4
-rw-r--r--src/corelib/plugin/qlibrary_win.cpp7
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp6
-rw-r--r--src/corelib/thread/qfuturewatcher.h2
-rw-r--r--src/corelib/tools/qdatetime.cpp4
-rw-r--r--src/corelib/tools/qdatetime.h2
-rw-r--r--src/corelib/tools/qdatetimeparser.cpp48
-rw-r--r--src/corelib/tools/qdatetimeparser_p.h5
-rw-r--r--src/corelib/tools/qlocale.cpp4
-rw-r--r--src/corelib/tools/qmap.h4
-rw-r--r--src/corelib/tools/qstring.cpp86
-rw-r--r--src/corelib/tools/qstringalgorithms.h2
-rw-r--r--src/corelib/tools/qstringiterator.qdoc2
-rw-r--r--src/corelib/tools/qstringiterator_p.h2
-rw-r--r--src/corelib/tools/qstringview.cpp34
-rw-r--r--src/corelib/tools/qstringview.h41
-rw-r--r--src/corelib/tools/qunicodetables.cpp20
-rw-r--r--src/corelib/tools/qunicodetables_p.h4
-rw-r--r--src/corelib/tools/qvector.h5
-rw-r--r--src/corelib/xml/qxmlstream.cpp1
-rw-r--r--src/dbus/doc/qtdbus.qdocconf2
-rw-r--r--src/gui/configure.json42
-rw-r--r--src/gui/doc/qtgui.qdocconf2
-rw-r--r--src/gui/image/qbmphandler.cpp4
-rw-r--r--src/gui/image/qimage.cpp4
-rw-r--r--src/gui/image/qimage.h2
-rw-r--r--src/gui/image/qimage_conversions.cpp28
-rw-r--r--src/gui/image/qimage_p.h4
-rw-r--r--src/gui/image/qpixmap_blitter.cpp2
-rw-r--r--src/gui/kernel/qguiapplication.cpp16
-rw-r--r--src/gui/kernel/qguiapplication_p.h2
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp18
-rw-r--r--src/gui/kernel/qinputdevicemanager.cpp44
-rw-r--r--src/gui/kernel/qinputdevicemanager_p.h3
-rw-r--r--src/gui/kernel/qinputdevicemanager_p_p.h2
-rw-r--r--src/gui/kernel/qopenglcontext.cpp4
-rw-r--r--src/gui/kernel/qplatformwindow.cpp10
-rw-r--r--src/gui/kernel/qplatformwindow.h1
-rw-r--r--src/gui/kernel/qwindow.cpp2
-rw-r--r--src/gui/kernel/qwindow_p.h2
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp7
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h3
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h12
-rw-r--r--src/gui/painting/qcolor.cpp2
-rw-r--r--src/gui/painting/qcoregraphics_p.h10
-rw-r--r--src/gui/painting/qdrawhelper.cpp9
-rw-r--r--src/gui/painting/qdrawhelper_avx2.cpp2
-rw-r--r--src/gui/painting/qdrawhelper_p.h4
-rw-r--r--src/gui/painting/qpaintengine.cpp22
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp10
-rw-r--r--src/gui/painting/qpainter.cpp4
-rw-r--r--src/gui/text/qdistancefield.cpp4
-rw-r--r--src/gui/util/qshadergraphloader.cpp3
-rw-r--r--src/gui/util/qshaderlanguage.cpp14
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp5
-rw-r--r--src/network/bearer/qbearerengine.cpp4
-rw-r--r--src/network/bearer/qnetworkconfigmanager.cpp4
-rw-r--r--src/network/bearer/qnetworksession.cpp4
-rw-r--r--src/network/configure.json8
-rw-r--r--src/network/doc/qtnetwork.qdocconf2
-rw-r--r--src/network/kernel/qdnslookup_unix.cpp27
-rw-r--r--src/network/kernel/qnetworkinterface_linux.cpp2
-rw-r--r--src/network/socket/qabstractsocket.cpp4
-rw-r--r--src/network/socket/qabstractsocket_p.h1
-rw-r--r--src/network/socket/qlocalserver_win.cpp2
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp26
-rw-r--r--src/network/socket/qudpsocket.cpp10
-rw-r--r--src/network/ssl/qsslkey_qt.cpp2
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp15
-rw-r--r--src/network/ssl/qsslsocket_winrt.cpp8
-rw-r--r--src/platformsupport/eglconvenience/qeglpbuffer.cpp11
-rw-r--r--src/platformsupport/eglconvenience/qeglpbuffer_p.h3
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp5
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm24
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h4
-rw-r--r--src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp7
-rw-r--r--src/platformsupport/input/libinput/qlibinputkeyboard.cpp5
-rw-r--r--src/platformsupport/input/libinput/qlibinputpointer.cpp6
-rw-r--r--src/plugins/bearer/bearer.pro5
-rw-r--r--src/plugins/bearer/connman/qconnmanservice_linux.cpp2
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.cpp3
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp10
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm44
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm5
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm1
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfscontext_p.h3
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfscursor.cpp15
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfscursor_p.h22
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro3
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/eglfs_openwfd.json3
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/eglfs_openwfd.pro17
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.cpp223
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.h69
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdmain.cpp58
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/eglfs_rcar.json3
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/eglfs_rcar.pro19
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarintegration.cpp159
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarintegration.h66
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarmain.cpp57
-rw-r--r--src/plugins/platforms/integrity/integrity.pro13
-rw-r--r--src/plugins/platforms/ios/qiosapplicationstate.h18
-rw-r--r--src/plugins/platforms/ios/qiosapplicationstate.mm111
-rw-r--r--src/plugins/platforms/ios/qioscontext.h1
-rw-r--r--src/plugins/platforms/ios/qioscontext.mm66
-rw-r--r--src/plugins/platforms/ios/qioseventdispatcher.mm14
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm24
-rw-r--r--src/plugins/platforms/ios/qiosintegration.h3
-rw-r--r--src/plugins/platforms/ios/qiosscreen.h7
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm107
-rw-r--r--src/plugins/platforms/ios/qiostextresponder.mm1
-rw-r--r--src/plugins/platforms/ios/qiosviewcontroller.mm20
-rw-r--r--src/plugins/platforms/ios/qioswindow.h2
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm9
-rw-r--r--src/plugins/platforms/ios/quiview.h1
-rw-r--r--src/plugins/platforms/ios/quiview.mm88
-rw-r--r--src/plugins/platforms/qnx/qnx.pro20
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp29
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.h8
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsmenu.cpp9
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.cpp46
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.cpp2
-rw-r--r--src/plugins/platforms/xcb/README3
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp35
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp11
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp35
-rw-r--r--src/plugins/platforms/xcb/xcb_qpa_lib.pro2
-rw-r--r--src/plugins/sqldrivers/db2/db2.pro2
-rw-r--r--src/plugins/sqldrivers/db2/qsql_db2.cpp28
-rw-r--r--src/plugins/sqldrivers/psql/qsql_psql.cpp2
-rw-r--r--src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp2
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm62
-rw-r--r--src/plugins/styles/windowsvista/qwindowsxpstyle.cpp4
-rw-r--r--src/printsupport/dialogs/qabstractprintdialog.cpp2
-rw-r--r--src/printsupport/dialogs/qabstractprintdialog_p.h2
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_p.h2
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_unix.cpp26
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_unix_p.h2
-rw-r--r--src/printsupport/dialogs/qprintdialog_unix.cpp17
-rw-r--r--src/printsupport/dialogs/qprintpreviewdialog.cpp4
-rw-r--r--src/printsupport/kernel/qpaintengine_preview.cpp8
-rw-r--r--src/printsupport/kernel/qplatformprintersupport.cpp4
-rw-r--r--src/printsupport/kernel/qplatformprintplugin.cpp4
-rw-r--r--src/printsupport/kernel/qprintengine_pdf.cpp2
-rw-r--r--src/printsupport/kernel/qprintengine_win.cpp2
-rw-r--r--src/printsupport/kernel/qprinter.cpp2
-rw-r--r--src/printsupport/widgets/qcupsjobwidget.cpp2
-rw-r--r--src/printsupport/widgets/qprintpreviewwidget.cpp4
-rw-r--r--src/sql/doc/snippets/code/doc_src_sql-driver.qdoc160
-rw-r--r--src/sql/doc/src/sql-driver.qdoc164
-rw-r--r--src/sql/kernel/qsqlfield.cpp13
-rw-r--r--src/sql/kernel/qsqlfield.h5
-rw-r--r--src/sql/kernel/qsqlquery.cpp17
-rw-r--r--src/tools/moc/main.cpp4
-rw-r--r--src/tools/qlalr/examples/qparser/calc.l3
-rw-r--r--src/widgets/dialogs/qfileinfogatherer.cpp35
-rw-r--r--src/widgets/dialogs/qfileinfogatherer_p.h3
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp7
-rw-r--r--src/widgets/dialogs/qwizard_win.cpp2
-rw-r--r--src/widgets/doc/qtwidgets.qdocconf4
-rw-r--r--src/widgets/itemviews/qheaderview.cpp23
-rw-r--r--src/widgets/itemviews/qtreeview.cpp3
-rw-r--r--src/widgets/kernel/qgesturemanager_p.h4
-rw-r--r--src/widgets/kernel/qwidget.cpp281
-rw-r--r--src/widgets/kernel/qwidget_p.h10
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp7
-rw-r--r--src/widgets/styles/qfusionstyle.cpp39
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp2
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp25
-rw-r--r--src/widgets/widgets/qabstractscrollarea_p.h1
-rw-r--r--src/widgets/widgets/qmenu.cpp3
-rw-r--r--src/widgets/widgets/qwidgetresizehandler.cpp2
228 files changed, 2930 insertions, 1131 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
index 0173311bc6..5118bdbe9c 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -2645,7 +2645,7 @@ bool Renderer11::getShareHandleSupport() const
if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_WARP)
{
-#if !defined(ANGLE_ENABLE_WINDOWS_STORE) && !defined(__GNUC__)
+#ifndef ANGLE_ENABLE_WINDOWS_STORE
if (!IsWindows8OrGreater())
{
// WARP on Windows 7 doesn't support shared handles
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
index 785a83cd77..42c336c8cf 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
@@ -707,15 +707,15 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width,
d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
// Create a quad in homogeneous coordinates
- float x1 = (x / float(mWidth)) * 2.0f - 1.0f;
- float y1 = (y / float(mHeight)) * 2.0f - 1.0f;
- float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f;
- float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f;
+ float x1 = (x / float(width)) * 2.0f - 1.0f;
+ float y1 = (y / float(height)) * 2.0f - 1.0f;
+ float x2 = ((x + width) / float(width)) * 2.0f - 1.0f;
+ float y2 = ((y + height) / float(height)) * 2.0f - 1.0f;
- float u1 = x / float(mWidth);
- float v1 = y / float(mHeight);
- float u2 = (x + width) / float(mWidth);
- float v2 = (y + height) / float(mHeight);
+ float u1 = x / float(width);
+ float v1 = y / float(height);
+ float u2 = (x + width) / float(width);
+ float v2 = (y + height) / float(height);
// Invert the quad vertices depending on the surface orientation.
if ((mOrientation & EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE) != 0)
@@ -760,8 +760,8 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width,
D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
- viewport.Width = static_cast<FLOAT>(mWidth);
- viewport.Height = static_cast<FLOAT>(mHeight);
+ viewport.Width = static_cast<FLOAT>(width);
+ viewport.Height = static_cast<FLOAT>(height);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
deviceContext->RSSetViewports(1, &viewport);
diff --git a/src/3rdparty/freetype/qt_attribution.json b/src/3rdparty/freetype/qt_attribution.json
index e00f2062b0..4be86e92b6 100644
--- a/src/3rdparty/freetype/qt_attribution.json
+++ b/src/3rdparty/freetype/qt_attribution.json
@@ -9,7 +9,7 @@
"Homepage": "http://www.freetype.org",
"License": "Freetype Project License or GNU General Public License v2.0 only",
"LicenseId": "FTL OR GPL-2.0",
- "LicenseFile": "LICENSE.TXT",
+ "LicenseFile": "LICENSE.txt",
"Copyright": "Copyright 2006-2015 by David Turner, Robert Wilhelm, and Werner Lemberg."
},
{
@@ -22,7 +22,7 @@
"Homepage": "http://www.freetype.org",
"License": "zlib License",
"LicenseId": "Zlib",
- "LicenseFile": "ZLIB-LICENSE.TXT",
+ "LicenseFile": "ZLIB-LICENSE.txt",
"Copyright": "Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler"
},
{
@@ -35,7 +35,7 @@
"Homepage": "http://www.freetype.org",
"License": "MIT License",
"LicenseId": "MIT",
- "LicenseFile": "BDF-LICENSE.TXT",
+ "LicenseFile": "BDF-LICENSE.txt",
"Copyright": "Copyright (C) 2001-2002 by Francesco Zappa Nardelli
Copyright 2000 Computing Research Labs, New Mexico State University
Copyright 2001-2002, 2011 Francesco Zappa Nardelli"
@@ -50,7 +50,7 @@ Copyright 2001-2002, 2011 Francesco Zappa Nardelli"
"Homepage": "http://www.freetype.org",
"License": "MIT License",
"LicenseId": "MIT",
- "LicenseFile": "PCF-LICENSE.TXT",
+ "LicenseFile": "PCF-LICENSE.txt",
"Copyright": "Copyright (C) 2000 by Francesco Zappa Nardelli"
}
]
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index 84d5adf856..0e28b964e8 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -1156,7 +1156,7 @@ public class QtActivityDelegate
return false;
m_metaState = MetaKeyKeyListener.handleKeyDown(m_metaState, keyCode, event);
- int c = event.getUnicodeChar(MetaKeyKeyListener.getMetaState(m_metaState));
+ int c = event.getUnicodeChar(MetaKeyKeyListener.getMetaState(m_metaState) | event.getMetaState());
int lc = c;
m_metaState = MetaKeyKeyListener.adjustMetaAfterKeypress(m_metaState);
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index f15c7f3a97..1cf3bca5f7 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -500,15 +500,16 @@ public class QtNative
}
}
- static public void sendGenericMotionEvent(MotionEvent event, int id)
+ static public boolean sendGenericMotionEvent(MotionEvent event, int id)
{
if (event.getActionMasked() != MotionEvent.ACTION_SCROLL
|| (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != InputDevice.SOURCE_CLASS_POINTER) {
- return;
+ return false;
}
mouseWheel(id, (int) event.getX(), (int) event.getY(),
event.getAxisValue(MotionEvent.AXIS_HSCROLL), event.getAxisValue(MotionEvent.AXIS_VSCROLL));
+ return true;
}
public static Context getContext() {
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
index e994002dd3..08b5a80f7e 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
@@ -116,7 +116,6 @@ public class QtSurface extends SurfaceView implements SurfaceHolder.Callback
@Override
public boolean onGenericMotionEvent(MotionEvent event)
{
- QtNative.sendGenericMotionEvent(event, getId());
- return true;
+ return QtNative.sendGenericMotionEvent(event, getId());
}
}
diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java
index 99c4ecca07..6e92e64028 100644
--- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java
+++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java
@@ -569,7 +569,8 @@ public abstract class QtLoader {
boolean bundlingQtLibs = false;
if (m_contextInfo.metaData.containsKey("android.app.bundle_local_qt_libs")
&& m_contextInfo.metaData.getInt("android.app.bundle_local_qt_libs") == 1) {
- localPrefix = m_context.getApplicationInfo().dataDir + "/";
+ File dataDir = new File(m_context.getApplicationInfo().dataDir);
+ localPrefix = dataDir.getCanonicalPath() + "/";
pluginsPrefix = localPrefix + "qt-reserved-files/";
if (libsDir == null)
diff --git a/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch b/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch
index dc091b0497..f42ff2141b 100644
--- a/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch
+++ b/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch
@@ -405,15 +405,6 @@ index ea84783..62badcc 100644
if (mD3d11Module)
{
-@@ -2618,7 +2642,7 @@ bool Renderer11::getShareHandleSupport() const
-
- if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_WARP)
- {
--#ifndef ANGLE_ENABLE_WINDOWS_STORE
-+#if !defined(ANGLE_ENABLE_WINDOWS_STORE) && !defined(__GNUC__)
- if (!IsWindows8OrGreater())
- {
- // WARP on Windows 7 doesn't support shared handles
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
index 62e9816..b4e7761 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
diff --git a/src/angle/patches/0016-ANGLE-Fix-resizing-of-windows.patch b/src/angle/patches/0016-ANGLE-Fix-resizing-of-windows.patch
new file mode 100644
index 0000000000..7ba92052f2
--- /dev/null
+++ b/src/angle/patches/0016-ANGLE-Fix-resizing-of-windows.patch
@@ -0,0 +1,57 @@
+From 55821d34b2208e7858dbba5648760b83c66b58a5 Mon Sep 17 00:00:00 2001
+From: Oliver Wolff <oliver.wolff@qt.io>
+Date: Mon, 29 Aug 2016 09:48:28 +0200
+Subject: [PATCH] ANGLE: Fix resizing of windows
+
+Use the correct height/width values when calculating
+the vector for resizing the window content and the
+new size as viewport size.
+
+Task-number: QTBUG-62475
+Change-Id: I33a8dc1379a908e991b04bc31dfc6254a6d005c9
+---
+ .../libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 35 +++++++++++-----------
+ 1 file changed, 17 insertions(+), 18 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
+index 785a83cd77..fe72bc935d 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
+@@ -707,15 +706,15 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width,
+ d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
+
+ // Create a quad in homogeneous coordinates
+- float x1 = (x / float(mWidth)) * 2.0f - 1.0f;
+- float y1 = (y / float(mHeight)) * 2.0f - 1.0f;
+- float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f;
+- float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f;
++ float x1 = (x / float(width)) * 2.0f - 1.0f;
++ float y1 = (y / float(height)) * 2.0f - 1.0f;
++ float x2 = ((x + width) / float(width)) * 2.0f - 1.0f;
++ float y2 = ((y + height) / float(height)) * 2.0f - 1.0f;
+
+- float u1 = x / float(mWidth);
+- float v1 = y / float(mHeight);
+- float u2 = (x + width) / float(mWidth);
+- float v2 = (y + height) / float(mHeight);
++ float u1 = x / float(width);
++ float v1 = y / float(height);
++ float u2 = (x + width) / float(width);
++ float v2 = (y + height) / float(height);
+
+ // Invert the quad vertices depending on the surface orientation.
+ if ((mOrientation & EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE) != 0)
+@@ -760,8 +759,8 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width,
+ D3D11_VIEWPORT viewport;
+ viewport.TopLeftX = 0;
+ viewport.TopLeftY = 0;
+- viewport.Width = static_cast<FLOAT>(mWidth);
+- viewport.Height = static_cast<FLOAT>(mHeight);
++ viewport.Width = static_cast<FLOAT>(width);
++ viewport.Height = static_cast<FLOAT>(height);
+ viewport.MinDepth = 0.0f;
+ viewport.MaxDepth = 1.0f;
+ deviceContext->RSSetViewports(1, &viewport);
+--
+2.15.0.windows.1
+
diff --git a/src/concurrent/doc/qtconcurrent.qdocconf b/src/concurrent/doc/qtconcurrent.qdocconf
index d8ee963ef5..356d602a7c 100644
--- a/src/concurrent/doc/qtconcurrent.qdocconf
+++ b/src/concurrent/doc/qtconcurrent.qdocconf
@@ -36,6 +36,8 @@ exampledirs += ../../../examples/qtconcurrent \
../ \
snippets
+manifestmeta.highlighted.names = "QtConcurrent/QtConcurrent Progress Dialog Example"
+
excludedirs += ../../../examples/widgets/doc
imagedirs += images
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index 2041b8816e..e445037efb 100644
--- a/src/corelib/animation/qabstractanimation.cpp
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -299,13 +299,13 @@ void QUnifiedTimer::stopAnimationDriver()
driver->stop();
}
-void QUnifiedTimer::updateAnimationTimers(qint64)
+void QUnifiedTimer::updateAnimationTimers(qint64 currentTick)
{
//setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations
if(insideTick)
return;
- qint64 totalElapsed = elapsed();
+ qint64 totalElapsed = currentTick > 0 ? currentTick : elapsed();
// ignore consistentTiming in case the pause timer is active
qint64 delta = (consistentTiming && !pauseTimer.isActive()) ?
diff --git a/src/corelib/configure.json b/src/corelib/configure.json
index 8067ca70f1..8cd73d6ce4 100644
--- a/src/corelib/configure.json
+++ b/src/corelib/configure.json
@@ -178,7 +178,7 @@
"slog2": {
"label": "slog2",
"test": {
- "include": "slog2.h",
+ "include": "sys/slog2.h",
"main": "slog2_set_default_buffer((slog2_buffer_t)-1);"
},
"export": "",
@@ -349,6 +349,15 @@
"qmake": "linux: LIBS += -lpthread -lrt"
}
},
+ "linkat": {
+ "label": "linkat()",
+ "type": "compile",
+ "test": {
+ "head": "#define _ATFILE_SOURCE 1",
+ "include": [ "fcntl.h", "unistd.h" ],
+ "main": "linkat(AT_FDCWD, \"foo\", AT_FDCWD, \"bar\", AT_SYMLINK_FOLLOW);"
+ }
+ },
"ppoll": {
"label": "ppoll()",
"type": "compile",
@@ -540,6 +549,12 @@
"condition": "libs.journald",
"output": [ "privateFeature" ]
},
+ "linkat": {
+ "label": "linkat()",
+ "autoDetect": "config.linux",
+ "condition": "tests.linkat",
+ "output": [ "privateFeature" ]
+ },
"std-atomic64": {
"label": "64 bit atomic operations",
"condition": "libs.libatomic",
@@ -593,7 +608,7 @@
"label": "PPS",
"emitIf": "config.qnx",
"condition": "libs.pps",
- "output": [ "privateConfig" ]
+ "output": [ "privateFeature" ]
},
"qeventtransition": {
"label": "QEventTransition class",
diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf
index 3d64708def..5a42e21845 100644
--- a/src/corelib/doc/qtcore.qdocconf
+++ b/src/corelib/doc/qtcore.qdocconf
@@ -45,5 +45,8 @@ excludedirs += snippets
excludefiles += ../../../examples/widgets/tools/customcompleter/doc/src/customcompleter.qdoc \
../../../examples/widgets/tools/codecs/doc/src/codecs.qdoc
+manifestmeta.highlighted.names = "QtCore/JSON Save Game Example" \
+ "QtCore/Local Fortune*"
+
navigation.landingpage = "Qt Core"
navigation.cppclassespage = "Qt Core C++ Classes"
diff --git a/src/corelib/doc/snippets/qstring/main.cpp b/src/corelib/doc/snippets/qstring/main.cpp
index 3d09e3618e..b936f0c057 100644
--- a/src/corelib/doc/snippets/qstring/main.cpp
+++ b/src/corelib/doc/snippets/qstring/main.cpp
@@ -750,7 +750,6 @@ void Widget::sizeFunction()
int n = str.size(); // n == 5
str.data()[0]; // returns 'W'
str.data()[4]; // returns 'd'
- str.data()[5]; // returns '\0'
//! [58]
}
@@ -810,6 +809,18 @@ void Widget::splitCaseSensitiveFunction()
QStringList list2 = str.split(',', QString::SkipEmptyParts);
// list2: [ "a", "b", "c" ]
//! [62]
+
+ //! [62-empty]
+ QString str = "abc";
+ auto parts = str.split("");
+ // parts: {"", "a", "b", "c", ""}
+ //! [62-empty]
+
+ //! [62-slashes]
+ QString str = "/a/b/c/";
+ auto parts = str.split('/');
+ // parts: {"", "a", "b", "c", ""}
+ //! [62-slashes]
}
void Widget::sprintfFunction()
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index a878a83bcb..2b4fd6d661 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -63,7 +63,10 @@ unset(f16c_cxx)
VERSIONTAGGING_SOURCES = global/qversiontagging.cpp
darwin: SOURCES += global/qoperatingsystemversion_darwin.mm
-win32: SOURCES += global/qoperatingsystemversion_win.cpp
+win32 {
+ SOURCES += global/qoperatingsystemversion_win.cpp
+ HEADERS += global/qoperatingsystemversion_win_p.h
+}
# qlibraryinfo.cpp includes qconfig.cpp
INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global
diff --git a/src/corelib/global/minimum-linux_p.h b/src/corelib/global/minimum-linux_p.h
index 324744b856..bad2488b4d 100644
--- a/src/corelib/global/minimum-linux_p.h
+++ b/src/corelib/global/minimum-linux_p.h
@@ -67,7 +67,7 @@ QT_BEGIN_NAMESPACE
* - inotify_init1 before 2.6.12-rc12
* - futex(2) before 2.6.12-rc12
* - FUTEX_WAKE_OP 2.6.14 FUTEX_OP
- * - linkat(2) 2.6.17 O_TMPFILE
+ * - linkat(2) 2.6.17 O_TMPFILE && QT_CONFIG(linkat)
* - FUTEX_PRIVATE_FLAG 2.6.22
* - O_CLOEXEC 2.6.23
* - eventfd 2.6.23
diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h
index eb56d2d0cd..0df593941d 100644
--- a/src/corelib/global/qconfig-bootstrapped.h
+++ b/src/corelib/global/qconfig-bootstrapped.h
@@ -87,6 +87,11 @@
#define QT_FEATURE_futimens -1
#define QT_FEATURE_futimes -1
#define QT_FEATURE_library -1
+#ifdef __linux__
+# define QT_FEATURE_linkat 1
+#else
+# define QT_FEATURE_linkat -1
+#endif
#define QT_NO_QOBJECT
#define QT_FEATURE_process -1
#define QT_FEATURE_regularexpression -1
diff --git a/src/corelib/global/qfloat16.cpp b/src/corelib/global/qfloat16.cpp
index 129ab4ded2..3046a47292 100644
--- a/src/corelib/global/qfloat16.cpp
+++ b/src/corelib/global/qfloat16.cpp
@@ -129,8 +129,8 @@ extern "C" {
# define f16cextern extern
#endif
-f16cextern void qFloatToFloat16_fast(quint16 *out, const float *in, qssize_t len) Q_DECL_NOTHROW;
-f16cextern void qFloatFromFloat16_fast(float *out, const quint16 *in, qssize_t len) Q_DECL_NOTHROW;
+f16cextern void qFloatToFloat16_fast(quint16 *out, const float *in, qsizetype len) Q_DECL_NOTHROW;
+f16cextern void qFloatFromFloat16_fast(float *out, const quint16 *in, qsizetype len) Q_DECL_NOTHROW;
#undef f16cextern
}
@@ -141,20 +141,20 @@ static inline bool hasFastF16()
return true;
}
-static void qFloatToFloat16_fast(quint16 *out, const float *in, qssize_t len) Q_DECL_NOTHROW
+static void qFloatToFloat16_fast(quint16 *out, const float *in, qsizetype len) Q_DECL_NOTHROW
{
__fp16 *out_f16 = reinterpret_cast<__fp16 *>(out);
- qssize_t i = 0;
+ qsizetype i = 0;
for (; i < len - 3; i += 4)
vst1_f16(out_f16 + i, vcvt_f16_f32(vld1q_f32(in + i)));
SIMD_EPILOGUE(i, len, 3)
out_f16[i] = __fp16(in[i]);
}
-static void qFloatFromFloat16_fast(float *out, const quint16 *in, qssize_t len) Q_DECL_NOTHROW
+static void qFloatFromFloat16_fast(float *out, const quint16 *in, qsizetype len) Q_DECL_NOTHROW
{
const __fp16 *in_f16 = reinterpret_cast<const __fp16 *>(in);
- qssize_t i = 0;
+ qsizetype i = 0;
for (; i < len - 3; i += 4)
vst1q_f32(out + i, vcvt_f32_f16(vld1_f16(in_f16 + i)));
SIMD_EPILOGUE(i, len, 3)
@@ -166,12 +166,12 @@ static inline bool hasFastF16()
return false;
}
-static void qFloatToFloat16_fast(quint16 *, const float *, qssize_t) Q_DECL_NOTHROW
+static void qFloatToFloat16_fast(quint16 *, const float *, qsizetype) Q_DECL_NOTHROW
{
Q_UNREACHABLE();
}
-static void qFloatFromFloat16_fast(float *, const quint16 *, qssize_t) Q_DECL_NOTHROW
+static void qFloatFromFloat16_fast(float *, const quint16 *, qsizetype) Q_DECL_NOTHROW
{
Q_UNREACHABLE();
}
@@ -182,12 +182,12 @@ static void qFloatFromFloat16_fast(float *, const quint16 *, qssize_t) Q_DECL_NO
Converts \a len floats from \a in to qfloat16 and stores them in \a out.
Both \a in and \a out must have \a len allocated entries.
*/
-Q_CORE_EXPORT void qFloatToFloat16(qfloat16 *out, const float *in, qssize_t len) Q_DECL_NOTHROW
+Q_CORE_EXPORT void qFloatToFloat16(qfloat16 *out, const float *in, qsizetype len) Q_DECL_NOTHROW
{
if (hasFastF16())
return qFloatToFloat16_fast(reinterpret_cast<quint16 *>(out), in, len);
- for (qssize_t i = 0; i < len; ++i)
+ for (qsizetype i = 0; i < len; ++i)
out[i] = qfloat16(in[i]);
}
@@ -197,12 +197,12 @@ Q_CORE_EXPORT void qFloatToFloat16(qfloat16 *out, const float *in, qssize_t len)
Converts \a len qfloat16 from \a in to floats and stores them in \a out.
Both \a in and \a out must have \a len allocated entries.
*/
-Q_CORE_EXPORT void qFloatFromFloat16(float *out, const qfloat16 *in, qssize_t len) Q_DECL_NOTHROW
+Q_CORE_EXPORT void qFloatFromFloat16(float *out, const qfloat16 *in, qsizetype len) Q_DECL_NOTHROW
{
if (hasFastF16())
return qFloatFromFloat16_fast(out, reinterpret_cast<const quint16 *>(in), len);
- for (qssize_t i = 0; i < len; ++i)
+ for (qsizetype i = 0; i < len; ++i)
out[i] = float(in[i]);
}
diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h
index bf223bee0c..a8befd7adb 100644
--- a/src/corelib/global/qfloat16.h
+++ b/src/corelib/global/qfloat16.h
@@ -88,8 +88,8 @@ private:
Q_DECLARE_TYPEINFO(qfloat16, Q_PRIMITIVE_TYPE);
-Q_CORE_EXPORT void qFloatToFloat16(qfloat16 *, const float *, qssize_t length) Q_DECL_NOTHROW;
-Q_CORE_EXPORT void qFloatFromFloat16(float *, const qfloat16 *, qssize_t length) Q_DECL_NOTHROW;
+Q_CORE_EXPORT void qFloatToFloat16(qfloat16 *, const float *, qsizetype length) Q_DECL_NOTHROW;
+Q_CORE_EXPORT void qFloatFromFloat16(float *, const qfloat16 *, qsizetype length) Q_DECL_NOTHROW;
Q_REQUIRED_RESULT Q_CORE_EXPORT bool qIsInf(qfloat16 f) Q_DECL_NOTHROW; // complements qnumeric.h
Q_REQUIRED_RESULT Q_CORE_EXPORT bool qIsNaN(qfloat16 f) Q_DECL_NOTHROW; // complements qnumeric.h
diff --git a/src/corelib/global/qfloat16_f16c.c b/src/corelib/global/qfloat16_f16c.c
index c88dbb6944..31dff0b154 100644
--- a/src/corelib/global/qfloat16_f16c.c
+++ b/src/corelib/global/qfloat16_f16c.c
@@ -54,9 +54,9 @@ extern "C" {
#endif
QT_FUNCTION_TARGET(F16C)
-void qFloatToFloat16_fast(quint16 *out, const float *in, qssize_t len) Q_DECL_NOTHROW
+void qFloatToFloat16_fast(quint16 *out, const float *in, qsizetype len) Q_DECL_NOTHROW
{
- qssize_t i = 0;
+ qsizetype i = 0;
for (; i < len - 7; i += 8)
_mm_storeu_si128((__m128i *)(out + i), _mm256_cvtps_ph(_mm256_loadu_ps(in + i), 0));
if (i < len - 3) {
@@ -69,9 +69,9 @@ void qFloatToFloat16_fast(quint16 *out, const float *in, qssize_t len) Q_DECL_NO
}
QT_FUNCTION_TARGET(F16C)
-void qFloatFromFloat16_fast(float *out, const quint16 *in, qssize_t len) Q_DECL_NOTHROW
+void qFloatFromFloat16_fast(float *out, const quint16 *in, qsizetype len) Q_DECL_NOTHROW
{
- qssize_t i = 0;
+ qsizetype i = 0;
for (; i < len - 7; i += 8)
_mm256_storeu_ps(out + i, _mm256_cvtph_ps(_mm_loadu_si128((const __m128i *)(in + i))));
if (i < len - 3) {
diff --git a/src/corelib/global/qfloat16_p.h b/src/corelib/global/qfloat16_p.h
index ae52e64435..f3fc96e119 100644
--- a/src/corelib/global/qfloat16_p.h
+++ b/src/corelib/global/qfloat16_p.h
@@ -61,9 +61,9 @@ static inline bool qt_is_inf(qfloat16 d) Q_DECL_NOTHROW
bool is_inf;
uchar *ch = (uchar *)&d;
if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
- is_inf = (ch[0] & 0x7c) == 0x7c;
+ is_inf = (ch[0] & 0x7c) == 0x7c && (ch[0] & 0x02) == 0;
else
- is_inf = (ch[1] & 0x7c) == 0x7c;
+ is_inf = (ch[1] & 0x7c) == 0x7c && (ch[1] & 0x02) == 0;
return is_inf;
}
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index c3b074c59f..a8fa7654ba 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -46,6 +46,9 @@
#include "qdatetime.h"
#include "qoperatingsystemversion.h"
#include "qoperatingsystemversion_p.h"
+#if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN) || defined(Q_OS_WINRT)
+#include "qoperatingsystemversion_win_p.h"
+#endif
#include <private/qlocale_tools_p.h>
#include <qmutex.h>
@@ -164,8 +167,8 @@ Q_STATIC_ASSERT_X(std::numeric_limits<float>::radix == 2,
// not required by the definition of size_t, but we depend on this
Q_STATIC_ASSERT_X(sizeof(size_t) == sizeof(void *), "size_t and a pointer don't have the same size");
-Q_STATIC_ASSERT(sizeof(size_t) == sizeof(qssize_t)); // implied by the definition
-Q_STATIC_ASSERT((std::is_same<qssize_t, qptrdiff>::value));
+Q_STATIC_ASSERT(sizeof(size_t) == sizeof(qsizetype)); // implied by the definition
+Q_STATIC_ASSERT((std::is_same<qsizetype, qptrdiff>::value));
/*!
\class QFlag
@@ -827,7 +830,7 @@ Q_STATIC_ASSERT((std::is_same<qssize_t, qptrdiff>::value));
*/
/*!
- \typedef qssize_t
+ \typedef qsizetype
\relates <QtGlobal>
\since 5.10
@@ -836,7 +839,7 @@ Q_STATIC_ASSERT((std::is_same<qssize_t, qptrdiff>::value));
This type is guaranteed to be the same size as a \c size_t on all
platforms supported by Qt.
- Note that qssize_t is signed. Use \c size_t for unsigned values.
+ Note that qsizetype is signed. Use \c size_t for unsigned values.
\sa qptrdiff
*/
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index d439085dbc..7873ab2b43 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -250,7 +250,7 @@ typedef quint64 qulonglong;
// In C++ mode, we define below using QIntegerForSize template
Q_STATIC_ASSERT_X(sizeof(ptrdiff_t) == sizeof(size_t), "Weird ptrdiff_t and size_t definitions");
typedef ptrdiff_t qptrdiff;
-typedef ptrdiff_t qssize_t;
+typedef ptrdiff_t qsizetype;
typedef ptrdiff_t qintptr;
typedef size_t quintptr;
#endif
@@ -475,7 +475,7 @@ namespace QtPrivate {
sizeof(void *) == sizeof(quintptr)
&& sizeof(void *) == sizeof(qptrdiff)
- size_t and qssize_t are not guaranteed to be the same size as a pointer, but
+ size_t and qsizetype are not guaranteed to be the same size as a pointer, but
they usually are.
*/
template <int> struct QIntegerForSize;
@@ -492,7 +492,7 @@ typedef QIntegerForSize<Q_PROCESSOR_WORDSIZE>::Unsigned qregisteruint;
typedef QIntegerForSizeof<void*>::Unsigned quintptr;
typedef QIntegerForSizeof<void*>::Signed qptrdiff;
typedef qptrdiff qintptr;
-using qssize_t = QIntegerForSizeof<std::size_t>::Signed;
+using qsizetype = QIntegerForSizeof<std::size_t>::Signed;
/* moc compats (signals/slots) */
#ifndef QT_MOC_COMPAT
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 6602d53b08..0861763492 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -61,7 +61,10 @@
#include <qt_windows.h>
#endif
#if QT_CONFIG(slog2)
-#include <slog2.h>
+#include <sys/slog2.h>
+#endif
+#if QT_HAS_INCLUDE(<paths.h>)
+#include <paths.h>
#endif
#ifdef Q_OS_ANDROID
@@ -215,8 +218,11 @@ static bool willLogToConsole()
# ifdef Q_OS_WIN
return GetConsoleWindow();
# elif defined(Q_OS_UNIX)
+# ifndef _PATH_TTY
+# define _PATH_TTY "/dev/tty"
+# endif
// if /dev/tty exists, we can only open it if we have a controlling TTY
- int devtty = qt_safe_open("/dev/tty", O_RDONLY);
+ int devtty = qt_safe_open(_PATH_TTY, O_RDONLY);
if (devtty == -1 && (errno == ENOENT || errno == EPERM || errno == ENXIO)) {
// no /dev/tty, fall back to isatty on stderr
return isatty(STDERR_FILENO);
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 38f194afb5..2773992b47 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -477,6 +477,8 @@ public:
WA_TabletTracking = 129,
+ WA_ContentsMarginsRespectsSafeArea = 130,
+
// Add new attributes before this line
WA_AttributeCount
};
diff --git a/src/corelib/global/qoperatingsystemversion_win.cpp b/src/corelib/global/qoperatingsystemversion_win.cpp
index 060ca2f7da..f3662ae1f9 100644
--- a/src/corelib/global/qoperatingsystemversion_win.cpp
+++ b/src/corelib/global/qoperatingsystemversion_win.cpp
@@ -37,7 +37,10 @@
**
****************************************************************************/
+#include "qoperatingsystemversion_win_p.h"
+
#include "qoperatingsystemversion_p.h"
+
#include <qt_windows.h>
#include <qbytearray.h>
diff --git a/src/corelib/global/qoperatingsystemversion_win_p.h b/src/corelib/global/qoperatingsystemversion_win_p.h
new file mode 100644
index 0000000000..446bd286fc
--- /dev/null
+++ b/src/corelib/global/qoperatingsystemversion_win_p.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore 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 QOPERATINGSYSTEMVERSION_WIN_P_H
+#define QOPERATINGSYSTEMVERSION_WIN_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/qglobal.h>
+#include <qt_windows.h>
+
+QT_BEGIN_NAMESPACE
+
+OSVERSIONINFOEX qWindowsVersionInfo();
+
+QT_END_NAMESPACE
+
+#endif // QOPERATINGSYSTEMVERSION_WIN_P_H
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
index 7da86188bb..f5c01aeaa6 100644
--- a/src/corelib/global/qrandom.cpp
+++ b/src/corelib/global/qrandom.cpp
@@ -93,7 +93,7 @@ DECLSPEC_IMPORT BOOLEAN WINAPI SystemFunction036(PVOID RandomBuffer, ULONG Rando
QT_BEGIN_NAMESPACE
#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND)
-static qssize_t qt_random_cpu(void *buffer, qssize_t count) Q_DECL_NOTHROW;
+static qsizetype qt_random_cpu(void *buffer, qsizetype count) Q_DECL_NOTHROW;
# ifdef Q_PROCESSOR_X86_64
# define _rdrandXX_step _rdrand64_step
@@ -101,7 +101,7 @@ static qssize_t qt_random_cpu(void *buffer, qssize_t count) Q_DECL_NOTHROW;
# define _rdrandXX_step _rdrand32_step
# endif
-static QT_FUNCTION_TARGET(RDRND) qssize_t qt_random_cpu(void *buffer, qssize_t count) Q_DECL_NOTHROW
+static QT_FUNCTION_TARGET(RDRND) qsizetype qt_random_cpu(void *buffer, qsizetype count) Q_DECL_NOTHROW
{
unsigned *ptr = reinterpret_cast<unsigned *>(buffer);
unsigned *end = ptr + count;
@@ -122,7 +122,7 @@ out:
return ptr - reinterpret_cast<unsigned *>(buffer);
}
#else
-static qssize_t qt_random_cpu(void *, qssize_t)
+static qsizetype qt_random_cpu(void *, qsizetype)
{
return 0;
}
@@ -136,10 +136,10 @@ enum {
struct QRandomGenerator::SystemGenerator
{
#if QT_CONFIG(getentropy)
- static qssize_t fillBuffer(void *buffer, qssize_t count) Q_DECL_NOTHROW
+ static qsizetype fillBuffer(void *buffer, qsizetype count) Q_DECL_NOTHROW
{
// getentropy can read at most 256 bytes, so break the reading
- qssize_t read = 0;
+ qsizetype read = 0;
while (count - read > 256) {
// getentropy can't fail under normal circumstances
int ret = getentropy(reinterpret_cast<uchar *>(buffer) + read, 256);
@@ -195,24 +195,24 @@ struct QRandomGenerator::SystemGenerator
Q_DECL_CONSTEXPR SystemGenerator() : fdp1 Q_BASIC_ATOMIC_INITIALIZER(0) {}
- qssize_t fillBuffer(void *buffer, qssize_t count)
+ qsizetype fillBuffer(void *buffer, qsizetype 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
+ return qMax<qsizetype>(n, 0); // ignore any errors
}
#elif defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- qssize_t fillBuffer(void *buffer, qssize_t count) Q_DECL_NOTHROW
+ qsizetype fillBuffer(void *buffer, qsizetype count) Q_DECL_NOTHROW
{
auto RtlGenRandom = SystemFunction036;
return RtlGenRandom(buffer, ULONG(count)) ? count: 0;
}
#elif defined(Q_OS_WINRT)
- qssize_t fillBuffer(void *, qssize_t) Q_DECL_NOTHROW
+ qsizetype fillBuffer(void *, qsizetype) Q_DECL_NOTHROW
{
// always use the fallback
return 0;
@@ -243,7 +243,7 @@ struct QRandomGenerator::SystemGenerator
#if defined(Q_OS_WIN)
static void fallback_update_seed(unsigned) {}
-static void fallback_fill(quint32 *ptr, qssize_t left) Q_DECL_NOTHROW
+static void fallback_fill(quint32 *ptr, qsizetype left) Q_DECL_NOTHROW
{
// on Windows, rand_s is a high-quality random number generator
// and it requires no seeding
@@ -255,14 +255,14 @@ static void fallback_fill(quint32 *ptr, qssize_t left) Q_DECL_NOTHROW
}
#elif QT_CONFIG(getentropy)
static void fallback_update_seed(unsigned) {}
-static void fallback_fill(quint32 *, qssize_t) Q_DECL_NOTHROW
+static void fallback_fill(quint32 *, qsizetype) 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) {}
-static void fallback_fill(quint32 *ptr, qssize_t left) Q_DECL_NOTHROW
+static void fallback_fill(quint32 *ptr, qsizetype left) Q_DECL_NOTHROW
{
// BSDs have arc4random(4) and these work even in chroot(2)
arc4random_buf(ptr, left * sizeof(*ptr));
@@ -281,7 +281,7 @@ Q_NEVER_INLINE
#ifdef Q_CC_GNU
__attribute__((cold)) // this function is pretty big, so optimize for size
#endif
-static void fallback_fill(quint32 *ptr, qssize_t left) Q_DECL_NOTHROW
+static void fallback_fill(quint32 *ptr, qsizetype left) Q_DECL_NOTHROW
{
quint32 scratch[12]; // see element count below
quint32 *end = scratch;
@@ -358,7 +358,7 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin,
Q_DECL_NOEXCEPT_EXPR(FillBufferNoexcept)
{
quint32 *buffer = begin;
- qssize_t count = end - begin;
+ qsizetype count = end - begin;
if (Q_UNLIKELY(uint(qt_randomdevice_control) & SetRandomData)) {
uint value = uint(qt_randomdevice_control) & RandomDataMask;
@@ -366,14 +366,14 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin,
return;
}
- qssize_t filled = 0;
+ qsizetype 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 =
- fillBuffer(buffer + filled, (count - filled) * qssize_t(sizeof(*buffer)));
- filled += bytesFilled / qssize_t(sizeof(*buffer));
+ qsizetype bytesFilled =
+ fillBuffer(buffer + filled, (count - filled) * qsizetype(sizeof(*buffer)));
+ filled += bytesFilled / qsizetype(sizeof(*buffer));
}
if (filled)
fallback_update_seed(*buffer);
@@ -656,6 +656,11 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
*/
/*!
+ \enum QRandomGenerator::System
+ \internal
+*/
+
+/*!
\fn QRandomGenerator::QRandomGenerator(quint32 seedValue)
Initializes this QRandomGenerator object with the value \a seedValue as
@@ -677,7 +682,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
*/
/*!
- \fn QRandomGenerator::QRandomGenerator(const quint32 *seedBuffer, qssize_t len)
+ \fn QRandomGenerator::QRandomGenerator(const quint32 *seedBuffer, qsizetype len)
\overload
Initializes this QRandomGenerator object with \a len values found in
@@ -694,7 +699,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
*/
/*!
- \fn QRandomGenerator::QRandomGenerator(const quint32 *begin, const quin32 *end)
+ \fn QRandomGenerator::QRandomGenerator(const quint32 *begin, const quint32 *end)
\overload
Initializes this QRandomGenerator object with the values found in the range
@@ -762,7 +767,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
A typedef to the type that operator()() returns. That is, quint32.
- \sa operator()()
+ \sa {QRandomGenerator::operator()}{operator()()}
*/
/*!
@@ -774,6 +779,22 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
*/
/*!
+ \fn quint32 QRandomGenerator::generate()
+
+ Generates a 32-bit random quantity and returns it.
+
+ \sa {QRandomGenerator::operator()}{operator()()}, generate64()
+ */
+
+/*!
+ \fn quint64 QRandomGenerator::generate64()
+
+ Generates a 64-bit random quantity and returns it.
+
+ \sa {QRandomGenerator::operator()}{operator()()}, generate()
+ */
+
+/*!
\fn result_type QRandomGenerator::min()
Returns the minimum value that QRandomGenerator may ever generate. That is, 0.
@@ -800,7 +821,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
\fn void QRandomGenerator::seed(std::seed_seq &seed)
\overload
- Reseeds this object using the seed sequence \a sseq as the seed.
+ Reseeds this object using the seed sequence \a seed as the seed.
*/
/*!
@@ -826,7 +847,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
\endcode
This function complies with the requirements for the function
- \c{\l{http://en.cppreference.com/w/cpp/numeric/random/seed_seq/generate}{std::seed_seq::generate}},
+ \l{http://en.cppreference.com/w/cpp/numeric/random/seed_seq/generate}{\c std::seed_seq::generate},
which requires unsigned 32-bit integer values.
Note that if the [begin, end) range refers to an area that can store more
@@ -853,7 +874,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
*/
/*!
- \fn void QRandomGenerator::fillRange(UInt *buffer, qssize_t count)
+ \fn void QRandomGenerator::fillRange(UInt *buffer, qsizetype count)
Generates \a count 32- or 64-bit quantities (depending on the type \c UInt)
and stores them in the buffer pointed by \a buffer. This is the most
@@ -906,16 +927,16 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
\endcode
The same may also be obtained by using
- \c{\l{http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution}{std::uniform_real_distribution}}
+ \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution}{\c std::uniform_real_distribution}
with parameters 0 and 1.
\sa generate(), generate64(), bounded()
*/
/*!
- \fn qreal QRandomGenerator::bounded(qreal highest)
+ \fn double QRandomGenerator::bounded(double highest)
- Generates one random qreal in the range between 0 (inclusive) and \a
+ Generates one random double in the range between 0 (inclusive) and \a
highest (exclusive). This function is equivalent to and is implemented as:
\code
@@ -931,7 +952,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
Generates one random 32-bit quantity in the range between 0 (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}}
+ \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{\c std::uniform_int_distribution}
with parameters 0 and \c{highest - 1}. That class can also be used to obtain
quantities larger than 32 bits.
@@ -969,7 +990,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
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}}
+ \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{\c std::uniform_int_distribution}
with parameters \a lowest and \c{\a highest - 1}. That class can also be used to
obtain quantities larger than 32 bits.
@@ -1098,7 +1119,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
A typedef to the type that operator()() returns. That is, quint64.
- \sa operator()()
+ \sa {QRandomGenerator64::operator()}{operator()()}
*/
/*!
@@ -1169,7 +1190,9 @@ QRandomGenerator64 QRandomGenerator64::securelySeeded()
return result;
}
-/// \internal
+/*!
+ \internal
+*/
inline QRandomGenerator::QRandomGenerator(System)
: type(SystemRNG)
{
diff --git a/src/corelib/global/qrandom.h b/src/corelib/global/qrandom.h
index bde64646a4..46d3e0e152 100644
--- a/src/corelib/global/qrandom.h
+++ b/src/corelib/global/qrandom.h
@@ -44,6 +44,13 @@
#include <algorithm> // for std::generate
#include <random> // for std::mt19937
+#ifdef min
+# undef min
+#endif
+#ifdef max
+# undef max
+#endif
+
QT_BEGIN_NAMESPACE
class QRandomGenerator
@@ -55,10 +62,10 @@ public:
QRandomGenerator(quint32 seedValue = 1)
: QRandomGenerator(&seedValue, 1)
{}
- template <qssize_t N> QRandomGenerator(const quint32 (&seedBuffer)[N])
+ template <qsizetype N> QRandomGenerator(const quint32 (&seedBuffer)[N])
: QRandomGenerator(seedBuffer, seedBuffer + N)
{}
- QRandomGenerator(const quint32 *seedBuffer, qssize_t len)
+ QRandomGenerator(const quint32 *seedBuffer, qsizetype len)
: QRandomGenerator(seedBuffer, seedBuffer + len)
{}
Q_CORE_EXPORT QRandomGenerator(std::seed_seq &sseq) Q_DECL_NOTHROW;
@@ -131,7 +138,7 @@ public:
}
template <typename UInt, IfValidUInt<UInt> = true>
- void fillRange(UInt *buffer, qssize_t count)
+ void fillRange(UInt *buffer, qsizetype count)
{
_fillRange(buffer, buffer + count);
}
@@ -160,8 +167,8 @@ public:
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 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();
@@ -177,7 +184,8 @@ private:
friend class QRandomGenerator64;
struct SystemGenerator;
struct SystemAndGlobalGenerators;
- typedef std::mt19937 RandomEngine;
+ using RandomEngine = std::mersenne_twister_engine<quint32,
+ 32,624,397,31,0x9908b0df,11,0xffffffff,7,0x9d2c5680,15,0xefc60000,18,1812433253>;
union Storage {
uint dummy;
@@ -214,10 +222,10 @@ public:
QRandomGenerator64(quint32 seedValue = 1)
: QRandomGenerator(seedValue)
{}
- template <qssize_t N> QRandomGenerator64(const quint32 (&seedBuffer)[N])
+ template <qsizetype N> QRandomGenerator64(const quint32 (&seedBuffer)[N])
: QRandomGenerator(seedBuffer)
{}
- QRandomGenerator64(const quint32 *seedBuffer, qssize_t len)
+ QRandomGenerator64(const quint32 *seedBuffer, qsizetype len)
: QRandomGenerator(seedBuffer, len)
{}
QRandomGenerator64(std::seed_seq &sseq) Q_DECL_NOTHROW
@@ -235,8 +243,8 @@ public:
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_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();
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index bac995ff25..e4888e9523 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -503,7 +503,8 @@ bool
QFile::remove()
{
Q_D(QFile);
- if (d->fileName.isEmpty()) {
+ if (d->fileName.isEmpty() &&
+ !static_cast<QFSFileEngine *>(d->engine())->isUnnamedFile()) {
qWarning("QFile::remove: Empty or null file name");
return false;
}
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index d77cdc123c..b974af80dc 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -55,6 +55,13 @@
#include <stdio.h>
#include <errno.h>
+#if QT_HAS_INCLUDE(<paths.h>)
+# include <paths.h>
+#endif
+#ifndef _PATH_TMP // from <paths.h>
+# define _PATH_TMP "/tmp"
+#endif
+
#if defined(Q_OS_MAC)
# include <QtCore/private/qcore_mac_p.h>
# include <CoreFoundation/CFBundle.h>
@@ -102,8 +109,22 @@ static int statx(int dirfd, const char *pathname, int flag, unsigned mask, struc
# endif
#endif
+#ifndef STATX_BASIC_STATS
+struct statx { mode_t stx_mode; };
+#endif
+
QT_BEGIN_NAMESPACE
+enum {
+#ifdef Q_OS_ANDROID
+ // On Android, the link(2) system call has been observed to always fail
+ // with EACCES, regardless of whether there are permission problems or not.
+ SupportsHardlinking = false
+#else
+ SupportsHardlinking = true
+#endif
+};
+
#define emptyFileEntryWarning() emptyFileEntryWarning_(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC)
static void emptyFileEntryWarning_(const char *file, int line, const char *function)
{
@@ -202,6 +223,8 @@ static inline typename QtPrivate::QEnableIf<(&T::st_atimespec, &T::st_mtimespec,
modification->tv_usec = p->st_mtimespec.tv_nsec / 1000;
}
+# ifndef st_atimensec
+// if "st_atimensec" is defined, this would expand to invalid C++
template <typename T>
static inline typename QtPrivate::QEnableIf<(&T::st_atimensec, &T::st_mtimensec, true)>::Type get(const T *p, struct timeval *access, struct timeval *modification)
{
@@ -211,6 +234,7 @@ static inline typename QtPrivate::QEnableIf<(&T::st_atimensec, &T::st_mtimensec,
modification->tv_sec = p->st_mtime;
modification->tv_usec = p->st_mtimensec / 1000;
}
+# endif
#endif
qint64 timespecToMSecs(const timespec &spec)
@@ -268,6 +292,7 @@ mtime(const T &statBuffer, int)
{ return timespecToMSecs(statBuffer.st_mtimespec); }
#endif
+#ifndef st_mtimensec
// Xtimensec
template <typename T>
Q_DECL_UNUSED static typename std::enable_if<(&T::st_atimensec, true), qint64>::type
@@ -288,8 +313,9 @@ template <typename T>
Q_DECL_UNUSED static typename std::enable_if<(&T::st_mtimensec, true), qint64>::type
mtime(const T &statBuffer, int)
{ return statBuffer.st_mtime * Q_INT64_C(1000) + statBuffer.st_mtimensec / 1000000; }
-}
-}
+#endif
+} // namespace GetFileTimes
+} // unnamed namespace
#ifdef STATX_BASIC_STATS
static int qt_real_statx(int fd, const char *pathname, int flags, struct statx *statxBuffer)
@@ -385,7 +411,6 @@ inline void QFileSystemMetaData::fillFromStatxBuf(const struct statx &statxBuffe
groupId_ = statxBuffer.stx_gid;
}
#else
-struct statx { mode_t stx_mode; };
static int qt_statx(const char *, struct statx *)
{ return -ENOSYS; }
@@ -918,7 +943,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
data.entryFlags &= ~what;
const QByteArray nativeFilePath = entry.nativeFilePath();
- bool entryExists = true; // innocent until proven otherwise
+ int entryErrno = 0; // innocent until proven otherwise
// first, we may try lstat(2). Possible outcomes:
// - success and is a symlink: filesystem entry exists, but we need stat(2)
@@ -968,7 +993,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
}
} else {
// it doesn't exist
- entryExists = false;
+ entryErrno = errno;
data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute;
}
@@ -976,8 +1001,8 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
}
// second, we try a regular stat(2)
- if (statResult != 0 && (what & QFileSystemMetaData::PosixStatFlags)) {
- if (entryExists && statResult == -1) {
+ if (statResult == -1 && (what & QFileSystemMetaData::PosixStatFlags)) {
+ if (entryErrno == 0 && statResult == -1) {
data.entryFlags &= ~QFileSystemMetaData::PosixStatFlags;
statResult = qt_statx(nativeFilePath, &statxBuffer);
if (statResult == -ENOSYS) {
@@ -991,7 +1016,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
}
if (statResult != 0) {
- entryExists = false;
+ entryErrno = errno;
data.birthTime_ = 0;
data.metadataChangeTime_ = 0;
data.modificationTime_ = 0;
@@ -1010,13 +1035,13 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
if (what & (QFileSystemMetaData::UserPermissions | QFileSystemMetaData::ExistsAttribute)) {
// calculate user permissions
auto checkAccess = [&](QFileSystemMetaData::MetaDataFlag flag, int mode) {
- if (!entryExists || (what & flag) == 0)
+ if (entryErrno != 0 || (what & flag) == 0)
return;
if (QT_ACCESS(nativeFilePath, mode) == 0) {
// access ok (and file exists)
data.entryFlags |= flag | QFileSystemMetaData::ExistsAttribute;
} else if (errno != EACCES && errno != EROFS) {
- entryExists = false;
+ entryErrno = errno;
}
};
@@ -1025,9 +1050,10 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
checkAccess(QFileSystemMetaData::UserExecutePermission, X_OK);
// if we still haven't found out if the file exists, try F_OK
- if (entryExists && (data.entryFlags & QFileSystemMetaData::ExistsAttribute) == 0) {
- entryExists = QT_ACCESS(nativeFilePath, F_OK) == 0;
- if (entryExists)
+ if (entryErrno == 0 && (data.entryFlags & QFileSystemMetaData::ExistsAttribute) == 0) {
+ if (QT_ACCESS(nativeFilePath, F_OK) == -1)
+ entryErrno = errno;
+ else
data.entryFlags |= QFileSystemMetaData::ExistsAttribute;
}
@@ -1037,13 +1063,13 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
#if defined(Q_OS_DARWIN)
if (what & QFileSystemMetaData::AliasType) {
- if (entryExists && hasResourcePropertyFlag(data, entry, kCFURLIsAliasFileKey))
+ if (entryErrno == 0 && hasResourcePropertyFlag(data, entry, kCFURLIsAliasFileKey))
data.entryFlags |= QFileSystemMetaData::AliasType;
data.knownFlagsMask |= QFileSystemMetaData::AliasType;
}
if (what & QFileSystemMetaData::BundleType) {
- if (entryExists && isPackage(data, entry))
+ if (entryErrno == 0 && isPackage(data, entry))
data.entryFlags |= QFileSystemMetaData::BundleType;
data.knownFlagsMask |= QFileSystemMetaData::BundleType;
@@ -1055,19 +1081,19 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
QString fileName = entry.fileName();
if ((fileName.size() > 0 && fileName.at(0) == QLatin1Char('.'))
#if defined(Q_OS_DARWIN)
- || (entryExists && hasResourcePropertyFlag(data, entry, kCFURLIsHiddenKey))
+ || (entryErrno == 0 && hasResourcePropertyFlag(data, entry, kCFURLIsHiddenKey))
#endif
)
data.entryFlags |= QFileSystemMetaData::HiddenAttribute;
data.knownFlagsMask |= QFileSystemMetaData::HiddenAttribute;
}
- if (!entryExists) {
+ if (entryErrno != 0) {
what &= ~QFileSystemMetaData::LinkType; // don't clear link: could be broken symlink
data.clearFlags(what);
return false;
}
- return data.hasFlags(what);
+ return true;
}
// static
@@ -1278,7 +1304,7 @@ bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSy
}
#endif
- if (::link(srcPath, tgtPath) == 0) {
+ if (SupportsHardlinking && ::link(srcPath, tgtPath) == 0) {
if (::unlink(srcPath) == 0)
return true;
@@ -1292,6 +1318,11 @@ bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSy
error = QSystemError(savedErrno, QSystemError::StandardLibraryError);
return false;
+ } else if (!SupportsHardlinking) {
+ // man 2 link on Linux has:
+ // EPERM The filesystem containing oldpath and newpath does not
+ // support the creation of hard links.
+ errno = EPERM;
}
switch (errno) {
@@ -1483,14 +1514,13 @@ QString QFileSystemEngine::tempPath()
#else
QString temp = QFile::decodeName(qgetenv("TMPDIR"));
if (temp.isEmpty()) {
+ if (false) {
#if defined(Q_OS_DARWIN) && !defined(QT_BOOTSTRAPPED)
- if (NSString *nsPath = NSTemporaryDirectory()) {
+ } else if (NSString *nsPath = NSTemporaryDirectory()) {
temp = QString::fromCFString((CFStringRef)nsPath);
- } else {
-#else
- {
#endif
- temp = QLatin1String("/tmp");
+ } else {
+ temp = QLatin1String(_PATH_TMP);
}
}
return QDir::cleanPath(temp);
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 944ca232ee..fadc058110 100644..100755
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -160,6 +160,7 @@ static TRUSTEE_W currentUserTrusteeW;
static TRUSTEE_W worldTrusteeW;
static PSID currentUserSID = 0;
static PSID worldSID = 0;
+static HANDLE currentUserImpersonatedToken = nullptr;
QT_BEGIN_NAMESPACE
@@ -180,6 +181,11 @@ GlobalSid::~GlobalSid()
::FreeSid(worldSID);
worldSID = 0;
}
+
+ if (currentUserImpersonatedToken) {
+ ::CloseHandle(currentUserImpersonatedToken);
+ currentUserImpersonatedToken = nullptr;
+ }
}
GlobalSid::GlobalSid()
@@ -210,6 +216,12 @@ GlobalSid::GlobalSid()
::CloseHandle(token);
}
+ token = nullptr;
+ if (::OpenProcessToken(hnd, TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ, &token)) {
+ ::DuplicateToken(token, SecurityImpersonation, &currentUserImpersonatedToken);
+ ::CloseHandle(token);
+ }
+
{
// Create TRUSTEE for Everyone (World)
SID_IDENTIFIER_AUTHORITY worldAuth = { SECURITY_WORLD_SID_AUTHORITY };
@@ -724,15 +736,49 @@ bool QFileSystemEngine::fillPermissions(const QFileSystemEntry &entry, QFileSyst
ACCESS_MASK access_mask;
TRUSTEE_W trustee;
if (what & QFileSystemMetaData::UserPermissions) { // user
- data.knownFlagsMask |= QFileSystemMetaData::UserPermissions;
- if (GetEffectiveRightsFromAcl(pDacl, &currentUserTrusteeW, &access_mask) != ERROR_SUCCESS)
- access_mask = (ACCESS_MASK)-1;
- if(access_mask & ReadMask)
- data.entryFlags |= QFileSystemMetaData::UserReadPermission;
- if(access_mask & WriteMask)
- data.entryFlags|= QFileSystemMetaData::UserWritePermission;
- if(access_mask & ExecMask)
- data.entryFlags|= QFileSystemMetaData::UserExecutePermission;
+ // Using AccessCheck because GetEffectiveRightsFromAcl doesn't account for elevation
+ if (currentUserImpersonatedToken) {
+ GENERIC_MAPPING mapping = {FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS};
+ PRIVILEGE_SET privileges;
+ DWORD grantedAccess;
+ BOOL result;
+
+ data.knownFlagsMask |= QFileSystemMetaData::UserPermissions;
+ DWORD genericAccessRights = GENERIC_READ;
+ ::MapGenericMask(&genericAccessRights, &mapping);
+
+ DWORD privilegesLength = sizeof(privileges);
+ if (::AccessCheck(pSD, currentUserImpersonatedToken, genericAccessRights,
+ &mapping, &privileges, &privilegesLength, &grantedAccess, &result) && result) {
+ data.entryFlags |= QFileSystemMetaData::UserReadPermission;
+ }
+
+ privilegesLength = sizeof(privileges);
+ genericAccessRights = GENERIC_WRITE;
+ ::MapGenericMask(&genericAccessRights, &mapping);
+ if (::AccessCheck(pSD, currentUserImpersonatedToken, genericAccessRights,
+ &mapping, &privileges, &privilegesLength, &grantedAccess, &result) && result) {
+ data.entryFlags |= QFileSystemMetaData::UserWritePermission;
+ }
+
+ privilegesLength = sizeof(privileges);
+ genericAccessRights = GENERIC_EXECUTE;
+ ::MapGenericMask(&genericAccessRights, &mapping);
+ if (::AccessCheck(pSD, currentUserImpersonatedToken, genericAccessRights,
+ &mapping, &privileges, &privilegesLength, &grantedAccess, &result) && result) {
+ data.entryFlags |= QFileSystemMetaData::UserExecutePermission;
+ }
+ } else { // fallback to GetEffectiveRightsFromAcl
+ data.knownFlagsMask |= QFileSystemMetaData::UserPermissions;
+ if (GetEffectiveRightsFromAclW(pDacl, &currentUserTrusteeW, &access_mask) != ERROR_SUCCESS)
+ access_mask = ACCESS_MASK(-1);
+ if (access_mask & ReadMask)
+ data.entryFlags |= QFileSystemMetaData::UserReadPermission;
+ if (access_mask & WriteMask)
+ data.entryFlags|= QFileSystemMetaData::UserWritePermission;
+ if (access_mask & ExecMask)
+ data.entryFlags|= QFileSystemMetaData::UserExecutePermission;
+ }
}
if (what & QFileSystemMetaData::OwnerPermissions) { // owner
data.knownFlagsMask |= QFileSystemMetaData::OwnerPermissions;
diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h
index 55e44d52c7..4d2a5acb9b 100644
--- a/src/corelib/io/qfilesystemmetadata_p.h
+++ b/src/corelib/io/qfilesystemmetadata_p.h
@@ -64,6 +64,10 @@
# endif
#endif
+#ifdef Q_OS_UNIX
+struct statx;
+#endif
+
QT_BEGIN_NAMESPACE
class QFileSystemEngine;
diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h
index bf90995fdd..16ba161b75 100644
--- a/src/corelib/io/qfsfileengine_p.h
+++ b/src/corelib/io/qfsfileengine_p.h
@@ -112,6 +112,9 @@ public:
qint64 write(const char *data, qint64 len) override;
bool cloneTo(QAbstractFileEngine *target) override;
+ virtual bool isUnnamedFile() const
+ { return false; }
+
bool extension(Extension extension, const ExtensionOption *option = 0, ExtensionReturn *output = 0) override;
bool supportsExtension(Extension extension) const override;
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index 1bf61017f6..b5f8e30b80 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -255,7 +255,7 @@ void QLoggingSettingsParser::parseNextLine(QStringRef line)
QLoggingRegistry::QLoggingRegistry()
: categoryFilter(defaultCategoryFilter)
{
- initalizeRules(); // Init on first use
+ initializeRules(); // Init on first use
}
static bool qtLoggingDebug()
@@ -284,7 +284,7 @@ static QVector<QLoggingRule> loadRulesFromFile(const QString &filePath)
Initializes the rules database by loading
$QT_LOGGING_CONF, $QT_LOGGING_RULES, and .config/QtProject/qtlogging.ini.
*/
-void QLoggingRegistry::initalizeRules()
+void QLoggingRegistry::initializeRules()
{
QVector<QLoggingRule> er, qr, cr;
// get rules from environment
diff --git a/src/corelib/io/qloggingregistry_p.h b/src/corelib/io/qloggingregistry_p.h
index a3857d3588..12a1f166b3 100644
--- a/src/corelib/io/qloggingregistry_p.h
+++ b/src/corelib/io/qloggingregistry_p.h
@@ -113,7 +113,7 @@ class Q_AUTOTEST_EXPORT QLoggingRegistry
public:
QLoggingRegistry();
- void initalizeRules();
+ void initializeRules();
void registerCategory(QLoggingCategory *category, QtMsgType enableForLevel);
void unregisterCategory(QLoggingCategory *category);
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 41f4b2aa83..2ee680a7c6 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -99,6 +99,10 @@ QT_END_NAMESPACE
#include <private/qcore_unix_p.h>
#endif
+#if QT_HAS_INCLUDE(<paths.h>)
+#include <paths.h>
+#endif
+
QT_BEGIN_NAMESPACE
/*!
@@ -2637,6 +2641,8 @@ QString QProcess::nullDevice()
{
#ifdef Q_OS_WIN
return QStringLiteral("\\\\.\\NUL");
+#elif defined(_PATH_DEVNULL)
+ return QStringLiteral(_PATH_DEVNULL);
#else
return QStringLiteral("/dev/null");
#endif
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index 9a63374e6f..35a0de4fb7 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -86,8 +86,8 @@ public:
}
const QChar *m_data;
- qssize_t m_len;
- qssize_t m_pos = 0;
+ qsizetype m_len;
+ qsizetype m_pos = 0;
QChar m_splitChar = QLatin1Char('/');
};
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index d0cbc82c56..bbc66120b5 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -1451,7 +1451,7 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile)
Files that we can't read (because of permissions or
because they don't exist) are treated as empty files.
*/
- if (file.isReadable() && fileInfo.size() != 0) {
+ if (file.isReadable() && file.size() != 0) {
bool ok = false;
#ifdef Q_OS_MAC
if (format == QSettings::NativeFormat) {
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index c3d45caf0e..b3a5bd797a 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -48,6 +48,14 @@
#include <qcoreapplication.h>
#endif
+#if QT_HAS_INCLUDE(<paths.h>)
+#include <paths.h>
+#endif
+
+#ifdef Q_OS_UNIX
+#include <unistd.h>
+#endif
+
#ifndef QT_NO_STANDARDPATHS
QT_BEGIN_NAMESPACE
@@ -509,6 +517,27 @@ QString QStandardPaths::findExecutable(const QString &executableName, const QStr
QStringList searchPaths = paths;
if (paths.isEmpty()) {
QByteArray pEnv = qgetenv("PATH");
+ if (Q_UNLIKELY(pEnv.isNull())) {
+ // Get a default path. POSIX.1 does not actually require this, but
+ // most Unix libc fall back to confstr(_CS_PATH) if the PATH
+ // environment variable isn't set. Let's try to do the same.
+#if defined(_PATH_DEFPATH)
+ // BSD API.
+ pEnv = _PATH_DEFPATH;
+#elif defined(_CS_PATH)
+ // POSIX API.
+ size_t n = confstr(_CS_PATH, nullptr, 0);
+ if (n) {
+ pEnv.resize(n);
+ // size()+1 is ok because QByteArray always has an extra NUL-terminator
+ confstr(_CS_PATH, pEnv.data(), pEnv.size() + 1);
+ }
+#else
+ // Windows SDK's execvpe() does not have a fallback, so we won't
+ // apply one either.
+#endif
+ }
+
// Remove trailing slashes, which occur on Windows.
const QStringList rawPaths = QString::fromLocal8Bit(pEnv.constData()).split(QDir::listSeparator(), QString::SkipEmptyParts);
searchPaths.reserve(rawPaths.size());
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index 6d8b6ee1a0..7664b77d81 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -108,6 +108,13 @@
# endif // QT_LARGEFILE_SUPPORT
#endif // Q_OS_BSD4
+#if QT_HAS_INCLUDE(<paths.h>)
+# include <paths.h>
+#endif
+#ifndef _PATH_MOUNTED
+# define _PATH_MOUNTED "/etc/mnttab"
+#endif
+
QT_BEGIN_NAMESPACE
class QStorageIterator
@@ -274,11 +281,9 @@ inline QByteArray QStorageIterator::subvolume() const
}
#elif defined(Q_OS_SOLARIS)
-static const char pathMounted[] = "/etc/mnttab";
-
inline QStorageIterator::QStorageIterator()
{
- const int fd = qt_safe_open(pathMounted, O_RDONLY);
+ const int fd = qt_safe_open(_PATH_MOUNTED, O_RDONLY);
fp = ::fdopen(fd, "r");
}
@@ -319,11 +324,9 @@ inline QByteArray QStorageIterator::subvolume() const
}
#elif defined(Q_OS_ANDROID)
-static const QLatin1String pathMounted("/proc/mounts");
-
inline QStorageIterator::QStorageIterator()
{
- file.setFileName(pathMounted);
+ file.setFileName(_PATH_MOUNTED);
file.open(QIODevice::ReadOnly | QIODevice::Text);
}
@@ -380,7 +383,6 @@ inline QByteArray QStorageIterator::subvolume() const
}
#elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
-static const char pathMounted[] = "/etc/mtab";
static const int bufferSize = 1024; // 2 paths (mount point+device) and metainfo;
// should be enough
@@ -397,7 +399,7 @@ inline QStorageIterator::QStorageIterator() :
usingMountinfo = true;
} else {
usingMountinfo = false;
- fp = ::setmntent(pathMounted, "r");
+ fp = ::setmntent(_PATH_MOUNTED, "r");
}
}
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index b8d3e859cf..35699d52df 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -393,7 +393,9 @@ bool QTemporaryFileEngine::remove()
// we must explicitly call QFSFileEngine::close() before we remove it.
d->unmapAll();
QFSFileEngine::close();
- if (isUnnamedFile() || QFSFileEngine::remove()) {
+ if (isUnnamedFile())
+ return true;
+ if (!filePathIsTemplate && QFSFileEngine::remove()) {
d->fileEntry.clear();
// If a QTemporaryFile is constructed using a template file path, the path
// is generated in QTemporaryFileEngine::open() and then filePathIsTemplate
@@ -511,7 +513,10 @@ bool QTemporaryFileEngine::materializeUnnamedFile(const QString &newName, QTempo
bool QTemporaryFileEngine::isUnnamedFile() const
{
#ifdef LINUX_UNNAMED_TMPFILE
- Q_ASSERT(unnamedFile == d_func()->fileEntry.isEmpty());
+ if (unnamedFile) {
+ Q_ASSERT(d_func()->fileEntry.isEmpty());
+ Q_ASSERT(filePathIsTemplate);
+ }
return unnamedFile;
#else
return false;
@@ -749,10 +754,21 @@ bool QTemporaryFile::autoRemove() const
}
/*!
- Sets the QTemporaryFile into auto-remove mode if \a b is true.
+ Sets the QTemporaryFile into auto-remove mode if \a b is \c true.
Auto-remove is on by default.
+ If you set this property to \c false, ensure the application provides a way
+ to remove the file once it is no longer needed, including passing the
+ responsibility on to another process. Always use the fileName() function to
+ obtain the name and never try to guess the name that QTemporaryFile has
+ generated.
+
+ On some systems, if fileName() is not called before closing the file, the
+ temporary file may be removed regardless of the state of this property.
+ This behavior should not be relied upon, so application code should either
+ call fileName() or leave the auto removal functionality enabled.
+
\sa autoRemove(), remove()
*/
void QTemporaryFile::setAutoRemove(bool b)
diff --git a/src/corelib/io/qtemporaryfile_p.h b/src/corelib/io/qtemporaryfile_p.h
index 46a0d7aba3..fb8887af53 100644
--- a/src/corelib/io/qtemporaryfile_p.h
+++ b/src/corelib/io/qtemporaryfile_p.h
@@ -58,7 +58,7 @@
#include "private/qfile_p.h"
#include "qtemporaryfile.h"
-#ifdef Q_OS_LINUX
+#if defined(Q_OS_LINUX) && QT_CONFIG(linkat)
# include <fcntl.h>
# ifdef O_TMPFILE
// some early libc support had the wrong values for O_TMPFILE
@@ -74,8 +74,8 @@ QT_BEGIN_NAMESPACE
struct QTemporaryFileName
{
QFileSystemEntry::NativePath path;
- qssize_t pos;
- qssize_t length;
+ qsizetype pos;
+ qsizetype length;
QTemporaryFileName(const QString &templateName);
QFileSystemEntry::NativePath generateNext();
@@ -140,7 +140,7 @@ public:
enum MaterializationMode { Overwrite, DontOverwrite, NameIsTemplate };
bool materializeUnnamedFile(const QString &newName, MaterializationMode mode);
- bool isUnnamedFile() const;
+ bool isUnnamedFile() const override final;
const QString &templateName;
quint32 fileMode;
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index cf7ed130ba..4587b9fcd6 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -90,11 +90,6 @@
fromPercentEncoding() and toPercentEncoding() which deal with
percent encoding and decoding of QString objects.
- Calling isRelative() will tell whether or not the URL is
- relative. A relative URL can be resolved by passing it as argument
- to resolved(), which returns an absolute URL. isParentOf() is used
- for determining whether one URL is a parent of another.
-
fromLocalFile() constructs a QUrl by parsing a local
file path. toLocalFile() converts a URL to a local file path.
@@ -116,6 +111,37 @@
from freedesktop.org, provided that the locale encodes file names using
UTF-8 (required by IDN).
+ \section2 Relative URLs vs Relative Paths
+
+ Calling isRelative() will return whether or not the URL is relative.
+ A relative URL has no \l {scheme}. For example:
+
+ \code
+ qDebug() << QUrl("main.qml").isRelative(); // true: no scheme
+ qDebug() << QUrl("qml/main.qml").isRelative(); // true: no scheme
+ qDebug() << QUrl("file:main.qml").isRelative(); // false: has "file" scheme
+ qDebug() << QUrl("file:qml/main.qml").isRelative(); // false: has "file" scheme
+ \endcode
+
+ Notice that a URL can be absolute while containing a relative path, and
+ vice versa:
+
+ \code
+ // Absolute URL, relative path
+ QUrl url("file:file.txt");
+ qDebug() << url.isRelative(); // false: has "file" scheme
+ qDebug() << QDir::isAbsolutePath(url.path()); // false: relative path
+
+ // Relative URL, absolute path
+ url = QUrl("/home/user/file.txt");
+ qDebug() << url.isRelative(); // true: has no scheme
+ qDebug() << QDir::isAbsolutePath(url.path()); // true: absolute path
+ \endcode
+
+ A relative URL can be resolved by passing it as an argument to resolved(),
+ which returns an absolute URL. isParentOf() is used for determining whether
+ one URL is a parent of another.
+
\section2 Error checking
QUrl is capable of detecting many errors in URLs while parsing it or when
@@ -2539,6 +2565,12 @@ void QUrl::setPath(const QString &path, ParsingMode mode)
/*!
Returns the path of the URL.
+ \code
+ qDebug() << QUrl("file:file.txt").path(); // "file.txt"
+ qDebug() << QUrl("/home/user/file.txt").path(); // "/home/user/file.txt"
+ qDebug() << QUrl("http://www.example.com/test/123").path(); // "/test/123"
+ \endcode
+
The \a options argument controls how to format the path component. All
values produce an unambiguous result. With QUrl::FullyDecoded, all
percent-encoded sequences are decoded; otherwise, the returned value may
@@ -2549,6 +2581,31 @@ void QUrl::setPath(const QString &path, ParsingMode mode)
sequences are present. It is recommended to use that value when the result
will be used in a non-URL context, such as sending to an FTP server.
+ An example of data loss is when you have non-Unicode percent-encoded sequences
+ and use FullyDecoded (the default):
+
+ \code
+ qDebug() << QUrl("/foo%FFbar").path();
+ \endcode
+
+ In this example, there will be some level of data loss because the \c %FF cannot
+ be converted.
+
+ Data loss can also occur when the path contains sub-delimiters (such as \c +):
+
+ \code
+ qDebug() << QUrl("/foo+bar%2B").path(); // "/foo+bar+"
+ \endcode
+
+ Other decoding examples:
+
+ \code
+ const QUrl url("/tmp/Mambo %235%3F.mp3");
+ qDebug() << url.path(QUrl::FullyDecoded); // "/tmp/Mambo #5?.mp3"
+ qDebug() << url.path(QUrl::PrettyDecoded); // "/tmp/Mambo #5?.mp3"
+ qDebug() << url.path(QUrl::FullyEncoded); // "/tmp/Mambo%20%235%3F.mp3"
+ \endcode
+
\sa setPath()
*/
QString QUrl::path(ComponentFormattingOptions options) const
@@ -3257,6 +3314,8 @@ QUrl QUrl::resolved(const QUrl &relative) const
equivalent to calling scheme().isEmpty().
Relative references are defined in RFC 3986 section 4.2.
+
+ \sa {Relative URLs vs Relative Paths}
*/
bool QUrl::isRelative() const
{
@@ -3796,6 +3855,41 @@ bool QUrl::isDetached() const
An empty \a localFile leads to an empty URL (since Qt 5.4).
+ \code
+ qDebug() << QUrl::fromLocalFile("file.txt"); // QUrl("file:file.txt")
+ qDebug() << QUrl::fromLocalFile("/home/user/file.txt"); // QUrl("file:///home/user/file.txt")
+ qDebug() << QUrl::fromLocalFile("file:file.txt"); // doesn't make sense; expects path, not url with scheme
+ \endcode
+
+ In the first line in snippet above, a file URL is constructed from a
+ local, relative path. A file URL with a relative path only makes sense
+ if there is a base URL to resolve it against. For example:
+
+ \code
+ QUrl url = QUrl::fromLocalFile("file.txt");
+ QUrl baseUrl = QUrl("file:/home/user/");
+ // wrong: prints QUrl("file:file.txt"), as url already has a scheme
+ qDebug() << baseUrl.resolved(url);
+ \endcode
+
+ To resolve such a URL, it's necessary to remove the scheme beforehand:
+
+ \code
+ // correct: prints QUrl("file:///home/user/file.txt")
+ url.setScheme(QString());
+ qDebug() << baseUrl.resolved(url);
+ \endcode
+
+ For this reason, it is better to use a relative URL (that is, no scheme)
+ for relative file paths:
+
+ \code
+ QUrl url = QUrl("file.txt");
+ QUrl baseUrl = QUrl("file:/home/user/");
+ // prints QUrl("file:///home/user/file.txt")
+ qDebug() << baseUrl.resolved(url);
+ \endcode
+
\sa toLocalFile(), isLocalFile(), QDir::toNativeSeparators()
*/
QUrl QUrl::fromLocalFile(const QString &localFile)
@@ -3840,6 +3934,12 @@ QUrl QUrl::fromLocalFile(const QString &localFile)
returned value in the form found on SMB networks (for example,
"//servername/path/to/file.txt").
+ \code
+ qDebug() << QUrl("file:file.txt").toLocalFile(); // "file:file.txt"
+ qDebug() << QUrl("file:/home/user/file.txt").toLocalFile(); // "file:///home/user/file.txt"
+ qDebug() << QUrl("file.txt").toLocalFile(); // ""; wasn't a local file as it had no scheme
+ \endcode
+
Note: if the path component of this URL contains a non-UTF-8 binary
sequence (such as %80), the behaviour of this function is undefined.
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index b4ba1a2823..c70fbaf63b 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -2660,8 +2660,8 @@ void QSortFilterProxyModel::setFilterRole(int role)
}
/*!
- \since 5.9
- \property QSortFilterProxyModel::recursiveFiltering
+ \since 5.10
+ \property QSortFilterProxyModel::recursiveFilteringEnabled
\brief whether the filter to be applied recursively on children, and for
any matching child, its parents will be visible as well.
@@ -2669,13 +2669,13 @@ void QSortFilterProxyModel::setFilterRole(int role)
\sa filterAcceptsRow()
*/
-bool QSortFilterProxyModel::recursiveFiltering() const
+bool QSortFilterProxyModel::isRecursiveFilteringEnabled() const
{
Q_D(const QSortFilterProxyModel);
return d->filter_recursive;
}
-void QSortFilterProxyModel::setRecursiveFiltering(bool recursive)
+void QSortFilterProxyModel::setRecursiveFilteringEnabled(bool recursive)
{
Q_D(QSortFilterProxyModel);
if (d->filter_recursive == recursive)
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.h b/src/corelib/itemmodels/qsortfilterproxymodel.h
index 2f93836544..6c620f4812 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.h
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.h
@@ -67,7 +67,7 @@ class Q_CORE_EXPORT QSortFilterProxyModel : public QAbstractProxyModel
Q_PROPERTY(bool isSortLocaleAware READ isSortLocaleAware WRITE setSortLocaleAware)
Q_PROPERTY(int sortRole READ sortRole WRITE setSortRole)
Q_PROPERTY(int filterRole READ filterRole WRITE setFilterRole)
- Q_PROPERTY(bool recursiveFiltering READ recursiveFiltering WRITE setRecursiveFiltering)
+ Q_PROPERTY(bool recursiveFilteringEnabled READ isRecursiveFilteringEnabled WRITE setRecursiveFilteringEnabled)
public:
explicit QSortFilterProxyModel(QObject *parent = nullptr);
@@ -108,8 +108,8 @@ public:
int filterRole() const;
void setFilterRole(int role);
- bool recursiveFiltering() const;
- void setRecursiveFiltering(bool recursive);
+ bool isRecursiveFilteringEnabled() const;
+ void setRecursiveFilteringEnabled(bool recursive);
public Q_SLOTS:
void setFilterRegExp(const QString &pattern);
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index 8abe9b2b44..2336278b17 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -188,7 +188,7 @@ vxworks {
kernel/qfunctions_vxworks.h
}
-qqnx_pps {
+qnx:qtConfig(qqnx_pps) {
QMAKE_USE_PRIVATE += pps
SOURCES += \
kernel/qppsattribute.cpp \
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 0ba841bd30..38bcba275f 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -2202,11 +2202,11 @@ QString QCoreApplication::applicationFilePath()
QCoreApplicationPrivate *d = self->d_func();
if (d->argc) {
- static const char *procName = d->argv[0];
- if (qstrcmp(procName, d->argv[0]) != 0) {
+ static QByteArray procName = QByteArray(d->argv[0]);
+ if (procName != d->argv[0]) {
// clear the cache if the procname changes, so we reprocess it.
QCoreApplicationPrivate::clearApplicationFilePath();
- procName = d->argv[0];
+ procName = QByteArray(d->argv[0]);
}
}
diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp
index c7109a6506..04c9a9bcba 100644
--- a/src/corelib/kernel/qjnihelpers.cpp
+++ b/src/corelib/kernel/qjnihelpers.cpp
@@ -592,7 +592,7 @@ void QtAndroidPrivate::setOnBindListener(QtAndroidPrivate::OnBindListener *liste
{
QMutexLocker lock(g_onBindListenerMutex);
*g_onBindListener = listener;
- if (!(*g_serviceSetupLockers)--)
+ if (!g_serviceSetupLockers->deref())
g_waitForServiceSetupSemaphore->release();
}
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 650523d01c..30cae20359 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -4796,7 +4796,7 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s
QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type,
const int *types, const QMetaObject *senderMetaObject)
{
- if (!sender || !slotObj || !senderMetaObject) {
+ if (!sender || !receiver || !slotObj || !senderMetaObject) {
qWarning("QObject::connect: invalid null parameter");
if (slotObj)
slotObj->destroyIfLastRef();
diff --git a/src/corelib/kernel/qppsobjectprivate_p.h b/src/corelib/kernel/qppsobjectprivate_p.h
index e1d54e58de..dae44e3609 100644
--- a/src/corelib/kernel/qppsobjectprivate_p.h
+++ b/src/corelib/kernel/qppsobjectprivate_p.h
@@ -57,13 +57,15 @@
#include <QDebug>
#include <sys/pps.h>
+#include <private/qobject_p.h>
QT_BEGIN_NAMESPACE
class QSocketNotifier;
-class QPpsObjectPrivate
+class QPpsObjectPrivate : public QObjectPrivate
{
+ Q_DECLARE_PUBLIC(QPpsObject)
public:
explicit QPpsObjectPrivate(const QString &path);
diff --git a/src/corelib/plugin/qlibrary_win.cpp b/src/corelib/plugin/qlibrary_win.cpp
index a4d3f67c27..9368e53b3f 100644
--- a/src/corelib/plugin/qlibrary_win.cpp
+++ b/src/corelib/plugin/qlibrary_win.cpp
@@ -116,7 +116,7 @@ bool QLibraryPrivate::load_sys()
#endif
if (!pHnd) {
errorString = QLibrary::tr("Cannot load library %1: %2").arg(
- QDir::toNativeSeparators(fileName)).arg(qt_error_string());
+ QDir::toNativeSeparators(fileName), qt_error_string());
} else {
// Query the actual name of the library that was loaded
errorString.clear();
@@ -152,7 +152,7 @@ bool QLibraryPrivate::unload_sys()
{
if (!FreeLibrary(pHnd)) {
errorString = QLibrary::tr("Cannot unload library %1: %2").arg(
- QDir::toNativeSeparators(fileName)).arg(qt_error_string());
+ QDir::toNativeSeparators(fileName), qt_error_string());
return false;
}
errorString.clear();
@@ -164,8 +164,7 @@ QFunctionPointer QLibraryPrivate::resolve_sys(const char* symbol)
FARPROC address = GetProcAddress(pHnd, symbol);
if (!address) {
errorString = QLibrary::tr("Cannot resolve symbol \"%1\" in %2: %3").arg(
- QString::fromLatin1(symbol)).arg(
- QDir::toNativeSeparators(fileName)).arg(qt_error_string());
+ QString::fromLatin1(symbol), QDir::toNativeSeparators(fileName), qt_error_string());
} else {
errorString.clear();
}
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index e58ddaff44..24734f99ac 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -3096,10 +3096,12 @@ int QSignalEventGenerator::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
void QSignalEventGenerator::execute(void **_a)
{
+ auto machinePrivate = QStateMachinePrivate::get(qobject_cast<QStateMachine*>(parent()));
+ if (machinePrivate->state != QStateMachinePrivate::Running)
+ return;
int signalIndex = senderSignalIndex();
Q_ASSERT(signalIndex != -1);
- QStateMachine *machine = qobject_cast<QStateMachine*>(parent());
- QStateMachinePrivate::get(machine)->handleTransitionSignal(sender(), signalIndex, _a);
+ machinePrivate->handleTransitionSignal(sender(), signalIndex, _a);
}
QSignalEventGenerator::QSignalEventGenerator(QStateMachine *parent)
diff --git a/src/corelib/thread/qfuturewatcher.h b/src/corelib/thread/qfuturewatcher.h
index 1d984a3205..fb7dd30499 100644
--- a/src/corelib/thread/qfuturewatcher.h
+++ b/src/corelib/thread/qfuturewatcher.h
@@ -114,7 +114,7 @@ template <typename T>
class QFutureWatcher : public QFutureWatcherBase
{
public:
- explicit QFutureWatcher(QObject *_parent = 0)
+ explicit QFutureWatcher(QObject *_parent = nullptr)
: QFutureWatcherBase(_parent)
{ }
~QFutureWatcher()
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index f6fc672486..050f37dcd2 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -2227,7 +2227,7 @@ static QString qt_tzname(QDateTimePrivate::DaylightStatus daylightStatus)
#endif // Q_OS_WIN
}
-#ifndef QT_BOOTSTRAPPED
+#if QT_CONFIG(datetimeparser) && QT_CONFIG(timezone)
/*
\internal
Implemented here to share qt_tzname()
@@ -2245,7 +2245,7 @@ int QDateTimeParser::startsWithLocalTimeZone(const QStringRef name)
}
return 0;
}
-#endif // QT_BOOTSTRAPPED
+#endif // datetimeparser && timezone
// Calls the platform variant of mktime for the given date, time and daylightStatus,
// and updates the date, time, daylightStatus and abbreviation with the returned values
diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h
index a390bce95f..5a7b75db62 100644
--- a/src/corelib/tools/qdatetime.h
+++ b/src/corelib/tools/qdatetime.h
@@ -81,7 +81,7 @@ public:
int daysInYear() const;
int weekNumber(int *yearNum = nullptr) const;
-#if QT_DEPRECATED_SINCE(5, 11) && !defined QT_NO_TEXTDATE
+#if QT_DEPRECATED_SINCE(5, 10) && !defined QT_NO_TEXTDATE
QT_DEPRECATED_X("Use QLocale::monthName or QLocale::standaloneMonthName")
static QString shortMonthName(int month, MonthNameType type = DateFormat);
QT_DEPRECATED_X("Use QLocale::dayName or QLocale::standaloneDayName")
diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp
index f0c8b5a799..551e01e076 100644
--- a/src/corelib/tools/qdatetimeparser.cpp
+++ b/src/corelib/tools/qdatetimeparser.cpp
@@ -195,9 +195,11 @@ bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const
return false;
// Preserve zone:
- v = (tspec == Qt::TimeZone
- ? QDateTime(newDate, newTime, v.timeZone())
- : QDateTime(newDate, newTime, tspec, offset));
+ v =
+#if QT_CONFIG(timezone)
+ tspec == Qt::TimeZone ? QDateTime(newDate, newTime, v.timeZone()) :
+#endif
+ QDateTime(newDate, newTime, tspec, offset);
return true;
}
@@ -213,7 +215,9 @@ int QDateTimeParser::absoluteMax(int s, const QDateTime &cur) const
{
const SectionNode &sn = sectionNode(s);
switch (sn.type) {
+#if QT_CONFIG(timezone)
case TimeZoneSection: return QTimeZone::MaxUtcOffsetSecs;
+#endif
case Hour24Section:
case Hour12Section: return 23; // this is special-cased in
// parseSection. We want it to be
@@ -248,7 +252,9 @@ int QDateTimeParser::absoluteMin(int s) const
{
const SectionNode &sn = sectionNode(s);
switch (sn.type) {
+#if QT_CONFIG(timezone)
case TimeZoneSection: return QTimeZone::MinUtcOffsetSecs;
+#endif
case Hour24Section:
case Hour12Section:
case MinuteSection:
@@ -766,9 +772,11 @@ QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionIndex,
text->replace(offset, used, sectiontext.constData(), used);
break; }
case TimeZoneSection:
+#if QT_CONFIG(timezone)
result = findTimeZone(sectionTextRef, currentValue,
absoluteMax(sectionIndex),
absoluteMin(sectionIndex));
+#endif
break;
case MonthSection:
case DayOfWeekSectionShort:
@@ -1091,17 +1099,21 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
int dayofweek = defaultDate.dayOfWeek();
Qt::TimeSpec tspec = defaultValue.timeSpec();
int zoneOffset = 0; // In seconds; local - UTC
+#if QT_CONFIG(timezone)
QTimeZone timeZone;
+#endif
switch (tspec) {
case Qt::OffsetFromUTC: // timeZone is ignored
zoneOffset = defaultValue.offsetFromUtc();
break;
+#if QT_CONFIG(timezone)
case Qt::TimeZone:
timeZone = defaultValue.timeZone();
if (timeZone.isValid())
zoneOffset = timeZone.offsetFromUtc(defaultValue);
// else: is there anything we can do about this ?
break;
+#endif
default: // zoneOffset and timeZone are ignored
break;
}
@@ -1126,9 +1138,11 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
{
const QDate date = actualDate(isSet, year, year2digits, month, day, dayofweek);
const QTime time = actualTime(isSet, hour, hour12, ampm, minute, second, msec);
- sect = parseSection(tspec == Qt::TimeZone
- ? QDateTime(date, time, timeZone)
- : QDateTime(date, time, tspec, zoneOffset),
+ sect = parseSection(
+#if QT_CONFIG(timezone)
+ tspec == Qt::TimeZone ? QDateTime(date, time, timeZone) :
+#endif
+ QDateTime(date, time, tspec, zoneOffset),
index, pos, input);
}
@@ -1154,16 +1168,20 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
case TimeZoneSection:
current = &zoneOffset;
if (sect.used > 0) {
- // Synchronize with what findTimeZone() found:
+#if QT_CONFIG(timezone) // Synchronize with what findTimeZone() found:
QStringRef zoneName = input->midRef(pos, sect.used);
Q_ASSERT(!zoneName.isEmpty()); // sect.used > 0
- const QByteArray latinZone(zoneName.toLatin1());
+ const QByteArray latinZone(zoneName == QLatin1String("Z")
+ ? QByteArray("UTC") : zoneName.toLatin1());
timeZone = QTimeZone(latinZone);
tspec = timeZone.isValid()
? (QTimeZone::isTimeZoneIdAvailable(latinZone)
? Qt::TimeZone
: Qt::OffsetFromUTC)
: (Q_ASSERT(startsWithLocalTimeZone(zoneName)), Qt::LocalTime);
+#else
+ tspec = Qt::LocalTime;
+#endif
}
break;
case Hour24Section: current = &hour; break;
@@ -1321,9 +1339,11 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
const QDate date(year, month, day);
const QTime time(hour, minute, second, msec);
- return StateNode(tspec == Qt::TimeZone
- ? QDateTime(date, time, timeZone)
- : QDateTime(date, time, tspec, zoneOffset),
+ return StateNode(
+#if QT_CONFIG(timezone)
+ tspec == Qt::TimeZone ? QDateTime(date, time, timeZone) :
+#endif
+ QDateTime(date, time, tspec, zoneOffset),
state, padding, conflicts);
}
@@ -1571,6 +1591,7 @@ QDateTimeParser::ParsedSection
QDateTimeParser::findTimeZone(QStringRef str, const QDateTime &when,
int maxVal, int minVal) const
{
+#if QT_CONFIG(timezone)
int index = startsWithLocalTimeZone(str);
int offset;
@@ -1597,6 +1618,10 @@ QDateTimeParser::findTimeZone(QStringRef str, const QDateTime &when,
while (index > 0) {
str.truncate(index);
+ if (str == QLatin1String("Z")) {
+ offset = 0; // "Zulu" time - a.k.a. UTC
+ break;
+ }
QTimeZone zone(str.toLatin1());
if (zone.isValid()) {
offset = zone.offsetFromUtc(when);
@@ -1609,6 +1634,7 @@ QDateTimeParser::findTimeZone(QStringRef str, const QDateTime &when,
if (index > 0 && maxVal >= offset && offset >= minVal)
return ParsedSection(Acceptable, offset, index);
+#endif // timezone
return ParsedSection();
}
diff --git a/src/corelib/tools/qdatetimeparser_p.h b/src/corelib/tools/qdatetimeparser_p.h
index c4afef0193..c9e63fe307 100644
--- a/src/corelib/tools/qdatetimeparser_p.h
+++ b/src/corelib/tools/qdatetimeparser_p.h
@@ -223,7 +223,10 @@ private:
QString *dayName = 0, int *used = 0) const;
ParsedSection findTimeZone(QStringRef str, const QDateTime &when,
int maxVal, int minVal) const;
- static int startsWithLocalTimeZone(const QStringRef name); // implemented in qdatetime.cpp
+#if QT_CONFIG(timezone)
+ // Implemented in qdatetime.cpp:
+ static int startsWithLocalTimeZone(const QStringRef name);
+#endif
enum AmPmFinder {
Neither = -1,
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index c785a5882a..5598dfe237 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -580,7 +580,7 @@ int qt_repeatCount(QStringView s)
if (s.isEmpty())
return 0;
const QChar c = s.front();
- qssize_t j = 1;
+ qsizetype j = 1;
while (j < s.size() && s.at(j) == c)
++j;
return int(j);
@@ -3459,7 +3459,7 @@ bool QLocaleData::validateChars(QStringView str, NumberMode numMode, QByteArray
bool dec = false;
int decDigitCnt = 0;
- for (qssize_t i = 0; i < str.size(); ++i) {
+ for (qsizetype i = 0; i < str.size(); ++i) {
char c = digitToCLocale(str.at(i));
if (c >= '0' && c <= '9') {
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index fc72c6e32c..a5b9096835 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -115,9 +115,9 @@ struct QMapNode : public QMapNodeBase
inline QMapNode *leftNode() const { return static_cast<QMapNode *>(left); }
inline QMapNode *rightNode() const { return static_cast<QMapNode *>(right); }
- inline const QMapNode *nextNode() const { return static_cast<const QMapNode *>(QMapNodeBase::nextNode()); }
+ inline const QMapNode *nextNode() const { return reinterpret_cast<const QMapNode *>(QMapNodeBase::nextNode()); }
inline const QMapNode *previousNode() const { return static_cast<const QMapNode *>(QMapNodeBase::previousNode()); }
- inline QMapNode *nextNode() { return static_cast<QMapNode *>(QMapNodeBase::nextNode()); }
+ inline QMapNode *nextNode() { return reinterpret_cast<QMapNode *>(QMapNodeBase::nextNode()); }
inline QMapNode *previousNode() { return static_cast<QMapNode *>(QMapNodeBase::previousNode()); }
QMapNode<Key, T> *copy(QMapData<Key, T> *d) const;
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 78b7e69d9c..8093a26f7d 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -160,9 +160,9 @@ static inline bool qt_ends_with(QStringView haystack, QStringView needle, Qt::Ca
static inline bool qt_ends_with(QStringView haystack, QLatin1String needle, Qt::CaseSensitivity cs);
static inline bool qt_ends_with(QStringView haystack, QChar needle, Qt::CaseSensitivity cs);
-qssize_t QtPrivate::qustrlen(const ushort *str) Q_DECL_NOTHROW
+qsizetype QtPrivate::qustrlen(const ushort *str) Q_DECL_NOTHROW
{
- qssize_t result = 0;
+ qsizetype result = 0;
#ifdef __SSE2__
// find the 16-byte alignment immediately prior or equal to str
@@ -769,8 +769,6 @@ static int qt_compare_strings(QLatin1String lhs, QLatin1String rhs, Qt::CaseSens
Case-sensitive comparison is based exclusively on the numeric Unicode values
of the characters and is very fast, but is not what a human would expect.
Consider sorting user-visible strings with QString::localeAwareCompare().
-
- \snippet qstring/main.cpp qCompareStrings-QSV-QSV
*/
int QtPrivate::compareStrings(QStringView lhs, QStringView rhs, Qt::CaseSensitivity cs) Q_DECL_NOTHROW
{
@@ -4837,7 +4835,7 @@ static QByteArray qt_convert_to_local_8bit(QStringView string);
locale, the returned byte array is undefined. Those characters may be
suppressed or replaced by another.
- \sa fromLocal8Bit(), toLatin1(), toUtf8(), QTextCodec, qConvertToLocal8Bit()
+ \sa fromLocal8Bit(), toLatin1(), toUtf8(), QTextCodec
*/
QByteArray QString::toLocal8Bit_helper(const QChar *data, int size)
@@ -4871,8 +4869,7 @@ static QByteArray qt_convert_to_local_8bit(QStringView string)
The behavior is undefined if \a string contains characters not
supported by the locale's 8-bit encoding.
- \sa QString::toLocal8Bit(), QStringView::toLocal8Bit(), QtPrivate::vonvertToLatin1(),
- QtPrivate::convertToUtf8(), QtPrivate::convertToUcs4()
+ \sa QString::toLocal8Bit(), QStringView::toLocal8Bit()
*/
QByteArray QtPrivate::convertToLocal8Bit(QStringView string)
{
@@ -4915,8 +4912,7 @@ static QByteArray qt_convert_to_utf8(QStringView str)
UTF-8 is a Unicode codec and can represent all characters in a Unicode
string like QStringView.
- \sa QString::toUtf8(), QStringView::toUtf8(), QtPrivate::convertToLatin1(),
- QtPrivate::convertToLocal8Bit(), QtPrivate::convertToUcs4()
+ \sa QString::toUtf8(), QStringView::toUtf8()
*/
QByteArray QtPrivate::convertToUtf8(QStringView string)
{
@@ -5279,8 +5275,8 @@ namespace {
}
/*!
- \fn QStringView qTrimmed(QStringView s)
- \fn QLatin1String qTrimmed(QLatin1String s)
+ \fn QStringView QtPrivate::trimmed(QStringView s)
+ \fn QLatin1String QtPrivate::trimmed(QLatin1String s)
\internal
\relates QStringView
\since 5.10
@@ -5521,14 +5517,9 @@ QString& QString::fill(QChar ch, int size)
Returns the number of characters in this string.
- The last character in the string is at position size() - 1. In
- addition, QString ensures that the character at position size()
- is always '\\0', so that you can use the return value of data()
- and constData() as arguments to functions that expect
- '\\0'-terminated strings.
+ The last character in the string is at position size() - 1.
Example:
-
\snippet qstring/main.cpp 58
\sa isEmpty(), resize()
@@ -6046,10 +6037,13 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1,
/*!
\fn const QChar *QString::unicode() const
- Returns a '\\0'-terminated Unicode representation of the string.
+ Returns a Unicode representation of the string.
The result remains valid until the string is modified.
- \sa utf16()
+ \note The returned string may not be '\\0'-terminated.
+ Use size() to determine the length of the array.
+
+ \sa utf16(), fromRawData()
*/
/*!
@@ -7250,6 +7244,16 @@ static ResultList splitString(const StringSource &source, const QChar *sep,
\snippet qstring/main.cpp 62
+ If \a sep is empty, split() returns an empty string, followed
+ by each of the string's characters, followed by another empty string:
+
+ \snippet qstring/main.cpp 62-empty
+
+ To understand this behavior, recall that the empty string matches
+ everywhere, so the above is qualitatively the same as:
+
+ \snippet qstring/main.cpp 62-slashes
+
\sa QStringList::join(), section()
*/
QStringList QString::split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
@@ -7259,15 +7263,10 @@ QStringList QString::split(const QString &sep, SplitBehavior behavior, Qt::CaseS
/*!
Splits the string into substring references wherever \a sep occurs, and
- returns the list of those strings. If \a sep does not match
- anywhere in the string, splitRef() returns a single-element vector
- containing this string reference.
+ returns the list of those strings.
- \a cs specifies whether \a sep should be matched case
- sensitively or case insensitively.
-
- If \a behavior is QString::SkipEmptyParts, empty entries don't
- appear in the result. By default, empty entries are kept.
+ See QString::split() for how \a sep, \a behavior and \a cs interact to form
+ the result.
\note All references are valid as long this string is alive. Destroying this
string will cause all references be dangling pointers.
@@ -7298,15 +7297,10 @@ QVector<QStringRef> QString::splitRef(QChar sep, SplitBehavior behavior, Qt::Cas
/*!
Splits the string into substrings references wherever \a sep occurs, and
- returns the list of those strings. If \a sep does not match
- anywhere in the string, split() returns a single-element vector
- containing this string reference.
+ returns the list of those strings.
- \a cs specifies whether \a sep should be matched case
- sensitively or case insensitively.
-
- If \a behavior is QString::SkipEmptyParts, empty entries don't
- appear in the result. By default, empty entries are kept.
+ See QString::split() for how \a sep, \a behavior and \a cs interact to form
+ the result.
\note All references are valid as long this string is alive. Destroying this
string will cause all references be dangling pointers.
@@ -8519,7 +8513,10 @@ bool QString::isRightToLeft() const
Returns a pointer to the data stored in the QString. The pointer
can be used to access and modify the characters that compose the
- string. For convenience, the data is '\\0'-terminated.
+ string.
+
+ Unlike constData() and unicode(), the returned data is always
+ '\\0'-terminated.
Example:
@@ -8535,18 +8532,25 @@ bool QString::isRightToLeft() const
/*! \fn const QChar *QString::data() const
\overload
+
+ \note The returned string may not be '\\0'-terminated.
+ Use size() to determine the length of the array.
+
+ \sa fromRawData()
*/
/*! \fn const QChar *QString::constData() const
Returns a pointer to the data stored in the QString. The pointer
- can be used to access the characters that compose the string. For
- convenience, the data is '\\0'-terminated.
+ can be used to access the characters that compose the string.
Note that the pointer remains valid only as long as the string is
not modified.
- \sa data(), operator[]()
+ \note The returned string may not be '\\0'-terminated.
+ Use size() to determine the length of the array.
+
+ \sa data(), operator[](), fromRawData()
*/
/*! \fn void QString::push_front(const QString &other)
@@ -8996,7 +9000,7 @@ QString &QString::setRawData(const QChar *unicode, int size)
If \a cs is Qt::CaseSensitive (the default), the search is case-sensitive;
otherwise the search is case-insensitive.
- \sa endsWith(), qStartsWith()
+ \sa endsWith()
*/
/*!
@@ -9016,7 +9020,7 @@ QString &QString::setRawData(const QChar *unicode, int size)
If \a cs is Qt::CaseSensitive (the default), the search is case-sensitive;
otherwise the search is case-insensitive.
- \sa startsWith(), qEndsWith()
+ \sa startsWith()
*/
/*!
diff --git a/src/corelib/tools/qstringalgorithms.h b/src/corelib/tools/qstringalgorithms.h
index 336da87468..aaa702301e 100644
--- a/src/corelib/tools/qstringalgorithms.h
+++ b/src/corelib/tools/qstringalgorithms.h
@@ -55,7 +55,7 @@ template <typename T> class QVector;
namespace QtPrivate {
-Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qssize_t qustrlen(const ushort *str) Q_DECL_NOTHROW;
+Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype qustrlen(const ushort *str) Q_DECL_NOTHROW;
Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION int compareStrings(QStringView lhs, QStringView rhs, Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW;
Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION int compareStrings(QStringView lhs, QLatin1String rhs, Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW;
diff --git a/src/corelib/tools/qstringiterator.qdoc b/src/corelib/tools/qstringiterator.qdoc
index 95c2247bc1..caec8803f3 100644
--- a/src/corelib/tools/qstringiterator.qdoc
+++ b/src/corelib/tools/qstringiterator.qdoc
@@ -120,7 +120,7 @@
*/
/*!
- \fn QStringIterator::QStringIterator(QStringView string, qssize_t idx)
+ \fn QStringIterator::QStringIterator(QStringView string, qsizetype idx)
Constructs an iterator over the contents of \a string. The iterator will point
before position \a idx in the string.
diff --git a/src/corelib/tools/qstringiterator_p.h b/src/corelib/tools/qstringiterator_p.h
index 8b1a6a1cd3..219589b6e4 100644
--- a/src/corelib/tools/qstringiterator_p.h
+++ b/src/corelib/tools/qstringiterator_p.h
@@ -62,7 +62,7 @@ class QStringIterator
QString::const_iterator i, pos, e;
Q_STATIC_ASSERT((std::is_same<QString::const_iterator, const QChar *>::value));
public:
- explicit QStringIterator(QStringView string, qssize_t idx = 0)
+ explicit QStringIterator(QStringView string, qsizetype idx = 0)
: i(string.begin()),
pos(i + idx),
e(string.end())
diff --git a/src/corelib/tools/qstringview.cpp b/src/corelib/tools/qstringview.cpp
index 8eefc6d814..6321427a2d 100644
--- a/src/corelib/tools/qstringview.cpp
+++ b/src/corelib/tools/qstringview.cpp
@@ -131,9 +131,9 @@ QT_BEGIN_NAMESPACE
/*!
\typedef QStringView::size_type
- Alias for qssize_t. Provided for compatibility with the STL.
+ Alias for qsizetype. Provided for compatibility with the STL.
- Unlike other Qt classes, QStringView uses qssize_t as its \c size_type, to allow
+ Unlike other Qt classes, QStringView uses qsizetype as its \c size_type, to allow
accepting data from \c{std::basic_string} without truncation. The Qt API functions,
for example length(), return \c int, while the STL-compatible functions, for example
size(), return \c size_type.
@@ -224,7 +224,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QStringView::QStringView(const Char *str, qssize_t len)
+ \fn QStringView::QStringView(const Char *str, qsizetype len)
Constructs a string view on \a str with length \a len.
@@ -486,7 +486,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn qssize_t QStringView::size() const
+ \fn qsizetype QStringView::size() const
Returns the size of this string view, in UTF-16 code points (that is,
surrogate pairs count as two for the purposes of this function, the same
@@ -510,7 +510,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QChar QStringView::operator[](qssize_t n) const
+ \fn QChar QStringView::operator[](qsizetype n) const
Returns the character at position \a n in this string view.
@@ -520,7 +520,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QChar QStringView::at(qssize_t n) const
+ \fn QChar QStringView::at(qsizetype n) const
Returns the character at position \a n in this string view.
@@ -582,7 +582,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QStringView QStringView::mid(qssize_t start) const
+ \fn QStringView QStringView::mid(qsizetype start) const
Returns the substring starting at position \a start in this object,
and extending to the end of the string.
@@ -593,7 +593,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QStringView QStringView::mid(qssize_t start, qssize_t length) const
+ \fn QStringView QStringView::mid(qsizetype start, qsizetype length) const
\overload
Returns the substring of length \a length starting at position
@@ -606,7 +606,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QStringView QStringView::left(qssize_t length) const
+ \fn QStringView QStringView::left(qsizetype length) const
Returns the substring of length \a length starting at position
0 in this object.
@@ -617,7 +617,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QStringView QStringView::right(qssize_t length) const
+ \fn QStringView QStringView::right(qsizetype length) const
Returns the substring of length \a length starting at position
size() - \a length in this object.
@@ -628,7 +628,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QStringView QStringView::chopped(qssize_t length) const
+ \fn QStringView QStringView::chopped(qsizetype length) const
Returns the substring of length size() - \a length starting at the
beginning of this object.
@@ -641,7 +641,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn void QStringView::truncate(qssize_t length)
+ \fn void QStringView::truncate(qsizetype length)
Truncates this string view to length \a length.
@@ -653,7 +653,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn void QStringView::chop(qssize_t length)
+ \fn void QStringView::chop(qsizetype length)
Truncates this string view by \a length characters.
@@ -672,8 +672,6 @@ QT_BEGIN_NAMESPACE
Whitespace means any character for which QChar::isSpace() returns
\c true. This includes the ASCII characters '\\t', '\\n', '\\v',
'\\f', '\\r', and ' '.
-
- \sa qTrimmed()
*/
/*!
@@ -689,7 +687,7 @@ QT_BEGIN_NAMESPACE
If \a cs is Qt::CaseSensitive (the default), the search is case-sensitive;
otherwise the search is case-insensitive.
- \sa endsWith(), qStartsWith()
+ \sa endsWith()
*/
/*!
@@ -705,7 +703,7 @@ QT_BEGIN_NAMESPACE
If \a cs is Qt::CaseSensitive (the default), the search is case-sensitive;
otherwise the search is case-insensitive.
- \sa startsWith(), qEndsWith()
+ \sa startsWith()
*/
/*!
@@ -730,7 +728,7 @@ QT_BEGIN_NAMESPACE
The behavior is undefined if the string contains characters not
supported by the locale's 8-bit encoding.
- \sa toLatin1(), toUtf8(), QTextCodec, qConvertToLocal8Bit()
+ \sa toLatin1(), toUtf8(), QTextCodec
*/
/*!
diff --git a/src/corelib/tools/qstringview.h b/src/corelib/tools/qstringview.h
index 14405f325d..ef442e5b65 100644
--- a/src/corelib/tools/qstringview.h
+++ b/src/corelib/tools/qstringview.h
@@ -111,7 +111,7 @@ public:
#endif
typedef const QChar value_type;
typedef std::ptrdiff_t difference_type;
- typedef qssize_t size_type;
+ typedef qsizetype size_type;
typedef value_type &reference;
typedef value_type &const_reference;
typedef value_type *pointer;
@@ -139,24 +139,25 @@ private:
using if_compatible_qstring_like = typename std::enable_if<std::is_same<T, QString>::value || std::is_same<T, QStringRef>::value, bool>::type;
template <typename Char, size_t N>
- static Q_DECL_CONSTEXPR qssize_t lengthHelperArray(const Char (&)[N]) Q_DECL_NOTHROW
+ static Q_DECL_CONSTEXPR qsizetype lengthHelperArray(const Char (&)[N]) Q_DECL_NOTHROW
{
- return qssize_t(N - 1);
+ return qsizetype(N - 1);
}
template <typename Char>
- static qssize_t lengthHelperPointer(const Char *str) Q_DECL_NOTHROW
+ static qsizetype lengthHelperPointer(const Char *str) Q_DECL_NOTHROW
{
#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL)
if (__builtin_constant_p(*str)) {
- qssize_t result = 0;
+ qsizetype result = 0;
while (*str++)
++result;
+ return result;
}
#endif
return QtPrivate::qustrlen(reinterpret_cast<const ushort *>(str));
}
- static qssize_t lengthHelperPointer(const QChar *str) Q_DECL_NOTHROW
+ static qsizetype lengthHelperPointer(const QChar *str) Q_DECL_NOTHROW
{
return QtPrivate::qustrlen(reinterpret_cast<const ushort *>(str));
}
@@ -174,7 +175,7 @@ public:
: QStringView() {}
template <typename Char, if_compatible_char<Char> = true>
- Q_DECL_CONSTEXPR QStringView(const Char *str, qssize_t len)
+ Q_DECL_CONSTEXPR QStringView(const Char *str, qsizetype len)
: m_size((Q_ASSERT(len >= 0), Q_ASSERT(str || !len), len)),
m_data(castHelper(str)) {}
@@ -204,20 +205,20 @@ public:
#else
template <typename String, if_compatible_qstring_like<String> = true>
QStringView(const String &str) Q_DECL_NOTHROW
- : QStringView(str.isNull() ? nullptr : str.data(), qssize_t(str.size())) {}
+ : QStringView(str.isNull() ? nullptr : str.data(), qsizetype(str.size())) {}
#endif
template <typename StdBasicString, if_compatible_string<StdBasicString> = true>
QStringView(const StdBasicString &str) Q_DECL_NOTHROW
- : QStringView(str.data(), qssize_t(str.size())) {}
+ : QStringView(str.data(), qsizetype(str.size())) {}
Q_REQUIRED_RESULT inline QString toString() const; // defined in qstring.h
- Q_REQUIRED_RESULT Q_DECL_CONSTEXPR qssize_t size() const Q_DECL_NOTHROW { return m_size; }
+ Q_REQUIRED_RESULT Q_DECL_CONSTEXPR qsizetype size() const Q_DECL_NOTHROW { return m_size; }
Q_REQUIRED_RESULT const_pointer data() const Q_DECL_NOTHROW { return reinterpret_cast<const_pointer>(m_data); }
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR const storage_type *utf16() const Q_DECL_NOTHROW { return m_data; }
- Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QChar operator[](qssize_t n) const
+ Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QChar operator[](qsizetype n) const
{ return Q_ASSERT(n >= 0), Q_ASSERT(n < size()), QChar(m_data[n]); }
//
@@ -229,22 +230,22 @@ public:
Q_REQUIRED_RESULT QByteArray toLocal8Bit() const { return QtPrivate::convertToLocal8Bit(*this); }
Q_REQUIRED_RESULT inline QVector<uint> toUcs4() const; // defined in qvector.h
- Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QChar at(qssize_t n) const { return (*this)[n]; }
+ Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QChar at(qsizetype n) const { return (*this)[n]; }
- Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView mid(qssize_t pos) const
+ Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView mid(qsizetype pos) const
{ return Q_ASSERT(pos >= 0), Q_ASSERT(pos <= size()), QStringView(m_data + pos, m_size - pos); }
- Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView mid(qssize_t pos, qssize_t n) const
+ Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView mid(qsizetype pos, qsizetype n) const
{ return Q_ASSERT(pos >= 0), Q_ASSERT(n >= 0), Q_ASSERT(pos + n <= size()), QStringView(m_data + pos, n); }
- Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView left(qssize_t n) const
+ Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView left(qsizetype n) const
{ return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QStringView(m_data, n); }
- Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView right(qssize_t n) const
+ Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView right(qsizetype n) const
{ return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QStringView(m_data + m_size - n, n); }
- Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView chopped(qssize_t n) const
+ Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView chopped(qsizetype n) const
{ return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QStringView(m_data, m_size - n); }
- Q_DECL_RELAXED_CONSTEXPR void truncate(qssize_t n)
+ Q_DECL_RELAXED_CONSTEXPR void truncate(qsizetype n)
{ Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); m_size = n; }
- Q_DECL_RELAXED_CONSTEXPR void chop(qssize_t n)
+ Q_DECL_RELAXED_CONSTEXPR void chop(qsizetype n)
{ Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); m_size -= n; }
Q_REQUIRED_RESULT QStringView trimmed() const Q_DECL_NOTHROW { return QtPrivate::trimmed(*this); }
@@ -291,7 +292,7 @@ public:
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QChar first() const { return front(); }
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QChar last() const { return back(); }
private:
- qssize_t m_size;
+ qsizetype m_size;
const storage_type *m_data;
};
Q_DECLARE_TYPEINFO(QStringView, Q_PRIMITIVE_TYPE);
diff --git a/src/corelib/tools/qunicodetables.cpp b/src/corelib/tools/qunicodetables.cpp
index ecab750833..01fa8b2102 100644
--- a/src/corelib/tools/qunicodetables.cpp
+++ b/src/corelib/tools/qunicodetables.cpp
@@ -6083,9 +6083,9 @@ static const Properties uc_properties[] = {
{ 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 13, 7 },
{ 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 7 },
{ 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 12, 0, 12, 7 },
- { 10, 5, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 3, 4, 4, 12, 8 },
- { 10, 5, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 3, 4, 4, 12, 8 },
- { 10, 5, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 3, 4, 4, 12, 2 },
+ { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 3, 4, 4, 12, 8 },
+ { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 3, 4, 4, 12, 8 },
+ { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 3, 4, 4, 12, 2 },
{ 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 8 },
{ 26, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 8 },
{ 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 10, 8 },
@@ -6146,7 +6146,7 @@ static const Properties uc_properties[] = {
{ 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 8 },
{ 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 6, 8 },
{ 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 8 },
- { 10, 5, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 12, 2 },
+ { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 12, 2 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 8 },
{ 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 8 },
{ 17, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 8 },
@@ -6749,7 +6749,7 @@ static const Properties uc_properties[] = {
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 6, 33 },
{ 25, 10, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 33 },
{ 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 33 },
- { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 4, 4, 4, 33 },
+ { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 4, 4, 4, 33 },
{ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 33 },
{ 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 33 },
{ 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 33 },
@@ -7058,7 +7058,7 @@ static const Properties uc_properties[] = {
{ 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 5, 17, 2 },
{ 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 5, 4, 2 },
{ 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 4, 20, 2 },
- { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
{ 10, 18, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
{ 10, 0, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
{ 10, 1, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
@@ -7108,10 +7108,10 @@ static const Properties uc_properties[] = {
{ 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 4, 4, 12, 2 },
{ 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 3, 4, 4, 12, 2 },
{ 13, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 12, 0 },
- { 10, 19, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 },
- { 10, 20, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 },
- { 10, 21, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 },
- { 10, 22, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 },
+ { 10, 19, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 },
+ { 10, 20, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 },
+ { 10, 21, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 },
+ { 10, 22, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 },
{ 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
{ 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
{ 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 8, 6, 12, 3 },
diff --git a/src/corelib/tools/qunicodetables_p.h b/src/corelib/tools/qunicodetables_p.h
index 5a422ea4eb..be2f44f0c3 100644
--- a/src/corelib/tools/qunicodetables_p.h
+++ b/src/corelib/tools/qunicodetables_p.h
@@ -50,11 +50,11 @@
// We mean it.
//
-#include <QtCore/private/qglobal_p.h>
-
#ifndef QUNICODETABLES_P_H
#define QUNICODETABLES_P_H
+#include <QtCore/private/qglobal_p.h>
+
#include <QtCore/qchar.h>
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 6825782131..ce6e657be0 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -162,9 +162,10 @@ public:
const const_iterator ce = this->cend(), cit = std::find(this->cbegin(), ce, t);
if (cit == ce)
return 0;
- // next operation detaches, so ce, cit may become invalidated:
+ // next operation detaches, so ce, cit, t may become invalidated:
+ const T tCopy = t;
const int firstFoundIdx = std::distance(this->cbegin(), cit);
- const iterator e = end(), it = std::remove(begin() + firstFoundIdx, e, t);
+ const iterator e = end(), it = std::remove(begin() + firstFoundIdx, e, tCopy);
const int result = std::distance(it, e);
erase(it, e);
return result;
diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp
index c1ed410de7..9b5295a17e 100644
--- a/src/corelib/xml/qxmlstream.cpp
+++ b/src/corelib/xml/qxmlstream.cpp
@@ -3741,7 +3741,6 @@ void QXmlStreamWriter::writeEntityReference(const QString &name)
void QXmlStreamWriter::writeNamespace(const QString &namespaceUri, const QString &prefix)
{
Q_D(QXmlStreamWriter);
- Q_ASSERT(!namespaceUri.isEmpty());
Q_ASSERT(prefix != QLatin1String("xmlns"));
if (prefix.isEmpty()) {
d->findNamespace(namespaceUri, d->inStartElement);
diff --git a/src/dbus/doc/qtdbus.qdocconf b/src/dbus/doc/qtdbus.qdocconf
index ff46cc5961..69eaa0eec3 100644
--- a/src/dbus/doc/qtdbus.qdocconf
+++ b/src/dbus/doc/qtdbus.qdocconf
@@ -59,4 +59,4 @@ navigation.cppclassespage = "Qt D-Bus C++ Classes"
manifestmeta.thumbnail.names = "QtDBus/D-Bus List Names Example" \
"QtDBus/D-Bus Ping Pong Example" \
- "QtDBus/D-Bus Complex Ping Pong Example" \
+ "QtDBus/D-Bus Complex Ping Pong Example"
diff --git a/src/gui/configure.json b/src/gui/configure.json
index b617a1e31d..0f71f7a98f 100644
--- a/src/gui/configure.json
+++ b/src/gui/configure.json
@@ -723,6 +723,33 @@
},
"use": "egl"
},
+ "egl-openwfd": {
+ "label": "OpenWFD EGL",
+ "type": "compile",
+ "test": {
+ "include": [ "wfd.h" ],
+ "main": [
+ "wfdEnumerateDevices(nullptr, 0, nullptr);"
+ ]
+ },
+ "use": "egl"
+ },
+ "egl-rcar": {
+ "label": "RCAR EGL",
+ "type": "compile",
+ "test": {
+ "include": [ "EGL/egl.h" ],
+ "tail": [
+ "extern \"C\" {",
+ "extern unsigned long PVRGrfxServerInit(void);",
+ "}"
+ ],
+ "main": [
+ "PVRGrfxServerInit();"
+ ]
+ },
+ "use": "egl opengl_es2"
+ },
"evdev": {
"label": "evdev",
"type": "compile",
@@ -954,7 +981,7 @@
"label": "IMF",
"emitIf": "config.qnx",
"condition": "libs.imf",
- "output": [ "privateConfig" ]
+ "output": [ "privateFeature" ]
},
"integrityfb": {
"label": "INTEGRITY framebuffer",
@@ -1124,11 +1151,21 @@
"condition": "features.eglfs && tests.egl-viv",
"output": [ "privateFeature" ]
},
+ "eglfs_rcar": {
+ "label": "EGLFS RCAR",
+ "condition": "config.integrity && features.eglfs && tests.egl-rcar",
+ "output": [ "privateFeature" ]
+ },
"eglfs_viv_wl": {
"label": "EGLFS i.Mx6 Wayland",
"condition": "features.eglfs_viv && libs.wayland_server",
"output": [ "privateFeature" ]
},
+ "eglfs_openwfd": {
+ "label": "EGLFS OpenWFD",
+ "condition": "config.integrity && features.eglfs && tests.egl-openwfd",
+ "output": [ "privateFeature" ]
+ },
"gif": {
"label": "GIF",
"condition": "features.imageformatplugin",
@@ -1204,6 +1241,7 @@
"label": "XCB",
"section": "Platform plugins",
"autoDetect": "!config.darwin",
+ "enable": "input.xcb == 'system' || input.xcb == 'qt'",
"condition": "libs.xcb",
"output": [ "privateFeature" ]
},
@@ -1628,7 +1666,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla
"section": "EGLFS details",
"condition": "features.eglfs",
"entries": [
- "eglfs_viv", "eglfs_viv_wl", "eglfs_egldevice", "eglfs_gbm", "eglfs_mali", "eglfs_brcm", "egl_x11"
+ "eglfs_openwfd", "eglfs_viv", "eglfs_viv_wl", "eglfs_rcar", "eglfs_egldevice", "eglfs_gbm", "eglfs_mali", "eglfs_brcm", "egl_x11"
]
},
"linuxfb", "vnc", "mirclient",
diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf
index 3b3ebafc2d..e1afa426ed 100644
--- a/src/gui/doc/qtgui.qdocconf
+++ b/src/gui/doc/qtgui.qdocconf
@@ -56,5 +56,7 @@ imagedirs += images \
../../../examples/gui/doc/images \
../../../doc/src/images \
+manifestmeta.highlighted.names = "QtGui/Analog Clock Window Example"
+
navigation.landingpage = "Qt GUI"
navigation.cppclassespage = "Qt GUI C++ Classes"
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index 1ec45a7491..587f375ce7 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -49,10 +49,10 @@ QT_BEGIN_NAMESPACE
static void swapPixel01(QImage *image) // 1-bpp: swap 0 and 1 pixels
{
- qssize_t i;
+ qsizetype i;
if (image->depth() == 1 && image->colorCount() == 2) {
uint *p = (uint *)image->bits();
- qssize_t nbytes = static_cast<qssize_t>(image->sizeInBytes());
+ qsizetype nbytes = static_cast<qsizetype>(image->sizeInBytes());
for (i=0; i<nbytes/4; i++) {
*p = ~*p;
p++;
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 209d011e7b..a5a5f7c1a4 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -130,7 +130,7 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format)
if (std::numeric_limits<int>::max()/depth < width
|| bytes_per_line <= 0
|| height <= 0
- || std::numeric_limits<qssize_t>::max()/uint(bytes_per_line) < height
+ || std::numeric_limits<qsizetype>::max()/uint(bytes_per_line) < height
|| std::numeric_limits<int>::max()/sizeof(uchar *) < uint(height))
return 0;
@@ -1470,7 +1470,7 @@ int QImage::byteCount() const
\sa byteCount(), bytesPerLine(), bits(), {QImage#Image Information}{Image
Information}
*/
-qssize_t QImage::sizeInBytes() const
+qsizetype QImage::sizeInBytes() const
{
return d ? d->nbytes : 0;
}
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 5f2965042f..9b76b62f24 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -217,7 +217,7 @@ public:
#if QT_DEPRECATED_SINCE(5, 10)
QT_DEPRECATED_X("Use sizeInBytes") int byteCount() const;
#endif
- qssize_t sizeInBytes() const;
+ qsizetype sizeInBytes() const;
uchar *scanLine(int);
const uchar *scanLine(int) const;
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 6abaa2887e..4eef617336 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -823,8 +823,8 @@ static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConve
const int depth = 32;
- const qssize_t dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
- const qssize_t nbytes = dst_bytes_per_line * data->height;
+ const qsizetype dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
+ const qsizetype nbytes = dst_bytes_per_line * data->height;
uchar *const newData = (uchar *)realloc(data->data, nbytes);
if (!newData)
return false;
@@ -877,8 +877,8 @@ static bool convert_indexed8_to_ARGB_inplace(QImageData *data, Qt::ImageConversi
const int depth = 32;
- const qssize_t dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
- const qssize_t nbytes = dst_bytes_per_line * data->height;
+ const qsizetype dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
+ const qsizetype nbytes = dst_bytes_per_line * data->height;
uchar *const newData = (uchar *)realloc(data->data, nbytes);
if (!newData)
return false;
@@ -945,8 +945,8 @@ static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConvers
const int depth = 16;
- const qssize_t dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
- const qssize_t nbytes = dst_bytes_per_line * data->height;
+ const qsizetype dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
+ const qsizetype nbytes = dst_bytes_per_line * data->height;
uchar *const newData = (uchar *)realloc(data->data, nbytes);
if (!newData)
return false;
@@ -1002,8 +1002,8 @@ static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFl
const int depth = 16;
- const qssize_t dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
- const qssize_t src_bytes_per_line = data->bytes_per_line;
+ const qsizetype dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
+ const qsizetype src_bytes_per_line = data->bytes_per_line;
quint32 *src_data = (quint32 *) data->data;
quint16 *dst_data = (quint16 *) data->data;
@@ -1257,9 +1257,9 @@ void dither_to_Mono(QImageData *dst, const QImageData *src,
}
uchar *dst_data = dst->data;
- qssize_t dst_bpl = dst->bytes_per_line;
+ qsizetype dst_bpl = dst->bytes_per_line;
const uchar *src_data = src->data;
- qssize_t src_bpl = src->bytes_per_line;
+ qsizetype src_bpl = src->bytes_per_line;
switch (dithermode) {
case Diffuse: {
@@ -1912,8 +1912,8 @@ static void convert_Indexed8_to_Alpha8(QImageData *dest, const QImageData *src,
if (simpleCase)
memcpy(dest->data, src->data, src->bytes_per_line * src->height);
else {
- qssize_t size = src->bytes_per_line * src->height;
- for (qssize_t i = 0; i < size; ++i) {
+ qsizetype size = src->bytes_per_line * src->height;
+ for (qsizetype i = 0; i < size; ++i) {
dest->data[i] = translate[src->data[i]];
}
}
@@ -1936,8 +1936,8 @@ static void convert_Indexed8_to_Grayscale8(QImageData *dest, const QImageData *s
if (simpleCase)
memcpy(dest->data, src->data, src->bytes_per_line * src->height);
else {
- qssize_t size = src->bytes_per_line * src->height;
- for (qssize_t i = 0; i < size; ++i) {
+ qsizetype size = src->bytes_per_line * src->height;
+ for (qsizetype i = 0; i < size; ++i) {
dest->data[i] = translate[src->data[i]];
}
}
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index 9ba4945dc5..befecbfe8b 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -71,12 +71,12 @@ struct Q_GUI_EXPORT QImageData { // internal image data
int width;
int height;
int depth;
- qssize_t nbytes; // number of bytes data
+ qsizetype nbytes; // number of bytes data
qreal devicePixelRatio;
QVector<QRgb> colortable;
uchar *data;
QImage::Format format;
- qssize_t bytes_per_line;
+ qsizetype bytes_per_line;
int ser_no; // serial number
int detach_no;
diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp
index d694352fc1..646e737afa 100644
--- a/src/gui/image/qpixmap_blitter.cpp
+++ b/src/gui/image/qpixmap_blitter.cpp
@@ -191,7 +191,7 @@ void QBlittablePlatformPixmap::fromImage(const QImage &image,
uchar *mem = thisImg->bits();
const uchar *bits = correctFormatPic.constBits();
- qssize_t bytesCopied = 0;
+ qsizetype bytesCopied = 0;
while (bytesCopied < correctFormatPic.sizeInBytes()) {
memcpy(mem,bits,correctFormatPic.bytesPerLine());
mem += thisImg->bytesPerLine();
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 5004582c5f..b7c61779e6 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -1787,6 +1787,9 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
case QWindowSystemInterfacePrivate::WindowScreenChanged:
QGuiApplicationPrivate::processWindowScreenChangedEvent(static_cast<QWindowSystemInterfacePrivate::WindowScreenChangedEvent *>(e));
break;
+ case QWindowSystemInterfacePrivate::SafeAreaMarginsChanged:
+ QGuiApplicationPrivate::processSafeAreaMarginsChangedEvent(static_cast<QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent *>(e));
+ break;
case QWindowSystemInterfacePrivate::ApplicationStateChanged: {
QWindowSystemInterfacePrivate::ApplicationStateChangedEvent * changeEvent = static_cast<QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *>(e);
QGuiApplicationPrivate::setApplicationState(changeEvent->newState, changeEvent->forcePropagate); }
@@ -2284,6 +2287,17 @@ void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterf
}
}
+void QGuiApplicationPrivate::processSafeAreaMarginsChangedEvent(QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent *wse)
+{
+ if (wse->window.isNull())
+ return;
+
+ // Handle by forwarding directly to QWindowPrivate, instead of sending spontaneous
+ // QEvent like most other functions, as there's no QEvent type for the safe area
+ // change, and we don't want to add one until we know that this is a good API.
+ qt_window_private(wse->window)->processSafeAreaMarginsChanged();
+}
+
void QGuiApplicationPrivate::processThemeChanged(QWindowSystemInterfacePrivate::ThemeChangeEvent *tce)
{
if (self)
@@ -2979,7 +2993,7 @@ QPlatformDragQtResponse QGuiApplicationPrivate::processDrag(QWindow *w, const QM
static QPointer<QWindow> currentDragWindow;
static Qt::DropAction lastAcceptedDropAction = Qt::IgnoreAction;
QPlatformDrag *platformDrag = platformIntegration()->drag();
- if (!platformDrag) {
+ if (!platformDrag || (w && w->d_func()->blockedByModalWindow)) {
lastAcceptedDropAction = Qt::IgnoreAction;
return QPlatformDragQtResponse(false, lastAcceptedDropAction, QRect());
}
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index b7b847785c..75cbc7abde 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -133,6 +133,8 @@ public:
static void processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *e);
static void processWindowScreenChangedEvent(QWindowSystemInterfacePrivate::WindowScreenChangedEvent *e);
+ static void processSafeAreaMarginsChangedEvent(QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent *e);
+
static void processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e);
static void updateFilteredScreenOrientation(QScreen *screen);
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index caef942840..8689f9f3b1 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -376,8 +376,22 @@ qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen)
{
qreal factor = qreal(1.0);
if (screen) {
- if (m_usePixelDensity)
- factor *= screen->pixelDensity();
+ if (m_usePixelDensity) {
+ qreal pixelDensity = screen->pixelDensity();
+
+ // Pixel density reported by the screen is sometimes not precise enough,
+ // so recalculate it: divide px (physical pixels) by dp (device-independent pixels)
+ // for both width and height, and then use the average if it is different from
+ // the one initially reported by the screen
+ QRect screenGeometry = screen->geometry();
+ qreal wFactor = qreal(screenGeometry.width()) / qRound(screenGeometry.width() / pixelDensity);
+ qreal hFactor = qreal(screenGeometry.height()) / qRound(screenGeometry.height() / pixelDensity);
+ qreal averageDensity = (wFactor + hFactor) / 2;
+ if (!qFuzzyCompare(pixelDensity, averageDensity))
+ pixelDensity = averageDensity;
+
+ factor *= pixelDensity;
+ }
if (m_screenFactorSet) {
QVariant screenFactor = screen->screen()->property(scaleFactorProperty);
if (screenFactor.isValid())
diff --git a/src/gui/kernel/qinputdevicemanager.cpp b/src/gui/kernel/qinputdevicemanager.cpp
index 2d231ae26f..37b1450d5a 100644
--- a/src/gui/kernel/qinputdevicemanager.cpp
+++ b/src/gui/kernel/qinputdevicemanager.cpp
@@ -92,4 +92,48 @@ void QInputDeviceManager::setCursorPos(const QPoint &pos)
emit cursorPositionChangeRequested(pos);
}
+/*!
+ \return the keyboard modifier state stored in the QInputDeviceManager object.
+
+ Keyboard input handlers are expected to keep this up-to-date via
+ setKeyboardModifiers().
+
+ Querying the state via this function (e.g. from a mouse handler that needs
+ to include the modifier state in mouse events) is the preferred alternative
+ over QGuiApplication::keyboardModifiers() since the latter may not report
+ the current state due to asynchronous QPA event processing.
+ */
+Qt::KeyboardModifiers QInputDeviceManager::keyboardModifiers() const
+{
+ Q_D(const QInputDeviceManager);
+ return d->keyboardModifiers;
+}
+
+void QInputDeviceManager::setKeyboardModifiers(Qt::KeyboardModifiers modsBeforeEvent, int key)
+{
+ Q_D(QInputDeviceManager);
+ Qt::KeyboardModifiers mods;
+ switch (key) {
+ case Qt::Key_Shift:
+ mods = Qt::KeyboardModifiers(modsBeforeEvent ^ Qt::ShiftModifier);
+ break;
+ case Qt::Key_Control:
+ mods = Qt::KeyboardModifiers(modsBeforeEvent ^ Qt::ControlModifier);
+ break;
+ case Qt::Key_Alt:
+ mods = Qt::KeyboardModifiers(modsBeforeEvent ^ Qt::AltModifier);
+ break;
+ case Qt::Key_Meta:
+ mods = Qt::KeyboardModifiers(modsBeforeEvent ^ Qt::MetaModifier);
+ break;
+ case Qt::Key_AltGr:
+ mods = Qt::KeyboardModifiers(modsBeforeEvent ^ Qt::GroupSwitchModifier);
+ break;
+ default:
+ mods = modsBeforeEvent;
+ break;
+ }
+ d->keyboardModifiers = mods;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qinputdevicemanager_p.h b/src/gui/kernel/qinputdevicemanager_p.h
index db9d0596b6..ddf1e6befa 100644
--- a/src/gui/kernel/qinputdevicemanager_p.h
+++ b/src/gui/kernel/qinputdevicemanager_p.h
@@ -78,6 +78,9 @@ public:
void setCursorPos(const QPoint &pos);
+ Qt::KeyboardModifiers keyboardModifiers() const;
+ void setKeyboardModifiers(Qt::KeyboardModifiers modsBeforeEvent, int key);
+
signals:
void deviceListChanged(QInputDeviceManager::DeviceType type);
void cursorPositionChangeRequested(const QPoint &pos);
diff --git a/src/gui/kernel/qinputdevicemanager_p_p.h b/src/gui/kernel/qinputdevicemanager_p_p.h
index ae91f3a2ab..0a91252fbc 100644
--- a/src/gui/kernel/qinputdevicemanager_p_p.h
+++ b/src/gui/kernel/qinputdevicemanager_p_p.h
@@ -69,6 +69,8 @@ public:
void setDeviceCount(QInputDeviceManager::DeviceType type, int count);
QMap<QInputDeviceManager::DeviceType, int> m_deviceCount;
+
+ Qt::KeyboardModifiers keyboardModifiers;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 6298dd5f45..27ea3864b9 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -937,7 +937,9 @@ GLuint QOpenGLContext::defaultFramebufferObject() const
/*!
Makes the context current in the current thread, against the given
- \a surface. Returns \c true if successful.
+ \a surface. Returns \c true if successful; otherwise returns \c false.
+ The latter may happen if the surface is not exposed, or the graphics
+ hardware is not available due to e.g. the application being suspended.
If \a surface is 0 this is equivalent to calling doneCurrent().
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index 2284290d6c..4bf96e277f 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -166,6 +166,16 @@ QMargins QPlatformWindow::frameMargins() const
}
/*!
+ The safe area margins of a window represent the area that is safe to
+ place content within, without intersecting areas of the screen where
+ system UI is placed, or where a screen bezel may cover the content.
+*/
+QMargins QPlatformWindow::safeAreaMargins() const
+{
+ return QMargins();
+}
+
+/*!
Reimplemented in subclasses to show the surface
if \a visible is \c true, and hide it if \a visible is \c false.
diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h
index 4105ef1c1a..61f1cb624c 100644
--- a/src/gui/kernel/qplatformwindow.h
+++ b/src/gui/kernel/qplatformwindow.h
@@ -88,6 +88,7 @@ public:
virtual QRect normalGeometry() const;
virtual QMargins frameMargins() const;
+ virtual QMargins safeAreaMargins() const;
virtual void setVisible(bool visible);
virtual void setWindowFlags(Qt::WindowFlags flags);
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index fea55e459d..3e5777ad49 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -2790,6 +2790,8 @@ bool QWindowPrivate::applyCursor()
if (!platformWindow)
return true;
QCursor *c = QGuiApplication::overrideCursor();
+ if (c != nullptr && platformCursor->capabilities().testFlag(QPlatformCursor::OverrideCursor))
+ return true;
if (!c && hasCursor)
c = &cursor;
platformCursor->changeCursor(c, q);
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index 2de5aab2c4..7ef73eb410 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -155,6 +155,8 @@ public:
virtual void clearFocusObject();
virtual QRectF closestAcceptableGeometry(const QRectF &rect) const;
+ virtual void processSafeAreaMarginsChanged() {};
+
bool isPopup() const { return (windowFlags & Qt::WindowType_Mask) == Qt::Popup; }
static QWindowPrivate *get(QWindow *window) { return window->d_func(); }
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index a47bac8f39..35a9ede227 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -265,6 +265,13 @@ void QWindowSystemInterface::handleWindowScreenChanged(QWindow *window, QScreen
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
+QT_DEFINE_QPA_EVENT_HANDLER(void, handleSafeAreaMarginsChanged, QWindow *window)
+{
+ QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent *e =
+ new QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent(window);
+ QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
+}
+
QT_DEFINE_QPA_EVENT_HANDLER(void, handleApplicationStateChanged, Qt::ApplicationState newState, bool forcePropagate)
{
Q_ASSERT(QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState));
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index 960f79b5ba..b22495f9d0 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -208,6 +208,9 @@ public:
static void handleWindowScreenChanged(QWindow *window, QScreen *newScreen);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
+ static void handleSafeAreaMarginsChanged(QWindow *window);
+
+ template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static void handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate = false);
#ifndef QT_NO_DRAGANDDROP
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index 152ea92919..c3fb19d21a 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -98,7 +98,8 @@ public:
#endif
ApplicationStateChanged = 0x19,
FlushEvents = 0x20,
- WindowScreenChanged = 0x21
+ WindowScreenChanged = 0x21,
+ SafeAreaMarginsChanged = 0x22
};
class WindowSystemEvent {
@@ -185,6 +186,15 @@ public:
QPointer<QScreen> screen;
};
+ class SafeAreaMarginsChangedEvent : public WindowSystemEvent {
+ public:
+ SafeAreaMarginsChangedEvent(QWindow *w)
+ : WindowSystemEvent(SafeAreaMarginsChanged), window(w)
+ { }
+
+ QPointer<QWindow> window;
+ };
+
class ApplicationStateChangedEvent : public WindowSystemEvent {
public:
ApplicationStateChangedEvent(Qt::ApplicationState newState, bool forcePropagate = false)
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index 855f245396..c55bcb12c9 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -853,7 +853,7 @@ QString QColor::name(NameFormat format) const
return QLatin1Char('#') + QString::number(rgba() | 0x1000000, 16).rightRef(6);
case HexArgb:
// it's called rgba() but it does return AARRGGBB
- return QLatin1Char('#') + QString::number(rgba() | 0x100000000, 16).rightRef(8);
+ return QLatin1Char('#') + QString::number(rgba() | Q_INT64_C(0x100000000), 16).rightRef(8);
}
return QString();
}
diff --git a/src/gui/painting/qcoregraphics_p.h b/src/gui/painting/qcoregraphics_p.h
index 7f677db465..de721c94aa 100644
--- a/src/gui/painting/qcoregraphics_p.h
+++ b/src/gui/painting/qcoregraphics_p.h
@@ -56,13 +56,15 @@
#include <QtGui/qpalette.h>
#include <CoreGraphics/CoreGraphics.h>
-#ifdef Q_OS_MACOS
+
+#if defined(__OBJC__) && defined(Q_OS_MACOS)
#include <AppKit/AppKit.h>
+#define HAVE_APPKIT
#endif
QT_BEGIN_NAMESPACE
-#ifdef Q_OS_MACOS
+#ifdef HAVE_APPKIT
Q_GUI_EXPORT NSImage *qt_mac_create_nsimage(const QPixmap &pm);
Q_GUI_EXPORT NSImage *qt_mac_create_nsimage(const QIcon &icon, int defaultSize = 0);
Q_GUI_EXPORT QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size);
@@ -75,7 +77,7 @@ Q_GUI_EXPORT void qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBou
Q_GUI_EXPORT void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform);
-#ifdef Q_OS_MACOS
+#ifdef HAVE_APPKIT
Q_GUI_EXPORT QColor qt_mac_toQColor(const NSColor *color);
Q_GUI_EXPORT QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup = QPalette::Normal);
#endif
@@ -121,4 +123,6 @@ private:
QT_END_NAMESPACE
+#undef HAVE_APPKIT
+
#endif // QCOREGRAPHICS_P_H
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 149fa124f6..7f8976d972 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -2383,7 +2383,7 @@ static void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper(uint
__m128i v_fy = _mm_setr_epi32(fy, fy + fdy, fy + fdy + fdy, fy + fdy + fdy + fdy);
const uchar *textureData = image.imageData;
- const qssize_t bytesPerLine = image.bytesPerLine;
+ const qsizetype bytesPerLine = image.bytesPerLine;
const __m128i vbpl = _mm_shufflelo_epi16(_mm_cvtsi32_si128(bytesPerLine/4), _MM_SHUFFLE(0, 0, 0, 0));
while (b < boundedEnd - 3) {
@@ -4719,6 +4719,7 @@ static void blend_transformed_argb(int count, const QSpan *spans, void *userData
CompositionFunction func = functionForMode[data->rasterBuffer->compositionMode];
uint buffer[buffer_size];
+ quint32 mask = (data->texture.format == QImage::Format_RGB32) ? 0xff000000 : 0;
const int image_x1 = data->texture.x1;
const int image_y1 = data->texture.y1;
@@ -4752,7 +4753,7 @@ static void blend_transformed_argb(int count, const QSpan *spans, void *userData
while (b < end) {
int px = qBound(image_x1, x >> 16, image_x2);
int py = qBound(image_y1, y >> 16, image_y2);
- *b = reinterpret_cast<const uint *>(data->texture.scanLine(py))[px];
+ *b = reinterpret_cast<const uint *>(data->texture.scanLine(py))[px] | mask;
x += fdx;
y += fdy;
@@ -4793,7 +4794,7 @@ static void blend_transformed_argb(int count, const QSpan *spans, void *userData
const int px = qBound(image_x1, int(tx) - (tx < 0), image_x2);
const int py = qBound(image_y1, int(ty) - (ty < 0), image_y2);
- *b = reinterpret_cast<const uint *>(data->texture.scanLine(py))[px];
+ *b = reinterpret_cast<const uint *>(data->texture.scanLine(py))[px] | mask;
x += fdx;
y += fdy;
w += fdw;
@@ -4959,7 +4960,7 @@ static void blend_transformed_tiled_argb(int count, const QSpan *spans, void *us
int image_width = data->texture.width;
int image_height = data->texture.height;
- const qssize_t scanline_offset = data->texture.bytesPerLine / 4;
+ const qsizetype scanline_offset = data->texture.bytesPerLine / 4;
if (data->fast_matrix) {
// The increment pr x in the scanline
diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp
index d6c3319c76..2619539788 100644
--- a/src/gui/painting/qdrawhelper_avx2.cpp
+++ b/src/gui/painting/qdrawhelper_avx2.cpp
@@ -685,7 +685,7 @@ void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2(uint *
v_fy = _mm256_add_epi32(v_fy, _mm256_mullo_epi32(_mm256_set1_epi32(fdy), v_index));
const uchar *textureData = image.imageData;
- const qssize_t bytesPerLine = image.bytesPerLine;
+ const qsizetype bytesPerLine = image.bytesPerLine;
const __m256i vbpl = _mm256_set1_epi16(bytesPerLine/4);
while (b < boundedEnd - 7) {
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 1dea386da4..4c2fe87355 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -293,7 +293,7 @@ struct QTextureData
int y1;
int x2;
int y2;
- qssize_t bytesPerLine;
+ qsizetype bytesPerLine;
QImage::Format format;
const QVector<QRgb> *colorTable;
bool hasAlpha;
@@ -847,7 +847,7 @@ inline void qt_memfill(T *dest, T value, int count)
template <class T> Q_STATIC_TEMPLATE_FUNCTION
inline void qt_rectfill(T *dest, T value,
- int x, int y, int width, int height, qssize_t stride)
+ int x, int y, int width, int height, qsizetype stride)
{
char *d = reinterpret_cast<char*>(dest + x) + y * stride;
if (uint(stride) == (width * sizeof(T))) {
diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp
index f42fd4ff87..1aee7d5f74 100644
--- a/src/gui/painting/qpaintengine.cpp
+++ b/src/gui/painting/qpaintengine.cpp
@@ -751,11 +751,29 @@ void QPaintEngine::drawPath(const QPainterPath &)
void QPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
{
const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
+ if (ti.glyphs.numGlyphs == 0)
+ return;
+
+ if (ti.fontEngine->glyphFormat == QFontEngine::Format_ARGB) {
+ QVarLengthArray<QFixedPoint> positions;
+ QVarLengthArray<glyph_t> glyphs;
+ QTransform matrix = QTransform::fromTranslate(p.x(), p.y() - ti.fontEngine->ascent().toReal());
+ ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
+ painter()->save();
+ painter()->setRenderHint(QPainter::SmoothPixmapTransform,
+ bool((painter()->renderHints() & QPainter::TextAntialiasing)
+ && !(painter()->font().styleStrategy() & QFont::NoAntialias)));
+ for (int i = 0; i < ti.glyphs.numGlyphs; ++i) {
+ QImage glyph = ti.fontEngine->bitmapForGlyph(glyphs[i], QFixed(), QTransform());
+ painter()->drawImage(positions[i].x.toReal(), positions[i].y.toReal(), glyph);
+ }
+ painter()->restore();
+ return;
+ }
QPainterPath path;
path.setFillRule(Qt::WindingFill);
- if (ti.glyphs.numGlyphs)
- ti.fontEngine->addOutlineToPath(0, 0, ti.glyphs, &path, ti.flags);
+ ti.fontEngine->addOutlineToPath(0, 0, ti.glyphs, &path, ti.flags);
if (!path.isEmpty()) {
painter()->save();
painter()->setRenderHint(QPainter::Antialiasing,
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 873303f78e..0e3163eefb 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -994,7 +994,7 @@ void QRasterPaintEnginePrivate::drawImage(const QPointF &pt,
Q_ASSERT(img.depth() >= 8);
- qssize_t srcBPL = img.bytesPerLine();
+ qsizetype srcBPL = img.bytesPerLine();
const uchar *srcBits = img.bits();
int srcSize = img.depth() >> 3; // This is the part that is incompatible with lower than 8-bit..
int iw = img.width();
@@ -1043,7 +1043,7 @@ void QRasterPaintEnginePrivate::drawImage(const QPointF &pt,
// call the blend function...
int dstSize = rasterBuffer->bytesPerPixel();
- qssize_t dstBPL = rasterBuffer->bytesPerLine();
+ qsizetype dstBPL = rasterBuffer->bytesPerLine();
func(rasterBuffer->buffer() + x * dstSize + y * dstBPL, dstBPL,
srcBits, srcBPL,
iw, ih,
@@ -2318,8 +2318,8 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
clippedSourceRect = clippedSourceRect.intersected(img.rect());
- const qssize_t dbpl = d->rasterBuffer->bytesPerLine();
- const qssize_t sbpl = img.bytesPerLine();
+ const qsizetype dbpl = d->rasterBuffer->bytesPerLine();
+ const qsizetype sbpl = img.bytesPerLine();
uchar *dst = d->rasterBuffer->buffer();
uint bpp = img.depth() >> 3;
@@ -2828,7 +2828,7 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
cache->fillInPendingGlyphs();
const QImage &image = cache->image();
- qssize_t bpl = image.bytesPerLine();
+ qsizetype bpl = image.bytesPerLine();
int depth = image.depth();
int rightShift = 0;
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 5f7f6a5148..e98ad8ce8b 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -6482,7 +6482,7 @@ void QPainterPrivate::drawTextItem(const QPointF &p, const QTextItem &_ti, QText
extended->drawTextItem(QPointF(x, y), ti2);
else
engine->drawTextItem(QPointF(x, y), ti2);
- drawTextItemDecoration(q, p, ti2.fontEngine, textEngine, ti2.underlineStyle,
+ drawTextItemDecoration(q, QPointF(x, y), ti2.fontEngine, textEngine, ti2.underlineStyle,
ti2.flags, ti2.width.toReal(), ti2.charFormat);
if (!rtl)
@@ -6515,7 +6515,7 @@ void QPainterPrivate::drawTextItem(const QPointF &p, const QTextItem &_ti, QText
extended->drawTextItem(QPointF(x, y), ti2);
else
engine->drawTextItem(QPointF(x,y), ti2);
- drawTextItemDecoration(q, p, ti2.fontEngine, textEngine, ti2.underlineStyle,
+ drawTextItemDecoration(q, QPointF(x, y), ti2.fontEngine, textEngine, ti2.underlineStyle,
ti2.flags, ti2.width.toReal(), ti2.charFormat);
// reset the high byte for all glyphs
diff --git a/src/gui/text/qdistancefield.cpp b/src/gui/text/qdistancefield.cpp
index af13b96c32..e7ca00b3a9 100644
--- a/src/gui/text/qdistancefield.cpp
+++ b/src/gui/text/qdistancefield.cpp
@@ -177,8 +177,8 @@ void drawTriangle(qint32 *bits, int width, int height, const QPoint *center,
const int y2 = clip == Clip ? qBound(0, v2->y() >> 8, height) : v2->y() >> 8;
const int yC = clip == Clip ? qBound(0, center->y() >> 8, height) : center->y() >> 8;
- const int v1Frac = clip == Clip ? (y1 << 8) + 0xff - v1->y() : ~v2->y() & 0xff;
- const int v2Frac = clip == Clip ? (y2 << 8) + 0xff - v2->y() : ~v1->y() & 0xff;
+ const int v1Frac = clip == Clip ? (y1 << 8) + 0xff - v1->y() : ~v1->y() & 0xff;
+ const int v2Frac = clip == Clip ? (y2 << 8) + 0xff - v2->y() : ~v2->y() & 0xff;
const int centerFrac = clip == Clip ? (yC << 8) + 0xff - center->y() : ~center->y() & 0xff;
int dx1 = 0, x1 = 0, dx2 = 0, x2 = 0;
diff --git a/src/gui/util/qshadergraphloader.cpp b/src/gui/util/qshadergraphloader.cpp
index c7560d9105..8d92c73a5a 100644
--- a/src/gui/util/qshadergraphloader.cpp
+++ b/src/gui/util/qshadergraphloader.cpp
@@ -48,10 +48,13 @@
QT_BEGIN_NAMESPACE
+void qt_register_ShaderLanguage_enums();
+
QShaderGraphLoader::QShaderGraphLoader() Q_DECL_NOTHROW
: m_status(Null),
m_device(nullptr)
{
+ qt_register_ShaderLanguage_enums();
}
QShaderGraphLoader::Status QShaderGraphLoader::status() const Q_DECL_NOTHROW
diff --git a/src/gui/util/qshaderlanguage.cpp b/src/gui/util/qshaderlanguage.cpp
index 4a0da5bfb5..f9192f5ff3 100644
--- a/src/gui/util/qshaderlanguage.cpp
+++ b/src/gui/util/qshaderlanguage.cpp
@@ -43,14 +43,12 @@
QT_BEGIN_NAMESPACE
-namespace {
- void registerEnums()
- {
- qRegisterMetaType<QShaderLanguage::StorageQualifier>();
- qRegisterMetaType<QShaderLanguage::VariableType>();
- }
+// Note: to be invoked explicitly. Relying for example on
+// Q_COREAPP_STARTUP_FUNCTION would not be acceptable in static builds.
+void qt_register_ShaderLanguage_enums()
+{
+ qRegisterMetaType<QShaderLanguage::StorageQualifier>();
+ qRegisterMetaType<QShaderLanguage::VariableType>();
}
-Q_COREAPP_STARTUP_FUNCTION(registerEnums)
-
QT_END_NAMESPACE
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index dce256b7e5..07644b869f 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -1889,7 +1889,8 @@ void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession
emit q->networkSessionConnected();
lastSessionState = state;
- if (online && state == QNetworkSession::Disconnected) {
+ if (online && (state == QNetworkSession::Disconnected
+ || state == QNetworkSession::NotAvailable)) {
const auto cfgs = networkConfigurationManager.allConfigurations();
for (const QNetworkConfiguration &cfg : cfgs) {
if (cfg.state().testFlag(QNetworkConfiguration::Active)) {
@@ -1931,9 +1932,9 @@ void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline)
online = (networkConfiguration.state() & QNetworkConfiguration::Active);
} else {
if (online != isOnline) {
+ online = isOnline;
_q_networkSessionClosed();
createSession(q->configuration());
- online = isOnline;
}
}
if (online) {
diff --git a/src/network/bearer/qbearerengine.cpp b/src/network/bearer/qbearerengine.cpp
index 215cd3fddd..677da08cb6 100644
--- a/src/network/bearer/qbearerengine.cpp
+++ b/src/network/bearer/qbearerengine.cpp
@@ -93,8 +93,8 @@ bool QBearerEngine::configurationsInUse() const
|| hasUsedConfiguration(userChoiceConfigurations);
}
+QT_END_NAMESPACE
+
#include "moc_qbearerengine_p.cpp"
#endif // QT_NO_BEARERMANAGEMENT
-
-QT_END_NAMESPACE
diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp
index 7d7b7cc5b0..81b5e01d6a 100644
--- a/src/network/bearer/qnetworkconfigmanager.cpp
+++ b/src/network/bearer/qnetworkconfigmanager.cpp
@@ -378,8 +378,8 @@ void QNetworkConfigurationManager::updateConfigurations()
priv->performAsyncConfigurationUpdate();
}
-#include "moc_qnetworkconfigmanager.cpp"
-
QT_END_NAMESPACE
+#include "moc_qnetworkconfigmanager.cpp"
+
#endif // QT_NO_BEARERMANAGEMENT
diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp
index bbcd191041..e5562e3a0b 100644
--- a/src/network/bearer/qnetworksession.cpp
+++ b/src/network/bearer/qnetworksession.cpp
@@ -749,8 +749,8 @@ void QNetworkSession::disconnectNotify(const QMetaMethod &signal)
d->setALREnabled(false);
}
-#include "moc_qnetworksession.cpp"
-
QT_END_NAMESPACE
+#include "moc_qnetworksession.cpp"
+
#endif // QT_NO_BEARERMANAGEMENT
diff --git a/src/network/configure.json b/src/network/configure.json
index ea01e8224d..94a23bbc78 100644
--- a/src/network/configure.json
+++ b/src/network/configure.json
@@ -69,18 +69,10 @@
{
"comment": "placeholder for OPENSSL_{PATH,LIBS{,_{DEBUG,RELEASE}}}",
"libs": "",
- "builds": {
- "debug": "",
- "release": ""
- },
"condition": "config.win32 && !features.shared"
},
{
"libs": "-lssleay32 -llibeay32",
- "builds": {
- "debug": "",
- "release": ""
- },
"condition": "config.win32 && features.shared"
},
{ "libs": "-lssl -lcrypto", "condition": "!config.win32" }
diff --git a/src/network/doc/qtnetwork.qdocconf b/src/network/doc/qtnetwork.qdocconf
index 2a8e577dda..4f667eed9d 100644
--- a/src/network/doc/qtnetwork.qdocconf
+++ b/src/network/doc/qtnetwork.qdocconf
@@ -40,5 +40,7 @@ exampledirs += ../../../examples/network \
imagedirs += images \
../../../examples/network/doc/images
+manifestmeta.highlighted.names = "QtNetwork/HTTP Example"
+
navigation.landingpage = "Qt Network"
navigation.cppclassespage = "Qt Network C++ Classes"
diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp
index 1da00813ce..ce1ec6442a 100644
--- a/src/network/kernel/qdnslookup_unix.cpp
+++ b/src/network/kernel/qdnslookup_unix.cpp
@@ -42,6 +42,7 @@
#if QT_CONFIG(library)
#include <qlibrary.h>
#endif
+#include <qvarlengtharray.h>
#include <qscopedpointer.h>
#include <qurl.h>
#include <private/qnativesocketengine_p.h>
@@ -58,6 +59,8 @@
# include <gnu/lib-names.h>
#endif
+#include <cstring>
+
QT_BEGIN_NAMESPACE
#if QT_CONFIG(library)
@@ -137,7 +140,7 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
// Initialize state.
struct __res_state state;
- memset(&state, 0, sizeof(state));
+ std::memset(&state, 0, sizeof(state));
if (local_res_ninit(&state) < 0) {
reply->error = QDnsLookup::ResolverError;
reply->errorString = tr("Resolver initialization failed");
@@ -189,11 +192,25 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
QScopedPointer<struct __res_state, QDnsLookupStateDeleter> state_ptr(&state);
// Perform DNS query.
- unsigned char response[PACKETSZ];
- memset(response, 0, sizeof(response));
- const int responseLength = local_res_nquery(&state, requestName, C_IN, requestType, response, sizeof(response));
+ QVarLengthArray<unsigned char, PACKETSZ> buffer(PACKETSZ);
+ std::memset(buffer.data(), 0, buffer.size());
+ int responseLength = local_res_nquery(&state, requestName, C_IN, requestType, buffer.data(), buffer.size());
+ if (Q_UNLIKELY(responseLength > PACKETSZ)) {
+ buffer.resize(responseLength);
+ std::memset(buffer.data(), 0, buffer.size());
+ responseLength = local_res_nquery(&state, requestName, C_IN, requestType, buffer.data(), buffer.size());
+ if (Q_UNLIKELY(responseLength > buffer.size())) {
+ // Ok, we give up.
+ reply->error = QDnsLookup::ResolverError;
+ reply->errorString.clear(); // We cannot be more specific, alas.
+ return;
+ }
+ }
- // Check the response header.
+ unsigned char *response = buffer.data();
+ // Check the response header. Though res_nquery returns -1 as a
+ // responseLength in case of error, we still can extract the
+ // exact error code from the response.
HEADER *header = (HEADER*)response;
const int answerCount = ntohs(header->ancount);
switch (header->rcode) {
diff --git a/src/network/kernel/qnetworkinterface_linux.cpp b/src/network/kernel/qnetworkinterface_linux.cpp
index 3211d1b8d8..01b2811070 100644
--- a/src/network/kernel/qnetworkinterface_linux.cpp
+++ b/src/network/kernel/qnetworkinterface_linux.cpp
@@ -165,7 +165,7 @@ template <typename Lambda> struct ProcessNetlinkRequest
int expectedType = expectedTypeForRequest(hdr->nlmsg_type);
const bool isDump = hdr->nlmsg_flags & NLM_F_DUMP;
forever {
- qssize_t len = recv(sock, buf, bufsize, 0);
+ qsizetype len = recv(sock, buf, bufsize, 0);
hdr = reinterpret_cast<struct nlmsghdr *>(buf);
if (!NLMSG_OK(hdr, len))
return;
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 98baa0c047..13e10e4102 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -1713,6 +1713,8 @@ void QAbstractSocket::connectToHost(const QString &hostName, quint16 port,
}
#endif
+ // Sync up with error string, which open() shall clear.
+ d->socketError = UnknownSocketError;
if (openMode & QIODevice::Unbuffered)
d->isBuffered = false;
else if (!d_func()->isBuffered)
@@ -1948,6 +1950,8 @@ bool QAbstractSocket::setSocketDescriptor(qintptr socketDescriptor, SocketState
return false;
}
+ // Sync up with error string, which open() shall clear.
+ d->socketError = UnknownSocketError;
if (d->threadData->hasEventDispatcher())
d->socketEngine->setReceiver(d);
diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h
index 3d788319a8..066a35ff85 100644
--- a/src/network/socket/qabstractsocket_p.h
+++ b/src/network/socket/qabstractsocket_p.h
@@ -156,6 +156,7 @@ public:
QAbstractSocket::SocketType socketType;
QAbstractSocket::SocketState state;
+ // Must be kept in sync with QIODevicePrivate::errorString.
QAbstractSocket::SocketError socketError;
QAbstractSocket::NetworkLayerProtocol preferredNetworkLayerProtocol;
diff --git a/src/network/socket/qlocalserver_win.cpp b/src/network/socket/qlocalserver_win.cpp
index 8cb3449343..ced923ced1 100644
--- a/src/network/socket/qlocalserver_win.cpp
+++ b/src/network/socket/qlocalserver_win.cpp
@@ -225,7 +225,7 @@ bool QLocalServerPrivate::addListener()
void QLocalServerPrivate::setError(const QString &function)
{
int windowsError = GetLastError();
- errorString = QString::fromLatin1("%1: %2").arg(function).arg(qt_error_string(windowsError));
+ errorString = QString::fromLatin1("%1: %2").arg(function, qt_error_string(windowsError));
error = QAbstractSocket::UnknownSocketError;
}
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index e8ab8de469..c303f01648 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -1321,6 +1321,9 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
setPortAndAddress(header.destinationPort, header.destinationAddress, &aa, &msg.namelen);
+ uint oldIfIndex = 0;
+ bool mustSetIpv6MulticastIf = false;
+
if (msg.namelen == sizeof(aa.a6)) {
// sending IPv6
if (header.hopLimit != -1) {
@@ -1332,7 +1335,7 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
cmsgptr = reinterpret_cast<WSACMSGHDR *>(reinterpret_cast<char *>(cmsgptr)
+ WSA_CMSG_SPACE(sizeof(int)));
}
- if (header.ifindex != 0 || !header.senderAddress.isNull()) {
+ if (!header.senderAddress.isNull()) {
struct in6_pktinfo *data = reinterpret_cast<in6_pktinfo *>(WSA_CMSG_DATA(cmsgptr));
memset(data, 0, sizeof(*data));
msg.Control.len += WSA_CMSG_SPACE(sizeof(*data));
@@ -1345,6 +1348,21 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
memcpy(&data->ipi6_addr, &tmp, sizeof(tmp));
cmsgptr = reinterpret_cast<WSACMSGHDR *>(reinterpret_cast<char *>(cmsgptr)
+ WSA_CMSG_SPACE(sizeof(*data)));
+ } else if (header.ifindex != 0) {
+ // Unlike other operating systems, setting the interface index in the in6_pktinfo
+ // structure above and leaving the ipi6_addr set to :: will cause the packets to be
+ // sent with source address ::. So we have to use IPV6_MULTICAST_IF, which MSDN is
+ // quite clear that "This option does not change the default interface for receiving
+ // IPv6 multicast traffic."
+ QT_SOCKOPTLEN_T len = sizeof(oldIfIndex);
+ if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+ reinterpret_cast<char *>(&oldIfIndex), &len) == -1
+ || ::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+ reinterpret_cast<const char *>(&header.ifindex), sizeof(header.ifindex)) == -1) {
+ setError(QAbstractSocket::NetworkError, SendDatagramErrorString);
+ return -1;
+ }
+ mustSetIpv6MulticastIf = true;
}
} else {
// sending IPv4
@@ -1398,6 +1416,12 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
ret = qint64(bytesSent);
}
+ if (mustSetIpv6MulticastIf) {
+ // undo what we did above
+ ::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+ reinterpret_cast<char *>(&oldIfIndex), sizeof(oldIfIndex));
+ }
+
#if defined (QNATIVESOCKETENGINE_DEBUG)
qDebug("QNativeSocketEnginePrivate::nativeSendDatagram(%p \"%s\", %lli, \"%s\", %i) == %lli", data,
qt_prettyDebug(data, qMin<qint64>(len, 16), len).data(), len,
diff --git a/src/network/socket/qudpsocket.cpp b/src/network/socket/qudpsocket.cpp
index 79629a07f2..85c4f4cbfd 100644
--- a/src/network/socket/qudpsocket.cpp
+++ b/src/network/socket/qudpsocket.cpp
@@ -185,6 +185,10 @@ QUdpSocket::~QUdpSocket()
This function returns \c true if successful; otherwise it returns \c false
and sets the socket error accordingly.
+ \note Joining IPv6 multicast groups without an interface selection is not
+ supported in all operating systems. Consider using the overload where the
+ interface is specified.
+
\sa leaveMulticastGroup()
*/
bool QUdpSocket::joinMulticastGroup(const QHostAddress &groupAddress)
@@ -219,6 +223,9 @@ bool QUdpSocket::joinMulticastGroup(const QHostAddress &groupAddress,
This function returns \c true if successful; otherwise it returns \c false and
sets the socket error accordingly.
+ \note This function should be called with the same arguments as were passed
+ to joinMulticastGroup().
+
\sa joinMulticastGroup()
*/
bool QUdpSocket::leaveMulticastGroup(const QHostAddress &groupAddress)
@@ -233,6 +240,9 @@ bool QUdpSocket::leaveMulticastGroup(const QHostAddress &groupAddress)
Leaves the multicast group specified by \a groupAddress on the interface \a
iface.
+ \note This function should be called with the same arguments as were passed
+ to joinMulticastGroup().
+
\sa joinMulticastGroup()
*/
bool QUdpSocket::leaveMulticastGroup(const QHostAddress &groupAddress,
diff --git a/src/network/ssl/qsslkey_qt.cpp b/src/network/ssl/qsslkey_qt.cpp
index 817317f303..a85fed21ed 100644
--- a/src/network/ssl/qsslkey_qt.cpp
+++ b/src/network/ssl/qsslkey_qt.cpp
@@ -95,7 +95,7 @@ static OidLengthMap createOidMap()
oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.8"), 160); // secp160r1
oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.9"), 160); // secp160k1
oids.insert(oids.cend(), QByteArrayLiteral("1.3.36.3.3.2.8.1.1.11"), 384); // brainpoolP384r1
- oids.insert(oids.cend(), QByteArrayLiteral("1.3.36.3.3.2.8.1.1.13"), 521); // brainpoolP512r1
+ oids.insert(oids.cend(), QByteArrayLiteral("1.3.36.3.3.2.8.1.1.13"), 512); // brainpoolP512r1
oids.insert(oids.cend(), QByteArrayLiteral("1.3.36.3.3.2.8.1.1.7"), 256); // brainpoolP256r1
return oids;
}
diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp
index 5c2bd55198..046b432252 100644
--- a/src/network/ssl/qsslsocket_mac.cpp
+++ b/src/network/ssl/qsslsocket_mac.cpp
@@ -47,6 +47,7 @@
#include "qsslkey_p.h"
#include <QtCore/qmessageauthenticationcode.h>
+#include <QtCore/qoperatingsystemversion.h>
#include <QtCore/qcryptographichash.h>
#include <QtCore/qsystemdetection.h>
#include <QtCore/qdatastream.h>
@@ -1307,13 +1308,17 @@ bool QSslSocketBackendPrivate::verifyPeerTrust()
// actual system CA certificate list (which most use-cases need) other than
// by letting SecTrustEvaluate fall through to the system list; so, in this case
// (even though the client code may have provided its own certs), we retain
- // the default behavior.
+ // the default behavior. Note, with macOS SDK below 10.12 using 'trust my
+ // anchors only' may result in some valid chains rejected, apparently the
+ // ones containing intermediated certificates; so we use this functionality
+ // on more recent versions only.
+
+ bool anchorsFromConfigurationOnly = false;
#ifdef Q_OS_MACOS
- const bool anchorsFromConfigurationOnly = true;
-#else
- const bool anchorsFromConfigurationOnly = false;
-#endif
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSSierra)
+ anchorsFromConfigurationOnly = true;
+#endif // Q_OS_MACOS
SecTrustSetAnchorCertificatesOnly(trust, anchorsFromConfigurationOnly);
diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp
index 6c5a09962b..f64ae2e020 100644
--- a/src/network/ssl/qsslsocket_winrt.cpp
+++ b/src/network/ssl/qsslsocket_winrt.cpp
@@ -47,6 +47,7 @@
#include <QtCore/QSysInfo>
#include <QtCore/qfunctions_winrt.h>
#include <private/qnativesocketengine_winrt_p.h>
+#include <private/qeventdispatcher_winrt_p.h>
#include <windows.networking.h>
#include <windows.networking.sockets.h>
@@ -443,8 +444,11 @@ void QSslSocketBackendPrivate::continueHandshake()
return;
}
- hr = op->put_Completed(Callback<IAsyncActionCompletedHandler>(
- this, &QSslSocketBackendPrivate::onSslUpgrade).Get());
+ hr = QEventDispatcherWinRT::runOnXamlThread([this, op]() {
+ HRESULT hr = op->put_Completed(Callback<IAsyncActionCompletedHandler>(
+ this, &QSslSocketBackendPrivate::onSslUpgrade).Get());
+ return hr;
+ });
Q_ASSERT_SUCCEEDED(hr);
}
diff --git a/src/platformsupport/eglconvenience/qeglpbuffer.cpp b/src/platformsupport/eglconvenience/qeglpbuffer.cpp
index 67d7204734..15fc089778 100644
--- a/src/platformsupport/eglconvenience/qeglpbuffer.cpp
+++ b/src/platformsupport/eglconvenience/qeglpbuffer.cpp
@@ -62,7 +62,7 @@ QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffs
, m_display(display)
, m_pbuffer(EGL_NO_SURFACE)
{
- bool hasSurfaceless = !flags.testFlag(QEGLPlatformContext::NoSurfaceless)
+ m_hasSurfaceless = !flags.testFlag(QEGLPlatformContext::NoSurfaceless)
&& q_hasEglExtension(display, "EGL_KHR_surfaceless_context");
// Disable surfaceless contexts on Mesa for now. As of 10.6.0 and Intel at least, some
@@ -72,9 +72,9 @@ QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffs
// read/draw surface in the Intel backend.
const char *vendor = eglQueryString(display, EGL_VENDOR); // hard to check for GL_ strings here, so blacklist all Mesa
if (vendor && strstr(vendor, "Mesa"))
- hasSurfaceless = false;
+ m_hasSurfaceless = false;
- if (hasSurfaceless)
+ if (m_hasSurfaceless)
return;
EGLConfig config = q_configFromGLFormat(m_display, m_format, false, EGL_PBUFFER_BIT);
@@ -100,4 +100,9 @@ QEGLPbuffer::~QEGLPbuffer()
eglDestroySurface(m_display, m_pbuffer);
}
+bool QEGLPbuffer::isValid() const
+{
+ return m_pbuffer != EGL_NO_SURFACE || m_hasSurfaceless;
+}
+
QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglpbuffer_p.h b/src/platformsupport/eglconvenience/qeglpbuffer_p.h
index eed8cd9dca..0285e067a6 100644
--- a/src/platformsupport/eglconvenience/qeglpbuffer_p.h
+++ b/src/platformsupport/eglconvenience/qeglpbuffer_p.h
@@ -64,7 +64,7 @@ public:
~QEGLPbuffer();
QSurfaceFormat format() const override { return m_format; }
- bool isValid() const override { return m_pbuffer != EGL_NO_SURFACE; }
+ bool isValid() const override;
EGLSurface pbuffer() const { return m_pbuffer; }
@@ -72,6 +72,7 @@ private:
QSurfaceFormat m_format;
EGLDisplay m_display;
EGLSurface m_pbuffer;
+ bool m_hasSurfaceless;
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
index 898cabd786..beec8e763c 100644
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
+++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
@@ -1773,7 +1773,10 @@ QFixed QFontEngineFT::scaledBitmapMetrics(QFixed m) const
glyph_metrics_t QFontEngineFT::scaledBitmapMetrics(const glyph_metrics_t &m, const QTransform &t) const
{
- QTransform trans(t);
+ QTransform trans;
+ trans.setMatrix(t.m11(), t.m12(), t.m13(),
+ t.m21(), t.m22(), t.m23(),
+ 0, 0, t.m33());
const qreal scaleFactor = scalableBitmapScaleFactor.toReal();
trans.scale(scaleFactor, scaleFactor);
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index 6347d4d231..237e8a89a5 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -416,7 +416,19 @@ extern CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef);
template <>
QFontEngine *QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>::fontEngine(const QFontDef &fontDef, void *usrPtr)
{
- CTFontDescriptorRef descriptor = static_cast<CTFontDescriptorRef>(usrPtr);
+ QCFType<CTFontDescriptorRef> descriptor = QCFType<CTFontDescriptorRef>::constructFromGet(
+ static_cast<CTFontDescriptorRef>(usrPtr));
+
+ // CoreText will sometimes invalidate information in font descriptors that refer
+ // to system fonts in certain function calls or application states. While the descriptor
+ // looks the same from the outside, some internal plumbing is different, causing the results
+ // of creating CTFonts from those descriptors unreliable. The work-around for this
+ // is to copy the attributes of those descriptors each time we make a new CTFont
+ // from them instead of referring to the original, as that may trigger the CoreText bug.
+ if (m_systemFontDescriptors.contains(descriptor)) {
+ QCFType<CFDictionaryRef> attributes = CTFontDescriptorCopyAttributes(descriptor);
+ descriptor = CTFontDescriptorCreateWithAttributes(attributes);
+ }
// Since we do not pass in the destination DPI to CoreText when making
// the font, we need to pass in a point size which is scaled to include
@@ -427,14 +439,10 @@ QFontEngine *QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>::fontEngine
qreal scaledPointSize = fontDef.pixelSize;
CGAffineTransform matrix = qt_transform_from_fontdef(fontDef);
- CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, scaledPointSize, &matrix);
- if (font) {
- QFontEngine *engine = new QCoreTextFontEngine(font, fontDef);
- CFRelease(font);
- return engine;
- }
+ if (QCFType<CTFontRef> font = CTFontCreateWithFontDescriptor(descriptor, scaledPointSize, &matrix))
+ return new QCoreTextFontEngine(font, fontDef);
- return NULL;
+ return nullptr;
}
#ifndef QT_NO_FREETYPE
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
index 76ab31c046..05f6ed641c 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
@@ -87,12 +87,14 @@ public:
QFont *themeFont(QPlatformTheme::Font) const;
const QHash<QPlatformTheme::Font, QFont *> &themeFonts() const;
+protected:
+ mutable QSet<CTFontDescriptorRef> m_systemFontDescriptors;
+
private:
void populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName = QString());
mutable QString defaultFontName;
- mutable QSet<CTFontDescriptorRef> m_systemFontDescriptors;
mutable QHash<QPlatformTheme::Font, QFont *> m_themeFonts;
bool m_hasPopulatedAliases;
};
diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
index 2d6426db7f..47a65eded8 100644
--- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
+++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
@@ -49,6 +49,9 @@
#include <qpa/qwindowsysteminterface.h>
#include <private/qcore_unix_p.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qinputdevicemanager_p.h>
+
#ifdef Q_OS_FREEBSD
#include <dev/evdev/input.h>
#else
@@ -222,6 +225,8 @@ void QEvdevKeyboardHandler::readKeycode()
void QEvdevKeyboardHandler::processKeyEvent(int nativecode, int unicode, int qtcode,
Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat)
{
+ QGuiApplicationPrivate::inputDeviceManager()->setKeyboardModifiers(modifiers, qtcode);
+
QWindowSystemInterface::handleExtendedKeyEvent(0, (isPress ? QEvent::KeyPress : QEvent::KeyRelease),
qtcode, modifiers, nativecode + 8, 0, int(modifiers),
(unicode != 0xffff ) ? QString(unicode) : QString(), autoRepeat);
@@ -403,6 +408,8 @@ QEvdevKeyboardHandler::KeycodeAction QEvdevKeyboardHandler::processKeycode(quint
Qt::KeyboardModifiers qtmods = Qt::KeyboardModifiers(qtcode & modmask);
qtcode &= ~modmask;
+ // qtmods here is the modifier state before the event, i.e. not
+ // including the current key in case it is a modifier.
qCDebug(qLcEvdevKeyMap, "Processing: uni=%04x, qt=%08x, qtmod=%08x", unicode, qtcode, int(qtmods));
// If NumLockOff and keypad key pressed remap event sent
diff --git a/src/platformsupport/input/libinput/qlibinputkeyboard.cpp b/src/platformsupport/input/libinput/qlibinputkeyboard.cpp
index 21f7fde7c8..54af8a5b0c 100644
--- a/src/platformsupport/input/libinput/qlibinputkeyboard.cpp
+++ b/src/platformsupport/input/libinput/qlibinputkeyboard.cpp
@@ -40,6 +40,8 @@
#include "qlibinputkeyboard_p.h"
#include <QtCore/QTextCodec>
#include <QtCore/QLoggingCategory>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qinputdevicemanager_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <libinput.h>
#ifndef QT_NO_XKBCOMMON_EVDEV
@@ -196,6 +198,8 @@ void QLibInputKeyboard::processKey(libinput_event_keyboard *e)
const xkb_keysym_t sym = xkb_state_key_get_one_sym(m_state, k);
+ // mods here is the modifier state before the event, i.e. not
+ // including the current key in case it is a modifier.
Qt::KeyboardModifiers mods = Qt::NoModifier;
const int qtkey = keysymToQtKey(sym, &mods, text);
@@ -211,6 +215,7 @@ void QLibInputKeyboard::processKey(libinput_event_keyboard *e)
xkb_state_update_key(m_state, k, pressed ? XKB_KEY_DOWN : XKB_KEY_UP);
+ QGuiApplicationPrivate::inputDeviceManager()->setKeyboardModifiers(mods, qtkey);
QWindowSystemInterface::handleExtendedKeyEvent(nullptr,
pressed ? QEvent::KeyPress : QEvent::KeyRelease,
qtkey, mods, k, sym, mods, text);
diff --git a/src/platformsupport/input/libinput/qlibinputpointer.cpp b/src/platformsupport/input/libinput/qlibinputpointer.cpp
index 12379a83fa..cb08ab53b2 100644
--- a/src/platformsupport/input/libinput/qlibinputpointer.cpp
+++ b/src/platformsupport/input/libinput/qlibinputpointer.cpp
@@ -42,6 +42,8 @@
#include <QtCore/QEvent>
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qinputdevicemanager_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <private/qhighdpiscaling_p.h>
@@ -80,7 +82,7 @@ void QLibInputPointer::processButton(libinput_event_pointer *e)
m_buttons.setFlag(button, pressed);
QEvent::Type type = pressed ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease;
- Qt::KeyboardModifiers mods = QGuiApplication::keyboardModifiers();
+ Qt::KeyboardModifiers mods = QGuiApplicationPrivate::inputDeviceManager()->keyboardModifiers();
QWindowSystemInterface::handleMouseEvent(nullptr, m_pos, m_pos, m_buttons, button, type, mods);
}
@@ -95,7 +97,7 @@ void QLibInputPointer::processMotion(libinput_event_pointer *e)
m_pos.setX(qBound(g.left(), qRound(m_pos.x() + dx), g.right()));
m_pos.setY(qBound(g.top(), qRound(m_pos.y() + dy), g.bottom()));
- Qt::KeyboardModifiers mods = QGuiApplication::keyboardModifiers();
+ Qt::KeyboardModifiers mods = QGuiApplicationPrivate::inputDeviceManager()->keyboardModifiers();
QWindowSystemInterface::handleMouseEvent(nullptr, m_pos, m_pos, m_buttons,
Qt::NoButton, QEvent::MouseMove, mods);
diff --git a/src/plugins/bearer/bearer.pro b/src/plugins/bearer/bearer.pro
index b362722b28..824fd0388f 100644
--- a/src/plugins/bearer/bearer.pro
+++ b/src/plugins/bearer/bearer.pro
@@ -6,11 +6,6 @@ QT_FOR_CONFIG += network-private
SUBDIRS += connman networkmanager
}
-#win32:SUBDIRS += nla
-win32:SUBDIRS += generic
-win32:!winrt: SUBDIRS += nativewifi
-darwin:qtConfig(corewlan): SUBDIRS += corewlan
-mac:SUBDIRS += generic
android:SUBDIRS += android
isEmpty(SUBDIRS):SUBDIRS = generic
diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp
index 55eec57270..7c9db4640b 100644
--- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp
+++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp
@@ -506,7 +506,7 @@ void QConnmanTechnologyInterface::scan()
void QConnmanTechnologyInterface::scanReply(QDBusPendingCallWatcher *call)
{
- QDBusPendingReply<QVariantMap> props_reply = *call;
+ QDBusPendingReply<> props_reply = *call;
if (props_reply.isError()) {
qDebug() << props_reply.error().message();
}
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index a3bc58bb89..309e41bfd6 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
@@ -106,7 +106,8 @@ namespace QtAndroidAccessibility
QAccessibleInterface *iface = interfaceFromId(objectId);
if (iface && iface->isValid()) {
const int childCount = iface->childCount();
- QVarLengthArray<jint, 8> ifaceIdArray(childCount);
+ QVarLengthArray<jint, 8> ifaceIdArray;
+ ifaceIdArray.reserve(childCount);
for (int i = 0; i < childCount; ++i) {
QAccessibleInterface *child = iface->child(i);
if (child && child->isValid())
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index 7fa809f3f8..fe4c5be4cb 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -526,6 +526,10 @@ void QAndroidInputContext::updateCursorPosition()
void QAndroidInputContext::updateSelectionHandles()
{
+ static bool noHandles = qEnvironmentVariableIntValue("QT_QPA_NO_TEXT_HANDLES");
+ if (noHandles)
+ return;
+
auto im = qGuiApp->inputMethod();
if (!m_focusObject || (m_cursorHandleShown == CursorHandleNotShown)) {
// Hide the handles
@@ -843,11 +847,11 @@ jint QAndroidInputContext::getCursorCapsMode(jint /*reqModes*/)
const uint qtInputMethodHints = query->value(Qt::ImHints).toUInt();
- if (qtInputMethodHints & Qt::ImhPreferUppercase)
- res = CAP_MODE_SENTENCES;
+ if (!(qtInputMethodHints & Qt::ImhLowercaseOnly) && !(qtInputMethodHints & Qt::ImhNoAutoUppercase))
+ res |= CAP_MODE_SENTENCES;
if (qtInputMethodHints & Qt::ImhUppercaseOnly)
- res = CAP_MODE_CHARACTERS;
+ res |= CAP_MODE_CHARACTERS;
return res;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h
index 129307acf4..0530aa8201 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.h
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h
@@ -84,6 +84,7 @@ private:
NSOpenGLContext *m_shareContext;
QSurfaceFormat m_format;
QPointer<QWindow> m_currentWindow;
+ bool m_didCheckForSoftwareContext;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index 5ed81a7f1b..b656025ec7 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -121,7 +121,8 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo
const QVariant &nativeHandle)
: m_context(nil),
m_shareContext(nil),
- m_format(format)
+ m_format(format),
+ m_didCheckForSoftwareContext(false)
{
if (!nativeHandle.isNull()) {
if (!nativeHandle.canConvert<QCocoaNativeContext>()) {
@@ -152,9 +153,32 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo
QMacAutoReleasePool pool; // For the SG Canvas render thread
+ m_shareContext = share ? static_cast<QCocoaGLContext *>(share)->nsOpenGLContext() : nil;
+
+ if (m_shareContext) {
+ // Allow sharing between 3.2 Core and 4.1 Core profile versions in
+ // cases where NSOpenGLContext creates a 4.1 context where a 3.2
+ // context was requested. Due to the semantics of QSurfaceFormat
+ // this 4.1 version can find its way onto the format for the new
+ // context, even though it was at no point requested by the user.
+ GLint shareContextRequestedProfile;
+ [m_shareContext.pixelFormat getValues:&shareContextRequestedProfile
+ forAttribute:NSOpenGLPFAOpenGLProfile forVirtualScreen:0];
+ auto shareContextActualProfile = share->format().version();
+
+ if (shareContextRequestedProfile == NSOpenGLProfileVersion3_2Core &&
+ shareContextActualProfile >= qMakePair(4, 1)) {
+
+ // There is a mismatch, downgrade requested format to make the
+ // NSOpenGLPFAOpenGLProfile attributes match. (NSOpenGLContext will
+ // fail to create a new context if there is a mismatch).
+ if (m_format.version() >= qMakePair(4, 1))
+ m_format.setVersion(3, 2);
+ }
+ }
+
// create native context for the requested pixel format and share
NSOpenGLPixelFormat *pixelFormat = createNSOpenGLPixelFormat(m_format);
- m_shareContext = share ? static_cast<QCocoaGLContext *>(share)->nsOpenGLContext() : nil;
m_context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:m_shareContext];
// retry without sharing on context creation failure.
@@ -239,6 +263,22 @@ bool QCocoaGLContext::makeCurrent(QPlatformSurface *surface)
QWindow *window = static_cast<QCocoaWindow *>(surface)->window();
setActiveWindow(window);
+
+ // Disable high-resolution surfaces when using the software renderer, which has the
+ // problem that the system silently falls back to a to using a low-resolution buffer
+ // when a high-resolution buffer is requested. This is not detectable using the NSWindow
+ // convertSizeToBacking and backingScaleFactor APIs. A typical result of this is that Qt
+ // will display a quarter of the window content when running in a virtual machine.
+ if (!m_didCheckForSoftwareContext) {
+ m_didCheckForSoftwareContext = true;
+
+ const GLubyte* renderer = glGetString(GL_RENDERER);
+ if (qstrcmp((const char *)renderer, "Apple Software Renderer") == 0) {
+ NSView *view = static_cast<QCocoaWindow *>(surface)->m_view;
+ [view setWantsBestResolutionOpenGLSurface:NO];
+ }
+ }
+
update();
return true;
}
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h
index 32a8fd89b4..6f3aca3a51 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.h
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.h
@@ -71,6 +71,7 @@ public:
QList<QCocoaMenuItem*> merged() const;
NSMenuItem *itemForRole(QPlatformMenuItem::MenuRole r);
+ QCocoaWindow *cocoaWindow() const;
void syncMenu_helper(QPlatformMenu *menu, bool menubarUpdate);
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index fd28a4d7da..8091d00bda 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -452,5 +452,10 @@ NSMenuItem *QCocoaMenuBar::itemForRole(QPlatformMenuItem::MenuRole r)
return nullptr;
}
+QCocoaWindow *QCocoaMenuBar::cocoaWindow() const
+{
+ return m_window.data();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
index fdca7297de..cd597da71c 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
@@ -43,6 +43,7 @@
#include "qcocoahelpers.h"
#include "qcocoamenubar.h"
#include "qcocoamenuitem.h"
+#include "qcocoaintegration.h"
#include <QtCore/private/qcore_mac_p.h>
#include <QtCore/private/qthread_p.h>
@@ -347,10 +348,13 @@
- (BOOL)validateMenuItem:(NSMenuItem*)menuItem
{
- if ([menuItem action] == @selector(hide:)
- || [menuItem action] == @selector(hideOtherApplications:)
+ if ([menuItem action] == @selector(hideOtherApplications:)
|| [menuItem action] == @selector(unhideAllApplications:)) {
return [NSApp validateMenuItem:menuItem];
+ } else if ([menuItem action] == @selector(hide:)) {
+ if (QCocoaIntegration::instance()->activePopupWindow())
+ return NO;
+ return [NSApp validateMenuItem:menuItem];
} else if ([menuItem tag]) {
QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([menuItem tag]);
return cocoaItem->isEnabled();
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index c3160e32c2..c000c90a85 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -198,6 +198,7 @@ void QCocoaWindow::initialize()
BOOL enable = qt_mac_resolveOption(YES, window(), "_q_mac_wantsBestResolutionOpenGLSurface",
"QT_MAC_WANTS_BEST_RESOLUTION_OPENGL_SURFACE");
[m_view setWantsBestResolutionOpenGLSurface:enable];
+ // See also QCocoaGLContext::makeCurrent for software renderer workarounds.
}
BOOL enable = qt_mac_resolveOption(NO, window(), "_q_mac_wantsLayer",
"QT_MAC_WANTS_LAYER");
diff --git a/src/plugins/platforms/eglfs/api/qeglfscontext_p.h b/src/plugins/platforms/eglfs/api/qeglfscontext_p.h
index 96f7f01381..af8725b6b3 100644
--- a/src/plugins/platforms/eglfs/api/qeglfscontext_p.h
+++ b/src/plugins/platforms/eglfs/api/qeglfscontext_p.h
@@ -52,6 +52,7 @@
//
#include "qeglfsglobal_p.h"
+#include "qeglfscursor_p.h"
#include <QtEglSupport/private/qeglplatformcontext_p.h>
#include <QtCore/QVariant>
@@ -68,6 +69,8 @@ public:
void runGLChecks() override;
void swapBuffers(QPlatformSurface *surface) override;
+ QEglFSCursorData cursorData;
+
private:
EGLNativeWindowType m_tempWindow;
};
diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
index f46206cab5..22319fcc66 100644
--- a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
@@ -40,10 +40,10 @@
#include "qeglfscursor_p.h"
#include "qeglfsintegration_p.h"
#include "qeglfsscreen_p.h"
+#include "qeglfscontext_p.h"
#include <qpa/qwindowsysteminterface.h>
#include <QtGui/QOpenGLContext>
-#include <QtGui/QOpenGLShaderProgram>
#include <QtCore/QFile>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonArray>
@@ -115,13 +115,6 @@ void QEglFSCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::Device
void QEglFSCursor::resetResources()
{
- if (QOpenGLContext *ctx = QOpenGLContext::currentContext()) {
- GraphicsContextData &gfx(m_gfx[ctx]);
- delete gfx.program;
- glDeleteTextures(1, &gfx.customCursorTexture);
- glDeleteTextures(1, &gfx.atlasTexture);
- gfx = GraphicsContextData();
- }
m_cursor.customCursorPending = !m_cursor.customCursorImage.isNull();
}
@@ -144,8 +137,8 @@ void QEglFSCursor::createShaderPrograms()
" gl_FragColor = texture2D(texture, textureCoord).bgra;\n"
"}\n";
- GraphicsContextData &gfx(m_gfx[QOpenGLContext::currentContext()]);
- gfx.program = new QOpenGLShaderProgram;
+ QEglFSCursorData &gfx = static_cast<QEglFSContext*>(QOpenGLContext::currentContext()->handle())->cursorData;
+ gfx.program.reset(new QOpenGLShaderProgram);
gfx.program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
gfx.program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
gfx.program->bindAttributeLocation("vertexCoordEntry", 0);
@@ -475,7 +468,7 @@ void QEglFSCursor::draw(const QRectF &r)
{
StateSaver stateSaver;
- GraphicsContextData &gfx(m_gfx[QOpenGLContext::currentContext()]);
+ QEglFSCursorData &gfx = static_cast<QEglFSContext*>(QOpenGLContext::currentContext()->handle())->cursorData;
if (!gfx.program) {
// one time initialization
initializeOpenGLFunctions();
diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
index aaeb83cb99..89c2e89f58 100644
--- a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
+++ b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
@@ -56,6 +56,7 @@
#include <qpa/qplatformscreen.h>
#include <QtGui/QMatrix4x4>
#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/private/qinputdevicemanager_p.h>
QT_BEGIN_NAMESPACE
@@ -81,6 +82,15 @@ private:
#if QT_CONFIG(opengl)
+struct QEglFSCursorData {
+ QScopedPointer<QOpenGLShaderProgram> program;
+ int textureEntry = 0;
+ int matEntry = 0;
+ uint customCursorTexture = 0;
+ uint atlasTexture = 0;
+ qint64 customCursorKey = 0;
+};
+
class Q_EGLFS_EXPORT QEglFSCursor : public QPlatformCursor
, protected QOpenGLFunctions
{
@@ -143,18 +153,6 @@ private:
QEglFSCursorDeviceListener *m_deviceListener;
bool m_updateRequested;
QMatrix4x4 m_rotationMatrix;
-
- struct GraphicsContextData {
- GraphicsContextData() : program(nullptr), textureEntry(0), matEntry(0),
- customCursorTexture(0), atlasTexture(0), customCursorKey(0) { }
- QOpenGLShaderProgram *program;
- int textureEntry;
- int matEntry;
- uint customCursorTexture;
- uint atlasTexture;
- qint64 customCursorKey;
- };
- QHash<QOpenGLContext *, GraphicsContextData> m_gfx;
};
#endif // QT_CONFIG(opengl)
diff --git a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro
index 6d759938b5..92ee83fd8f 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro
+++ b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro
@@ -7,8 +7,9 @@ qtConfig(eglfs_egldevice): SUBDIRS *= eglfs_kms_support eglfs_kms_egldevice
qtConfig(eglfs_brcm): SUBDIRS += eglfs_brcm
qtConfig(eglfs_mali): SUBDIRS += eglfs_mali
qtConfig(eglfs_viv): SUBDIRS += eglfs_viv
+qtConfig(eglfs_rcar): SUBDIRS += eglfs_rcar
qtConfig(eglfs_viv_wl): SUBDIRS += eglfs_viv_wl
-
+qtConfig(eglfs_openwfd): SUBDIRS += eglfs_openwfd
qtConfig(opengl): SUBDIRS += eglfs_emu
eglfs_kms_egldevice.depends = eglfs_kms_support
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/eglfs_openwfd.json b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/eglfs_openwfd.json
new file mode 100644
index 0000000000..cf7cf6b887
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/eglfs_openwfd.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "eglfs_openwfd" ]
+}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/eglfs_openwfd.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/eglfs_openwfd.pro
new file mode 100644
index 0000000000..448b4cbe21
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/eglfs_openwfd.pro
@@ -0,0 +1,17 @@
+TARGET = qeglfs-openwfd-integration
+
+QT += core-private gui-private eglfsdeviceintegration-private
+
+INCLUDEPATH += $$PWD/../../api
+CONFIG += egl
+
+SOURCES += $$PWD/qeglfsopenwfdmain.cpp \
+ $$PWD/qeglfsopenwfdintegration.cpp
+
+HEADERS += $$PWD/qeglfsopenwfdintegration.h
+
+OTHER_FILES += $$PWD/eglfs_openwfd.json
+
+PLUGIN_TYPE = egldeviceintegrations
+PLUGIN_CLASS_NAME = QEglFSOpenWFDIntegrationPlugin
+load(qt_plugin)
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.cpp
new file mode 100644
index 0000000000..bb176a69d2
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.cpp
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins 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$
+**
+****************************************************************************/
+
+#include "qeglfsopenwfdintegration.h"
+
+#include "wfd.h"
+#include "wfdext2.h"
+
+QT_BEGIN_NAMESPACE
+
+#define MAX_NUM_OF_WFD_BUFFERS 3
+#define MAX_NUM_OF_WFD_DEVICES 4
+#define MAX_NUM_OF_WFD_PIPELINES 4
+#define MAX_NUM_OF_WFD_PORT_MODES 64
+#define MAX_NUM_OF_WFD_PORTS 4
+
+typedef struct wfd_buffer {
+ WFD_EGLImageType* image;
+ WFDSource source;
+} wfd_buffer_t;
+
+typedef struct wfd_window {
+ WFDDevice dev;
+ WFDPort port;
+ WFDPipeline pipeline;
+ int numBuffers;
+ wfd_buffer_t buffers[MAX_NUM_OF_WFD_BUFFERS];
+} wfd_window_t;
+
+void QEglFSOpenWFDIntegration::platformInit()
+{
+ QEglFSDeviceIntegration::platformInit();
+
+ mNativeDisplay = EGL_DEFAULT_DISPLAY;
+
+ // Get device list
+ WFDint numDevs = wfdEnumerateDevices(nullptr, 0, nullptr);
+ WFDint devIds[MAX_NUM_OF_WFD_DEVICES];
+
+ if (numDevs > 0)
+ wfdEnumerateDevices(devIds, numDevs, nullptr);
+
+ // Create device
+ mDevice = wfdCreateDevice(WFD_DEFAULT_DEVICE_ID, nullptr);
+
+ if (WFD_INVALID_HANDLE == mDevice)
+ qFatal( "Failed to create wfd device");
+
+ // Get port list
+ WFDint portIds[MAX_NUM_OF_WFD_PORTS];
+ WFDint numPorts = wfdEnumeratePorts(mDevice, nullptr, 0, nullptr);
+ wfdEnumeratePorts(mDevice, portIds, numPorts, nullptr);
+
+ // Create port
+ mPort = wfdCreatePort(mDevice, portIds[0], nullptr);
+
+ if (WFD_INVALID_HANDLE == mPort)
+ qFatal("Failed to create wfd port");
+
+ // Get port modes
+ WFDint numPortModes = wfdGetPortModes(mDevice, mPort, nullptr, 0);
+ WFDPortMode portModes[MAX_NUM_OF_WFD_PORT_MODES];
+ wfdGetPortModes(mDevice, mPort, portModes, numPortModes);
+
+ // Get width and height
+ mScreenSize.setWidth(wfdGetPortModeAttribi(mDevice, mPort, portModes[0], WFD_PORT_MODE_WIDTH));
+ mScreenSize.setHeight(wfdGetPortModeAttribi(mDevice, mPort, portModes[0], WFD_PORT_MODE_HEIGHT));
+
+ // Set port mode
+ wfdSetPortMode(mDevice, mPort, portModes[0]);
+ WFDErrorCode eError = wfdGetError(mDevice);
+ if (WFD_ERROR_NONE != eError)
+ qFatal("Failed to set wfd port mode");
+
+ // Power on
+ wfdSetPortAttribi(mDevice, mPort, WFD_PORT_POWER_MODE, WFD_POWER_MODE_ON);
+ eError = wfdGetError(mDevice);
+ if (WFD_ERROR_NONE != eError)
+ qFatal("Failed to power on wfd port");
+}
+
+QSize QEglFSOpenWFDIntegration::screenSize() const
+{
+ return mScreenSize;
+}
+
+EGLNativeDisplayType QEglFSOpenWFDIntegration::platformDisplay() const
+{
+ return mNativeDisplay;
+}
+
+EGLNativeWindowType QEglFSOpenWFDIntegration::createNativeWindow(QPlatformWindow *window,
+ const QSize &size,
+ const QSurfaceFormat &format)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(format);
+
+ // Get list of pipelines
+ WFDint numPipelines = wfdEnumeratePipelines(mDevice, nullptr, 0, nullptr);
+
+ WFDint pipelineIds[MAX_NUM_OF_WFD_PIPELINES];
+ wfdEnumeratePipelines(mDevice, pipelineIds, numPipelines, nullptr);
+
+ WFDint testId = 0;
+ testId = pipelineIds[0];
+ WFDPipeline pipeline = wfdCreatePipeline(mDevice, testId, nullptr);
+ if (WFD_INVALID_HANDLE == pipeline)
+ qFatal("Failed to create wfd pipeline");
+
+ wfdSetPipelineAttribi(mDevice, pipeline, WFD_PIPELINE_TRANSPARENCY_ENABLE,
+ (WFD_TRANSPARENCY_SOURCE_ALPHA|WFD_TRANSPARENCY_GLOBAL_ALPHA));
+
+ WFDErrorCode eError = wfdGetError(mDevice);
+ if (WFD_ERROR_NONE != eError)
+ qFatal("Failed to set WFD_PIPELINE_TRANSPARENCY_ENABLE");
+
+ wfdSetPipelineAttribi(mDevice, pipeline, WFD_PIPELINE_GLOBAL_ALPHA, 255);
+ eError = wfdGetError(mDevice);
+ if (WFD_ERROR_NONE != eError)
+ qFatal("Failed to set WFD_PIPELINE_GLOBAL_ALPHA");
+
+ wfdBindPipelineToPort(mDevice, mPort, pipeline);
+ eError = wfdGetError(mDevice);
+ if (WFD_ERROR_NONE != eError)
+ qFatal("Failed to bind port to pipeline");
+
+ // Create buffers
+ WFDSource source[MAX_NUM_OF_WFD_BUFFERS] = {WFD_INVALID_HANDLE, WFD_INVALID_HANDLE,
+ WFD_INVALID_HANDLE};
+ WFDEGLImage eglImageHandles[MAX_NUM_OF_WFD_BUFFERS];
+ WFD_EGLImageType* wfdEglImages[MAX_NUM_OF_WFD_BUFFERS];
+
+ for (int i = 0; i < MAX_NUM_OF_WFD_BUFFERS; i++) {
+ wfdCreateWFDEGLImages(mDevice, mScreenSize.width(), mScreenSize.height(),
+ WFD_FORMAT_RGBA8888, WFD_USAGE_OPENGL_ES2 | WFD_USAGE_DISPLAY,
+ 1, &(eglImageHandles[i]), 0);
+
+ wfdEglImages[i] = (WFD_EGLImageType *)(eglImageHandles[i]);
+ if (WFD_INVALID_HANDLE == wfdEglImages[i])
+ qFatal("Failed to create WDFEGLImages");
+
+ source[i] = wfdCreateSourceFromImage(mDevice, pipeline, eglImageHandles[i], nullptr);
+ if (WFD_INVALID_HANDLE == source[i])
+ qFatal("Failed to create source from EGLImage");
+ }
+
+ // Commit port
+ wfdDeviceCommit(mDevice, WFD_COMMIT_ENTIRE_PORT, mPort);
+ eError = wfdGetError(mDevice);
+ if (WFD_ERROR_NONE != eError)
+ qFatal("Failed to commit port");
+
+ // Create native window
+ wfd_window_t* nativeWindow = (wfd_window_t*)malloc(sizeof(wfd_window_t));
+ if (nullptr == nativeWindow)
+ qFatal("Failed to allocate memory for native window");
+
+ nativeWindow->dev = mDevice;
+ nativeWindow->port = mPort;
+ nativeWindow->pipeline = pipeline;
+ nativeWindow->numBuffers = MAX_NUM_OF_WFD_BUFFERS;
+
+ for (int i = 0; i < MAX_NUM_OF_WFD_BUFFERS; i++) {
+ nativeWindow->buffers[i].image = wfdEglImages[i];
+ nativeWindow->buffers[i].source = source[i];
+ }
+
+ return (EGLNativeWindowType)nativeWindow;
+}
+
+QSurfaceFormat QEglFSOpenWFDIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const
+{
+ QSurfaceFormat format;
+ format.setRedBufferSize(8);
+ format.setGreenBufferSize(8);
+ format.setBlueBufferSize(8);
+ format.setAlphaBufferSize(8);
+ return format;
+}
+
+void QEglFSOpenWFDIntegration::destroyNativeWindow(EGLNativeWindowType window)
+{
+ free((void*)window);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.h
new file mode 100644
index 0000000000..189ddd4d7a
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins 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 QEGLFSOPENWFDINTEGRATION_H
+#define QEGLFSOPENWFDINTEGRATION_H
+
+#include "private/qeglfsdeviceintegration_p.h"
+#define WFD_WFDEXT_PROTOTYPES
+#include "wfd.h"
+#include "wfdext2.h"
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSOpenWFDIntegration : public QEglFSDeviceIntegration
+{
+public:
+ void platformInit() override;
+ QSize screenSize() const override;
+ EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) override;
+ void destroyNativeWindow(EGLNativeWindowType window) override;
+ EGLNativeDisplayType platformDisplay() const override;
+ virtual QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const;
+
+private:
+ QSize mScreenSize;
+ EGLNativeDisplayType mNativeDisplay;
+ WFDDevice mDevice;
+ WFDPort mPort;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdmain.cpp
new file mode 100644
index 0000000000..1d6132b55e
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdmain.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins 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$
+**
+****************************************************************************/
+
+#include "private/qeglfsdeviceintegration_p.h"
+#include "qeglfsopenwfdintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSOpenWFDIntegrationPlugin : public QEglFSDeviceIntegrationPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_openwfd.json")
+
+public:
+ QEglFSDeviceIntegration *create() override {
+ return new QEglFSOpenWFDIntegration;
+ }
+};
+
+QT_END_NAMESPACE
+
+#include "qeglfsopenwfdmain.moc"
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/eglfs_rcar.json b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/eglfs_rcar.json
new file mode 100644
index 0000000000..77b3083eef
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/eglfs_rcar.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "eglfs_rcar" ]
+}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/eglfs_rcar.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/eglfs_rcar.pro
new file mode 100644
index 0000000000..04236449a0
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/eglfs_rcar.pro
@@ -0,0 +1,19 @@
+TARGET = qeglfs-rcar-integration
+
+QT += core-private gui-private eglfsdeviceintegration-private
+
+INCLUDEPATH += $$PWD/../../api
+CONFIG += egl
+DEFINES += LINUX=1 EGL_API_FB=1
+QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
+
+SOURCES += $$PWD/qeglfsrcarmain.cpp \
+ $$PWD/qeglfsrcarintegration.cpp
+
+HEADERS += $$PWD/qeglfsrcarintegration.h
+
+OTHER_FILES += $$PWD/eglfs_rcar.json
+
+PLUGIN_TYPE = egldeviceintegrations
+PLUGIN_CLASS_NAME = QEglFSRcarIntegrationPlugin
+load(qt_plugin)
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarintegration.cpp
new file mode 100644
index 0000000000..98cf1d3bfb
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarintegration.cpp
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins 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$
+**
+****************************************************************************/
+
+#include <QDebug>
+#include <QtEglSupport/private/qeglconvenience_p.h>
+#include <EGL/egl.h>
+#include "INTEGRITY.h"
+#include "qeglfsrcarintegration.h"
+
+#define RCAR_DEFAULT_DISPLAY 1
+#define RCAR_DEFAULT_WM_LAYER 2
+
+extern "C" unsigned long PVRGrfxServerInit(void);
+
+QT_BEGIN_NAMESPACE
+
+void QEglFSRcarIntegration::platformInit()
+{
+ QEglFSDeviceIntegration::platformInit();
+
+ PVRGrfxServerInit();
+
+ mScreenSize = q_screenSizeFromFb(0);
+ mNativeDisplay = (NativeDisplayType)EGL_DEFAULT_DISPLAY;
+}
+
+QSize QEglFSRcarIntegration::screenSize() const
+{
+ return mScreenSize;
+}
+
+EGLNativeDisplayType QEglFSRcarIntegration::platformDisplay() const
+{
+ return mNativeDisplay;
+}
+
+static r_wm_WinColorFmt_t getWMColorFormat(const QSurfaceFormat &format)
+{
+ const int a = format.alphaBufferSize();
+ const int r = format.redBufferSize();
+ const int g = format.greenBufferSize();
+ const int b = format.blueBufferSize();
+
+ switch (r) {
+ case 4:
+ if (g == 4 && b == 4 && a == 4)
+ return R_WM_COLORFMT_ARGB4444;
+ break;
+ case 5:
+ if (g == 6 && b == 5 && a == 0)
+ return R_WM_COLORFMT_RGB565;
+ else if (g == 5 && b == 5 && a == 1)
+ return R_WM_COLORFMT_ARGB1555;
+ break;
+ case 8:
+ if (g == 8 && b == 8 && a == 0)
+ return R_WM_COLORFMT_RGB0888;
+ else if (g == 8 && b == 8 && a == 8)
+ return R_WM_COLORFMT_ARGB8888;
+ break;
+ }
+
+ qFatal("Unsupported color format: R:%d G:%d B:%d A:%d", r, g, b, a);
+ return R_WM_COLORFMT_LAST;
+}
+
+EGLNativeWindowType QEglFSRcarIntegration::createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format)
+{
+ bool ok;
+
+ mNativeDisplayID = qEnvironmentVariableIntValue("QT_QPA_WM_DISP_ID", &ok);
+ if (!ok)
+ mNativeDisplayID = RCAR_DEFAULT_DISPLAY;
+
+ r_wm_Error_t wm_err = R_WM_DevInit(mNativeDisplayID);
+ if (wm_err != R_WM_ERR_OK)
+ qFatal("Failed to init WM Dev: %d, error: %d", mNativeDisplayID, wm_err);
+
+ mNativeWindow = (EGLNativeWindowTypeREL*)malloc(sizeof(EGLNativeWindowTypeREL));
+ memset(mNativeWindow, 0, sizeof(EGLNativeWindowTypeREL));
+
+ mNativeWindow->ColorFmt = getWMColorFormat(format);
+ mNativeWindow->PosX = 0;
+ mNativeWindow->PosY = 0;
+ mNativeWindow->PosZ = qEnvironmentVariableIntValue("QT_QPA_WM_LAYER", &ok);
+ if (!ok)
+ mNativeWindow->PosZ = RCAR_DEFAULT_WM_LAYER;
+ mNativeWindow->Pitch = size.width();
+ mNativeWindow->Width = size.width();
+ mNativeWindow->Height = size.height();
+ mNativeWindow->Alpha = format.alphaBufferSize();
+
+ if (format.swapBehavior() == QSurfaceFormat::DefaultSwapBehavior)
+ mNativeWindow->Surface.BufNum = 3;
+ else
+ mNativeWindow->Surface.BufNum = format.swapBehavior();
+
+ mNativeWindow->Surface.Type = R_WM_SURFACE_FB;
+ mNativeWindow->Surface.BufMode = R_WM_WINBUF_ALLOC_INTERNAL;
+
+ wm_err = R_WM_WindowCreate(mNativeDisplayID, mNativeWindow);
+ if (wm_err != R_WM_ERR_OK)
+ qFatal("Failed to create window layer: %d", wm_err);
+ wm_err = R_WM_DevEventRegister(mNativeDisplayID, R_WM_EVENT_VBLANK, 0);
+ if (wm_err != R_WM_ERR_OK)
+ qFatal("Failed to Register vsync event: %d", wm_err);
+ wm_err = R_WM_WindowEnable(mNativeDisplayID, mNativeWindow);
+ if (wm_err != R_WM_ERR_OK)
+ qFatal("Failed to Enable window surface: %d", wm_err);
+
+ return static_cast<EGLNativeWindowType>(mNativeWindow);
+}
+
+void QEglFSRcarIntegration::destroyNativeWindow(EGLNativeWindowType window)
+{
+ R_WM_WindowDisable(mNativeDisplayID, mNativeWindow);
+ usleep(100000); //Needed to allow Window Manager make the window transparent
+ R_WM_WindowDelete(mNativeDisplayID, mNativeWindow);
+ R_WM_DevDeinit(mNativeDisplayID);
+ free(mNativeWindow);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarintegration.h
new file mode 100644
index 0000000000..08911594f9
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarintegration.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins 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 QEGLFSVIVINTEGRATION_H
+#define QEGLFSVIVINTEGRATION_H
+
+#include "private/qeglfsdeviceintegration_p.h"
+#include "EGL/eglext_REL.h"
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSRcarIntegration : public QEglFSDeviceIntegration
+{
+public:
+ void platformInit() override;
+ QSize screenSize() const override;
+ EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) override;
+ void destroyNativeWindow(EGLNativeWindowType window) override;
+ EGLNativeDisplayType platformDisplay() const override;
+
+private:
+ QSize mScreenSize;
+ EGLNativeDisplayType mNativeDisplay;
+ EGLNativeWindowTypeREL *mNativeWindow;
+ int mNativeDisplayID;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarmain.cpp
new file mode 100644
index 0000000000..6cf3e1387d
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarmain.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins 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$
+**
+****************************************************************************/
+
+#include "INTEGRITY.h"
+#include "private/qeglfsdeviceintegration_p.h"
+#include "qeglfsrcarintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSRcarIntegrationPlugin : public QEglFSDeviceIntegrationPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_rcar.json")
+
+public:
+ QEglFSDeviceIntegration *create() override { return new QEglFSRcarIntegration; }
+};
+
+QT_END_NAMESPACE
+
+#include "qeglfsrcarmain.moc"
diff --git a/src/plugins/platforms/integrity/integrity.pro b/src/plugins/platforms/integrity/integrity.pro
index 0fb256793d..54438707eb 100644
--- a/src/plugins/platforms/integrity/integrity.pro
+++ b/src/plugins/platforms/integrity/integrity.pro
@@ -8,13 +8,18 @@ QT += \
SOURCES = \
main.cpp \
qintegrityfbintegration.cpp \
- qintegrityfbscreen.cpp \
- qintegrityhidmanager.cpp
+ qintegrityfbscreen.cpp
HEADERS = \
qintegrityfbintegration.h \
- qintegrityfbscreen.h \
- qintegrityhidmanager.h
+ qintegrityfbscreen.h
+
+qtConfig(integrityhid) {
+ SOURCES += \
+ qintegrityhidmanager.cpp
+ HEADERS += \
+ qintegrityhidmanager.h
+}
OTHER_FILES += integrity.json
diff --git a/src/plugins/platforms/ios/qiosapplicationstate.h b/src/plugins/platforms/ios/qiosapplicationstate.h
index 1c77b26da1..a68147a72a 100644
--- a/src/plugins/platforms/ios/qiosapplicationstate.h
+++ b/src/plugins/platforms/ios/qiosapplicationstate.h
@@ -40,20 +40,24 @@
#ifndef QIOSAPPLICATIONSTATE_H
#define QIOSAPPLICATIONSTATE_H
-#include <QtCore/qglobal.h>
-#include <QtCore/qvector.h>
+#include <QtCore/qobject.h>
-Q_FORWARD_DECLARE_OBJC_CLASS(NSObject);
+#include <UIKit/UIApplication.h>
QT_BEGIN_NAMESPACE
-class QIOSApplicationState
+class QIOSApplicationState : public QObject
{
+ Q_OBJECT
public:
QIOSApplicationState();
- ~QIOSApplicationState();
-private:
- QVector<NSObject*> m_observers;
+
+ static void handleApplicationStateChanged(UIApplicationState state, const QString &reason);
+ static Qt::ApplicationState toQtApplicationState(UIApplicationState state);
+
+Q_SIGNALS:
+ void applicationStateWillChange(Qt::ApplicationState);
+ void applicationStateDidChange(Qt::ApplicationState);
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosapplicationstate.mm b/src/plugins/platforms/ios/qiosapplicationstate.mm
index 13e7e1150f..3407aebf8f 100644
--- a/src/plugins/platforms/ios/qiosapplicationstate.mm
+++ b/src/plugins/platforms/ios/qiosapplicationstate.mm
@@ -40,82 +40,77 @@
#include "qiosapplicationstate.h"
#include "qiosglobal.h"
+#include "qiosintegration.h"
#include <qpa/qwindowsysteminterface.h>
#include <QtCore/qcoreapplication.h>
#include <QtGui/private/qguiapplication_p.h>
-#import <UIKit/UIKit.h>
+QT_BEGIN_NAMESPACE
-static Qt::ApplicationState qtApplicationState(UIApplicationState uiApplicationState)
+static void qRegisterApplicationStateNotifications()
{
- switch (uiApplicationState) {
- case UIApplicationStateActive:
- // The application is visible in front, and receiving events
- return Qt::ApplicationActive;
- case UIApplicationStateInactive:
- // The app is running in the foreground but is not receiving events. This
- // typically happens while transitioning to/from active/background, like
- // upon app launch or when receiving incoming calls.
- return Qt::ApplicationInactive;
- case UIApplicationStateBackground:
- // Normally the app would enter this state briefly before it gets
- // suspeded (you have five seconds, according to Apple).
- // You can request more time and start a background task, which would
- // normally map closer to Qt::ApplicationHidden. But since we have no
- // API for doing that yet, we handle this state as "about to be suspended".
- // Note: A screen-shot for the SpringBoard will also be taken after this
- // call returns.
- return Qt::ApplicationSuspended;
+ NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
+ NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
+
+ // Map between notifications and corresponding application state. Note that
+ // there's no separate notification for moving to UIApplicationStateInactive,
+ // so we use UIApplicationWillResignActiveNotification as an intermediate.
+ static QMap<NSNotificationName, UIApplicationState> notifications {
+ { UIApplicationWillEnterForegroundNotification, UIApplicationStateInactive },
+ { UIApplicationDidBecomeActiveNotification, UIApplicationStateActive },
+ { UIApplicationWillResignActiveNotification, UIApplicationStateInactive },
+ { UIApplicationDidEnterBackgroundNotification, UIApplicationStateBackground },
+ };
+
+ for (auto i = notifications.constBegin(); i != notifications.constEnd(); ++i) {
+ [notificationCenter addObserverForName:i.key() object:nil queue:mainQueue
+ usingBlock:^void(NSNotification *notification) {
+ NSRange nameRange = NSMakeRange(2, notification.name.length - 14);
+ QString reason = QString::fromNSString([notification.name substringWithRange:nameRange]);
+ QIOSApplicationState::handleApplicationStateChanged(i.value(), reason);
+ }];
}
-}
-static void handleApplicationStateChanged(UIApplicationState uiApplicationState)
-{
- Qt::ApplicationState state = qtApplicationState(uiApplicationState);
- qCDebug(lcQpaApplication) << "moved to" << state;
- QWindowSystemInterface::handleApplicationStateChanged<QWindowSystemInterface::SynchronousDelivery>(state);
+ // Initialize correct startup state, which may not be the Qt default (inactive)
+ UIApplicationState startupState = [UIApplication sharedApplication].applicationState;
+ QIOSApplicationState::handleApplicationStateChanged(startupState, QLatin1String("Application loaded"));
}
-
-QT_BEGIN_NAMESPACE
+Q_CONSTRUCTOR_FUNCTION(qRegisterApplicationStateNotifications)
QIOSApplicationState::QIOSApplicationState()
{
- NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
-
- m_observers.push_back([notificationCenter addObserverForName:UIApplicationDidBecomeActiveNotification
- object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *) {
- handleApplicationStateChanged(UIApplicationStateActive);
- }
- ]);
-
- m_observers.push_back([notificationCenter addObserverForName:UIApplicationWillResignActiveNotification
- object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *) {
- // Note: UIApplication is still UIApplicationStateActive at this point,
- // but since there is no separate notification for the inactive state,
- // we report UIApplicationStateInactive now.
- handleApplicationStateChanged(UIApplicationStateInactive);
- }
- ]);
-
- m_observers.push_back([notificationCenter addObserverForName:UIApplicationDidEnterBackgroundNotification
- object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *) {
- handleApplicationStateChanged(UIApplicationStateBackground);
- }
- ]);
-
- // Initialize correct startup state, which may not be the Qt default (inactive)
UIApplicationState startupState = [UIApplication sharedApplication].applicationState;
- QGuiApplicationPrivate::applicationState = qtApplicationState(startupState);
+ QIOSApplicationState::handleApplicationStateChanged(startupState, QLatin1String("Application launched"));
}
-QIOSApplicationState::~QIOSApplicationState()
+void QIOSApplicationState::handleApplicationStateChanged(UIApplicationState uiState, const QString &reason)
{
- NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
- foreach (const NSObject* observer, m_observers)
- [notificationCenter removeObserver:observer];
+ Qt::ApplicationState state = toQtApplicationState(uiState);
+ qCDebug(lcQpaApplication) << qPrintable(reason)
+ << "- moving from" << QGuiApplication::applicationState() << "to" << state;
+
+ if (QIOSIntegration *integration = QIOSIntegration::instance()) {
+ emit integration->applicationState.applicationStateWillChange(state);
+ QWindowSystemInterface::handleApplicationStateChanged(state);
+ emit integration->applicationState.applicationStateDidChange(state);
+ qCDebug(lcQpaApplication) << "done moving to" << state;
+ } else {
+ qCDebug(lcQpaApplication) << "no platform integration yet, setting state directly";
+ QGuiApplicationPrivate::applicationState = state;
+ }
}
-QT_END_NAMESPACE
+Qt::ApplicationState QIOSApplicationState::toQtApplicationState(UIApplicationState state)
+{
+ switch (state) {
+ case UIApplicationStateActive: return Qt::ApplicationActive;
+ case UIApplicationStateInactive: return Qt::ApplicationInactive;
+ case UIApplicationStateBackground: return Qt::ApplicationSuspended;
+ }
+}
+#include "moc_qiosapplicationstate.cpp"
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h
index 7539e981c0..a2595877dc 100644
--- a/src/plugins/platforms/ios/qioscontext.h
+++ b/src/plugins/platforms/ios/qioscontext.h
@@ -87,6 +87,7 @@ private:
bool isComplete;
};
+ static bool verifyGraphicsHardwareAvailability();
static void deleteBuffers(const FramebufferObject &framebufferObject);
FramebufferObject &backingFramebufferObjectFor(QPlatformSurface *) const;
diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm
index 6a6cbb4324..03643c19a9 100644
--- a/src/plugins/platforms/ios/qioscontext.mm
+++ b/src/plugins/platforms/ios/qioscontext.mm
@@ -38,10 +38,13 @@
****************************************************************************/
#include "qioscontext.h"
+
+#include "qiosintegration.h"
#include "qioswindow.h"
#include <dlfcn.h>
+#include <QtGui/QGuiApplication>
#include <QtGui/QOpenGLContext>
#import <OpenGLES/EAGL.h>
@@ -136,6 +139,9 @@ bool QIOSContext::makeCurrent(QPlatformSurface *surface)
{
Q_ASSERT_IS_GL_SURFACE(surface);
+ if (!verifyGraphicsHardwareAvailability())
+ return false;
+
[EAGLContext setCurrentContext:m_eaglContext];
// For offscreen surfaces we don't prepare a default FBO
@@ -214,18 +220,12 @@ void QIOSContext::swapBuffers(QPlatformSurface *surface)
{
Q_ASSERT_IS_GL_SURFACE(surface);
+ if (!verifyGraphicsHardwareAvailability())
+ return;
+
if (surface->surface()->surfaceClass() == QSurface::Offscreen)
return; // Nothing to do
- // When using threaded rendering, the render-thread may not have picked up
- // yet on the fact that a window is no longer exposed, and will try to swap
- // a non-exposed window. This may in some cases result in crashes, e.g. when
- // iOS is suspending an application, so we have an extra guard here.
- if (!static_cast<QIOSWindow *>(surface)->isExposed()) {
- qCDebug(lcQpaGLContext, "Detected swapBuffers on a non-exposed window, skipping flush");
- return;
- }
-
FramebufferObject &framebufferObject = backingFramebufferObjectFor(surface);
Q_ASSERT_X(framebufferObject.isComplete, "QIOSContext", "swapBuffers on incomplete FBO");
@@ -287,6 +287,54 @@ bool QIOSContext::needsRenderbufferResize(QPlatformSurface *surface) const
return false;
}
+bool QIOSContext::verifyGraphicsHardwareAvailability()
+{
+ // Per the iOS OpenGL ES Programming Guide, background apps may not execute commands on the
+ // graphics hardware. Specifically: "In your app delegate’s applicationDidEnterBackground:
+ // method, your app may want to delete some of its OpenGL ES objects to make memory and
+ // resources available to the foreground app. Call the glFinish function to ensure that
+ // the resources are removed immediately. After your app exits its applicationDidEnterBackground:
+ // method, it must not make any new OpenGL ES calls. If it makes an OpenGL ES call, it is
+ // terminated by iOS.".
+ static bool applicationBackgrounded = QGuiApplication::applicationState() == Qt::ApplicationSuspended;
+
+ static dispatch_once_t onceToken = 0;
+ dispatch_once(&onceToken, ^{
+ QIOSApplicationState *applicationState = &QIOSIntegration::instance()->applicationState;
+ connect(applicationState, &QIOSApplicationState::applicationStateWillChange, [](Qt::ApplicationState state) {
+ if (applicationBackgrounded && state != Qt::ApplicationSuspended) {
+ qCDebug(lcQpaGLContext) << "app no longer backgrounded, rendering enabled";
+ applicationBackgrounded = false;
+ }
+ });
+ connect(applicationState, &QIOSApplicationState::applicationStateDidChange, [](Qt::ApplicationState state) {
+ if (state != Qt::ApplicationSuspended)
+ return;
+
+ qCDebug(lcQpaGLContext) << "app backgrounded, rendering disabled";
+ applicationBackgrounded = true;
+
+ // By the time we receive this signal the application has moved into
+ // Qt::ApplactionStateSuspended, and all windows have been obscured,
+ // which should stop all rendering. If there's still an active GL context,
+ // we follow Apple's advice and call glFinish before making it inactive.
+ if (QOpenGLContext *currentContext = QOpenGLContext::currentContext()) {
+ qCWarning(lcQpaGLContext) << "explicitly glFinishing and deactivating" << currentContext;
+ glFinish();
+ currentContext->doneCurrent();
+ }
+ });
+ });
+
+ if (applicationBackgrounded) {
+ static const char warning[] = "OpenGL ES calls are not allowed while an application is backgrounded";
+ Q_ASSERT_X(!applicationBackgrounded, "QIOSContext", warning);
+ qCWarning(lcQpaGLContext, warning);
+ }
+
+ return !applicationBackgrounded;
+}
+
void QIOSContext::windowDestroyed(QObject *object)
{
QIOSWindow *window = static_cast<QIOSWindow *>(object);
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm
index cf7680529a..de2c30cdfb 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.mm
+++ b/src/plugins/platforms/ios/qioseventdispatcher.mm
@@ -294,7 +294,7 @@ static bool rootLevelRunLoopIntegration()
{
[[NSNotificationCenter defaultCenter]
addObserver:self
- selector:@selector(applicationDidFinishLaunching)
+ selector:@selector(applicationDidFinishLaunching:)
name:UIApplicationDidFinishLaunchingNotification
object:nil];
@@ -320,8 +320,10 @@ static bool rootLevelRunLoopIntegration()
# error "Unknown processor family"
#endif
-+ (void)applicationDidFinishLaunching
++ (void)applicationDidFinishLaunching:(NSNotification *)notification
{
+ qCDebug(lcQpaApplication) << "Application launched with options" << notification.userInfo;
+
if (!isQtApplication())
return;
@@ -329,7 +331,7 @@ static bool rootLevelRunLoopIntegration()
// We schedule the main-redirection for the next run-loop pass, so that we
// can return from this function and let UIApplicationMain finish its job.
// This results in running Qt's application eventloop as a nested runloop.
- qEventDispatcherDebug() << "Scheduling main() on next run-loop pass";
+ qCDebug(lcQpaApplication) << "Scheduling main() on next run-loop pass";
CFRunLoopTimerRef userMainTimer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault,
CFAbsoluteTimeGetCurrent(), 0, 0, 0, ^(CFRunLoopTimerRef) { user_main_trampoline(); });
CFRunLoopAddTimer(CFRunLoopGetMain(), userMainTimer, kCFRunLoopCommonModes);
@@ -339,7 +341,7 @@ static bool rootLevelRunLoopIntegration()
switch (setjmp(processEventEnterJumpPoint)) {
case kJumpPointSetSuccessfully:
- qEventDispatcherDebug() << "Running main() on separate stack"; qIndent();
+ qCDebug(lcQpaApplication) << "Running main() on separate stack"; qIndent();
// Redirect the stack pointer to the start of the reserved stack. This ensures
// that when we longjmp out of the event dispatcher and continue execution, the
@@ -358,7 +360,7 @@ static bool rootLevelRunLoopIntegration()
case kJumpedFromEventDispatcherProcessEvents:
// We've returned from the longjmp in the event dispatcher,
// and the stack has been restored to its old self.
- qUnIndent(); qEventDispatcherDebug() << "Returned from processEvents";
+ qUnIndent(); qCDebug(lcQpaApplication) << "Returned from processEvents";
if (Q_UNLIKELY(debugStackUsage))
userMainStack.printUsage();
@@ -422,6 +424,8 @@ QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent)
, m_processEventLevel(0)
, m_runLoopExitObserver(this, &QIOSEventDispatcher::handleRunLoopExit, kCFRunLoopExit)
{
+ // We want all delivery of events from the system to be handled synchronously
+ QWindowSystemInterface::setSynchronousWindowSystemEvents(true);
}
bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index 237077400b..050c592aca 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -500,23 +500,25 @@ void QIOSInputContext::scrollToCursor()
QWindow *focusWindow = qApp->focusWindow();
QRect cursorRect = qApp->inputMethod()->cursorRectangle().translated(focusWindow->geometry().topLeft()).toRect();
- if (cursorRect.isNull()) {
- scroll(0);
- return;
- }
-
- // Add some padding so that the cusor does not end up directly above the keyboard
- static const int kCursorRectPadding = 20;
- cursorRect.adjust(0, -kCursorRectPadding, 0, kCursorRectPadding);
// We explicitly ask for the geometry of the screen instead of the availableGeometry,
- // as we hide the statusbar when scrolling the screen, so the available geometry will
+ // as we hide the status bar when scrolling the screen, so the available geometry will
// include the space taken by the status bar at the moment.
QRect screenGeometry = focusWindow->screen()->geometry();
+
+ if (!cursorRect.isNull()) {
+ // Add some padding so that the cursor does not end up directly above the keyboard
+ static const int kCursorRectPadding = 20;
+ cursorRect.adjust(0, -kCursorRectPadding, 0, kCursorRectPadding);
+
+ // Make sure the cursor rect is still within the screen geometry after padding
+ cursorRect &= screenGeometry;
+ }
+
QRect keyboardGeometry = QRectF::fromCGRect(m_keyboardState.keyboardEndRect).toRect();
QRect availableGeometry = (QRegion(screenGeometry) - keyboardGeometry).boundingRect();
- if (!availableGeometry.contains(cursorRect, true)) {
+ if (!cursorRect.isNull() && !availableGeometry.contains(cursorRect)) {
qImDebug() << "cursor rect" << cursorRect << "not fully within" << availableGeometry;
int scrollToCenter = -(availableGeometry.center() - cursorRect.center()).y();
int scrollToBottom = focusWindow->screen()->geometry().bottom() - availableGeometry.bottom();
@@ -528,6 +530,8 @@ void QIOSInputContext::scrollToCursor()
void QIOSInputContext::scroll(int y)
{
+ Q_ASSERT(y >= 0);
+
UIView *rootView = scrollableRootView();
if (!rootView)
return;
diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h
index 20eb210cd5..6be8855020 100644
--- a/src/plugins/platforms/ios/qiosintegration.h
+++ b/src/plugins/platforms/ios/qiosintegration.h
@@ -104,6 +104,8 @@ public:
QFactoryLoader *optionalPlugins() { return m_optionalPlugins; }
+ QIOSApplicationState applicationState;
+
private:
QPlatformFontDatabase *m_fontDatabase;
#ifndef Q_OS_TVOS
@@ -111,7 +113,6 @@ private:
#endif
QPlatformInputContext *m_inputContext;
QTouchDevice *m_touchDevice;
- QIOSApplicationState m_applicationState;
QIOSServices *m_platformServices;
mutable QPlatformAccessibility *m_accessibility;
QFactoryLoader *m_optionalPlugins;
diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h
index 329fb1f9e2..d5a253461d 100644
--- a/src/plugins/platforms/ios/qiosscreen.h
+++ b/src/plugins/platforms/ios/qiosscreen.h
@@ -46,6 +46,10 @@
@class QIOSOrientationListener;
+@interface QUIWindow : UIWindow
+@property (nonatomic, readonly) BOOL sendingEvent;
+@end
+
QT_BEGIN_NAMESPACE
class QIOSScreen : public QObject, public QPlatformScreen
@@ -56,6 +60,8 @@ public:
QIOSScreen(UIScreen *screen);
~QIOSScreen();
+ QString name() const override;
+
QRect geometry() const override;
QRect availableGeometry() const override;
int depth() const override;
@@ -63,6 +69,7 @@ public:
QSizeF physicalSize() const override;
QDpi logicalDpi() const override;
qreal devicePixelRatio() const override;
+ qreal refreshRate() const override;
Qt::ScreenOrientation nativeOrientation() const override;
Qt::ScreenOrientation orientation() const override;
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index e8854a4c4b..c394592d76 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -174,18 +174,53 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
@end
+@interface UIScreen (Compatibility)
+@property (nonatomic, readonly) CGRect qt_applicationFrame;
+@end
+
+@implementation UIScreen (Compatibility)
+- (CGRect)qt_applicationFrame
+{
+#ifdef Q_OS_IOS
+ return self.applicationFrame;
+#else
+ return self.bounds;
+#endif
+}
+@end
+
+// -------------------------------------------------------------------------
+
+@implementation QUIWindow
+
+- (id)initWithFrame:(CGRect)frame
+{
+ if ((self = [super initWithFrame:frame]))
+ self->_sendingEvent = NO;
+
+ return self;
+}
+
+- (void)sendEvent:(UIEvent *)event
+{
+ QScopedValueRollback<BOOL> sendingEvent(self->_sendingEvent, YES);
+ [super sendEvent:event];
+}
+
+@end
+
// -------------------------------------------------------------------------
QT_BEGIN_NAMESPACE
/*!
Returns the model identifier of the device.
-
- When running under the simulator, the identifier will not
- match the simulated device, but will be x86_64 or i386.
*/
static QString deviceModelIdentifier()
{
+#if TARGET_OS_SIMULATOR
+ return QString::fromLocal8Bit(qgetenv("SIMULATOR_MODEL_IDENTIFIER"));
+#else
static const char key[] = "hw.machine";
size_t size;
@@ -195,6 +230,7 @@ static QString deviceModelIdentifier()
sysctlbyname(key, &value, &size, NULL, 0);
return QString::fromLatin1(value);
+#endif
}
QIOSScreen::QIOSScreen(UIScreen *screen)
@@ -203,25 +239,30 @@ QIOSScreen::QIOSScreen(UIScreen *screen)
, m_uiWindow(0)
, m_orientationListener(0)
{
- if (screen == [UIScreen mainScreen]) {
- QString deviceIdentifier = deviceModelIdentifier();
+ QString deviceIdentifier = deviceModelIdentifier();
+ if (screen == [UIScreen mainScreen] && !deviceIdentifier.startsWith("AppleTV")) {
// Based on https://en.wikipedia.org/wiki/List_of_iOS_devices#Display
// iPhone (1st gen), 3G, 3GS, and iPod Touch (1st–3rd gen) are 18-bit devices
- if (deviceIdentifier.contains(QRegularExpression("^(iPhone1,[12]|iPhone2,1|iPod[1-3],1)$")))
- m_depth = 18;
- else
- m_depth = 24;
+ static QRegularExpression lowBitDepthDevices("^(iPhone1,[12]|iPhone2,1|iPod[1-3],1)$");
+ m_depth = deviceIdentifier.contains(lowBitDepthDevices) ? 18 : 24;
+
+ static QRegularExpression iPhoneXModels("^iPhone(10,[36])$");
+ static QRegularExpression iPhonePlusModels("^iPhone(7,1|8,2|9,[24]|10,[25])$");
+ static QRegularExpression iPadMiniModels("^iPad(2,[567]|4,[4-9]|5,[12])$");
- if (deviceIdentifier.contains(QRegularExpression("^iPhone(7,1|8,2|9,2|9,4)$"))) {
- // iPhone Plus models
+ if (deviceIdentifier.contains(iPhoneXModels)) {
+ m_physicalDpi = 458;
+ } else if (deviceIdentifier.contains(iPhonePlusModels)) {
m_physicalDpi = 401;
- } else if (deviceIdentifier.contains(QRegularExpression("^iPad(1,1|2,[1-4]|3,[1-6]|4,[1-3]|5,[3-4]|6,[7-8])$"))) {
- // All iPads except the iPad Mini series
- m_physicalDpi = 132 * devicePixelRatio();
+ } else if (deviceIdentifier.startsWith("iPad")) {
+ if (deviceIdentifier.contains(iPadMiniModels))
+ m_physicalDpi = 163 * devicePixelRatio();
+ else
+ m_physicalDpi = 132 * devicePixelRatio();
} else {
- // All non-Plus iPhones, and iPad Minis
+ // All normal iPhones, and iPods
m_physicalDpi = 163 * devicePixelRatio();
}
} else {
@@ -239,7 +280,7 @@ QIOSScreen::QIOSScreen(UIScreen *screen)
if (!m_uiWindow) {
// Create a window and associated view-controller that we can use
- m_uiWindow = [[UIWindow alloc] initWithFrame:[m_uiScreen bounds]];
+ m_uiWindow = [[QUIWindow alloc] initWithFrame:[m_uiScreen bounds]];
m_uiWindow.rootViewController = [[[QIOSViewController alloc] initWithQIOSScreen:this] autorelease];
}
@@ -258,17 +299,31 @@ QIOSScreen::~QIOSScreen()
[m_uiWindow release];
}
+QString QIOSScreen::name() const
+{
+ if (m_uiScreen == [UIScreen mainScreen]) {
+ return QString::fromNSString([UIDevice currentDevice].model)
+ + QLatin1String(" built-in display");
+ } else {
+ return QLatin1String("External display");
+ }
+}
+
void QIOSScreen::updateProperties()
{
QRect previousGeometry = m_geometry;
QRect previousAvailableGeometry = m_availableGeometry;
m_geometry = QRectF::fromCGRect(m_uiScreen.bounds).toRect();
-#ifdef Q_OS_TVOS
- m_availableGeometry = m_geometry;
-#else
- m_availableGeometry = QRectF::fromCGRect(m_uiScreen.applicationFrame).toRect();
-#endif
+
+ // The application frame doesn't take safe area insets into account, and
+ // the safe area insets are not available before the UIWindow is shown,
+ // and do not take split-view constraints into account, so we have to
+ // combine the two to get the correct available geometry.
+ QRect applicationFrame = QRectF::fromCGRect(m_uiScreen.qt_applicationFrame).toRect();
+ UIEdgeInsets safeAreaInsets = m_uiWindow.qt_safeAreaInsets;
+ m_availableGeometry = m_geometry.adjusted(safeAreaInsets.left, safeAreaInsets.top,
+ -safeAreaInsets.right, -safeAreaInsets.bottom).intersected(applicationFrame);
#ifndef Q_OS_TVOS
if (m_uiScreen == [UIScreen mainScreen]) {
@@ -390,6 +445,16 @@ qreal QIOSScreen::devicePixelRatio() const
return [m_uiScreen scale];
}
+qreal QIOSScreen::refreshRate() const
+{
+#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, 100300, 110000, __WATCHOS_NA)
+ if (__builtin_available(iOS 10.3, tvOS 11, *))
+ return m_uiScreen.maximumFramesPerSecond;
+#endif
+
+ return 60.0;
+}
+
Qt::ScreenOrientation QIOSScreen::nativeOrientation() const
{
CGRect nativeBounds =
diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm
index 7d48a012dd..b029c49a67 100644
--- a/src/plugins/platforms/ios/qiostextresponder.mm
+++ b/src/plugins/platforms/ios/qiostextresponder.mm
@@ -377,7 +377,6 @@
QScopedValueRollback<BOOL> rollback(m_inSendEventToFocusObject, true);
QWindowSystemInterface::handleKeyEvent(qApp->focusWindow(), QEvent::KeyPress, key, modifiers);
QWindowSystemInterface::handleKeyEvent(qApp->focusWindow(), QEvent::KeyRelease, key, modifiers);
- QWindowSystemInterface::flushWindowSystemEvents();
}
#ifndef QT_NO_SHORTCUT
diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm
index a7f1254064..a7663b9e94 100644
--- a/src/plugins/platforms/ios/qiosviewcontroller.mm
+++ b/src/plugins/platforms/ios/qiosviewcontroller.mm
@@ -156,6 +156,26 @@
- (void)layoutSubviews
{
+ if (QGuiApplication::applicationState() == Qt::ApplicationSuspended) {
+ // Despite the OpenGL ES Programming Guide telling us to avoid all
+ // use of OpenGL while in the background, iOS will perform its view
+ // snapshotting for the app switcher after the application has been
+ // backgrounded; once for each orientation. Presumably the expectation
+ // is that no rendering needs to be done to provide an alternate
+ // orientation snapshot, just relayouting of views. But in our case,
+ // or any non-stretchable content case such as a OpenGL based game,
+ // this is not true. Instead of continuing layout, which will send
+ // potentially expensive geometry changes (with isExposed false,
+ // since we're in the background), we short-circuit the snapshotting
+ // here. iOS will still use the latest rendered frame to create the
+ // application switcher thumbnail, but it will be based on the last
+ // active orientation of the application.
+ QIOSScreen *screen = self.qtViewController->m_screen;
+ qCDebug(lcQpaWindow) << "ignoring layout of subviews while suspended,"
+ << "likely system snapshot of" << screen->screen()->primaryOrientation();
+ return;
+ }
+
for (int i = int(self.subviews.count) - 1; i >= 0; --i) {
UIView *view = static_cast<UIView *>([self.subviews objectAtIndex:i]);
if (![view isKindOfClass:[QUIView class]])
diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h
index 1342d66201..d5af31044d 100644
--- a/src/plugins/platforms/ios/qioswindow.h
+++ b/src/plugins/platforms/ios/qioswindow.h
@@ -71,6 +71,8 @@ public:
bool isExposed() const override;
void propagateSizeHints() override {}
+ QMargins safeAreaMargins() const override;
+
void raise() override{ raiseOrLower(true); }
void lower() override { raiseOrLower(false); }
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index bcec9899f7..38136c05db 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -223,9 +223,16 @@ void QIOSWindow::applyGeometry(const QRect &rect)
[m_view layoutIfNeeded];
}
+QMargins QIOSWindow::safeAreaMargins() const
+{
+ UIEdgeInsets safeAreaInsets = m_view.qt_safeAreaInsets;
+ return QMargins(safeAreaInsets.left, safeAreaInsets.top,
+ safeAreaInsets.right, safeAreaInsets.bottom);
+}
+
bool QIOSWindow::isExposed() const
{
- return qApp->applicationState() >= Qt::ApplicationActive
+ return qApp->applicationState() != Qt::ApplicationSuspended
&& window()->isVisible() && !window()->geometry().isEmpty();
}
diff --git a/src/plugins/platforms/ios/quiview.h b/src/plugins/platforms/ios/quiview.h
index 2224ee336a..3e3c579075 100644
--- a/src/plugins/platforms/ios/quiview.h
+++ b/src/plugins/platforms/ios/quiview.h
@@ -78,5 +78,6 @@ QT_END_NAMESPACE
- (QWindow *)qwindow;
- (UIViewController *)viewController;
- (QIOSViewController*)qtViewController;
+@property (nonatomic, readonly) UIEdgeInsets qt_safeAreaInsets;
@end
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm
index 406bfcf5b3..dda8ee5b53 100644
--- a/src/plugins/platforms/ios/quiview.mm
+++ b/src/plugins/platforms/ios/quiview.mm
@@ -43,6 +43,7 @@
#include "qiosintegration.h"
#include "qiosviewcontroller.h"
#include "qiostextresponder.h"
+#include "qiosscreen.h"
#include "qioswindow.h"
#ifndef Q_OS_TVOS
#include "qiosmenu.h"
@@ -56,6 +57,24 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
@implementation QUIView
++ (void)load
+{
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::IOS, 11)) {
+ // iOS 11 handles this though [UIView safeAreaInsetsDidChange], but there's no signal for
+ // the corresponding top and bottom layout guides that we use on earlier versions. Note
+ // that we use the _will_ change version of the notification, because we want to react
+ // to the change as early was possible. But since the top and bottom layout guides have
+ // not been updated at this point we use asynchronous delivery of the event, so that the
+ // event is processed by QtGui just after iOS has updated the layout margins.
+ [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillChangeStatusBarFrameNotification
+ object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *) {
+ for (QWindow *window : QGuiApplication::allWindows())
+ QWindowSystemInterface::handleSafeAreaMarginsChanged<QWindowSystemInterface::AsynchronousDelivery>(window);
+ }
+ ];
+ }
+}
+
+ (Class)layerClass
{
return [CAEAGLLayer class];
@@ -100,6 +119,22 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
self.layer.borderColor = colorWithBrightness(1.0);
self.layer.borderWidth = 1.0;
}
+
+#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, 110000, 110000, __WATCHOS_NA)
+ if (qEnvironmentVariableIsSet("QT_IOS_DEBUG_WINDOW_SAFE_AREAS")) {
+ if (__builtin_available(iOS 11, tvOS 11, *)) {
+ UIView *safeAreaOverlay = [[UIView alloc] initWithFrame:CGRectZero];
+ [safeAreaOverlay setBackgroundColor:[UIColor colorWithRed:0.3 green:0.7 blue:0.9 alpha:0.3]];
+ [self addSubview:safeAreaOverlay];
+
+ safeAreaOverlay.translatesAutoresizingMaskIntoConstraints = NO;
+ [safeAreaOverlay.topAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.topAnchor].active = YES;
+ [safeAreaOverlay.leftAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.leftAnchor].active = YES;
+ [safeAreaOverlay.rightAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.rightAnchor].active = YES;
+ [safeAreaOverlay.bottomAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.bottomAnchor].active = YES;
+ }
+ }
+#endif
}
return self;
@@ -163,7 +198,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
QRect lastReportedGeometry = qt_window_private(window)->geometry;
QRect currentGeometry = QRectF::fromCGRect(self.frame).toRect();
qCDebug(lcQpaWindow) << m_qioswindow->window() << "new geometry is" << currentGeometry;
- QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(window, currentGeometry);
+ QWindowSystemInterface::handleGeometryChange(window, currentGeometry);
if (currentGeometry.size() != lastReportedGeometry.size()) {
// Trigger expose event on resize
@@ -196,7 +231,12 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
}
qCDebug(lcQpaWindow) << m_qioswindow->window() << region << "isExposed" << m_qioswindow->isExposed();
- QWindowSystemInterface::handleExposeEvent<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window(), region);
+ QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region);
+}
+
+- (void)safeAreaInsetsDidChange
+{
+ QWindowSystemInterface::handleSafeAreaMarginsChanged(m_qioswindow->window());
}
// -------------------------------------------------------------------------
@@ -227,7 +267,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
}
if (qGuiApp->focusWindow() != m_qioswindow->window())
- QWindowSystemInterface::handleWindowActivated<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window());
+ QWindowSystemInterface::handleWindowActivated(m_qioswindow->window());
else
qImDebug() << m_qioswindow->window() << "already active, not sending window activation";
@@ -265,7 +305,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
UIResponder *newResponder = FirstResponderCandidate::currentCandidate();
if ([self responderShouldTriggerWindowDeactivation:newResponder])
- QWindowSystemInterface::handleWindowActivated<QWindowSystemInterface::SynchronousDelivery>(0);
+ QWindowSystemInterface::handleWindowActivated(0);
return YES;
}
@@ -384,8 +424,24 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
}
}
}
- if (!m_activeTouches.isEmpty())
- QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values());
+ if (m_activeTouches.isEmpty())
+ return;
+ QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values());
+ if (!static_cast<QUIWindow *>(self.window).sendingEvent) {
+ // The event is likely delivered as part of delayed touch delivery, via
+ // _UIGestureEnvironmentSortAndSendDelayedTouches, due to one of the two
+ // _UISystemGestureGateGestureRecognizer instances on the top level window
+ // having its delaysTouchesBegan set to YES. During this delivery, it's not
+ // safe to spin up a recursive event loop, as our calling function is not
+ // reentrant, so any gestures used by the recursive code, e.g. a native
+ // alert dialog, will fail to recognize. To be on the safe side, we deliver
+ // the event asynchronously.
+ QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::AsynchronousDelivery>(
+ m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values());
+ } else {
+ QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(
+ m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values());
+ }
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
@@ -483,7 +539,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
NSTimeInterval timestamp = event ? event.timestamp : [[NSProcessInfo processInfo] systemUptime];
QIOSIntegration *iosIntegration = static_cast<QIOSIntegration *>(QGuiApplicationPrivate::platformIntegration());
- QWindowSystemInterface::handleTouchCancelEvent<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window(), ulong(timestamp * 1000), iosIntegration->touchDevice());
+ QWindowSystemInterface::handleTouchCancelEvent(m_qioswindow->window(), ulong(timestamp * 1000), iosIntegration->touchDevice());
}
- (int)mapPressTypeToKey:(UIPress*)press
@@ -511,7 +567,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
int key = [self mapPressTypeToKey:press];
if (key == Qt::Key_unknown)
continue;
- if (QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window(), type, key, Qt::NoModifier))
+ if (QWindowSystemInterface::handleKeyEvent(m_qioswindow->window(), type, key, Qt::NoModifier))
handled = true;
}
@@ -590,6 +646,22 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
return nil;
}
+- (UIEdgeInsets)qt_safeAreaInsets
+{
+#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, 110000, 110000, __WATCHOS_NA)
+ if (__builtin_available(iOS 11, tvOS 11, *))
+ return self.safeAreaInsets;
+#endif
+
+ // Fallback for iOS < 11
+ UIEdgeInsets safeAreaInsets = UIEdgeInsetsZero;
+ CGPoint topInset = [self convertPoint:CGPointMake(0, self.viewController.topLayoutGuide.length) fromView:nil];
+ CGPoint bottomInset = [self convertPoint:CGPointMake(0, self.viewController.bottomLayoutGuide.length) fromView:nil];
+ safeAreaInsets.top = topInset.y;
+ safeAreaInsets.bottom = bottomInset.y;
+ return safeAreaInsets;
+}
+
@end
#ifndef QT_NO_ACCESSIBILITY
diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro
index 34be6d582e..15d33200e5 100644
--- a/src/plugins/platforms/qnx/qnx.pro
+++ b/src/plugins/platforms/qnx/qnx.pro
@@ -81,26 +81,26 @@ qtConfig(opengles2) {
QMAKE_USE += opengl_es2 egl
}
-CONFIG(qqnx_pps) {
- DEFINES += QQNX_PPS
-
- SOURCES += qqnxclipboard.cpp \
- qqnxbuttoneventnotifier.cpp \
+qtConfig(qqnx_pps) {
+ SOURCES += qqnxbuttoneventnotifier.cpp \
qqnxnavigatorpps.cpp \
qqnxnavigatoreventnotifier.cpp \
qqnxvirtualkeyboardpps.cpp
- HEADERS += qqnxclipboard.h \
- qqnxbuttoneventnotifier.h \
+ HEADERS += qqnxbuttoneventnotifier.h \
qqnxnavigatorpps.h \
qqnxnavigatoreventnotifier.h \
qqnxvirtualkeyboardpps.h
QMAKE_USE += pps
- !contains(DEFINES, QT_NO_CLIPBOARD): LIBS += -lclipboard
- CONFIG(qqnx_imf) {
- DEFINES += QQNX_IMF
+ qtConfig(clipboard) {
+ SOURCES += qqnxclipboard.cpp
+ HEADERS += qqnxclipboard.h
+ LIBS += -lclipboard
+ }
+
+ qtConfig(qqnx_imf) {
HEADERS += qqnxinputcontext_imf.h
SOURCES += qqnxinputcontext_imf.cpp
} else {
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index eee0581709..072510e052 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -56,17 +56,16 @@
#include "qqnxeglwindow.h"
#endif
-#if defined(QQNX_PPS)
+#if QT_CONFIG(qqnx_pps)
#include "qqnxnavigatorpps.h"
#include "qqnxnavigatoreventnotifier.h"
#include "qqnxvirtualkeyboardpps.h"
#endif
-#if defined(QQNX_PPS)
+#if QT_CONFIG(qqnx_pps)
# include "qqnxbuttoneventnotifier.h"
# include "qqnxclipboard.h"
-
-# if defined(QQNX_IMF)
+# if QT_CONFIG(qqnx_imf)
# include "qqnxinputcontext_imf.h"
# else
# include "qqnxinputcontext_noimf.h"
@@ -126,7 +125,7 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
, m_screenEventThread(0)
, m_navigatorEventHandler(new QQnxNavigatorEventHandler())
, m_virtualKeyboard(0)
-#if defined(QQNX_PPS)
+#if QT_CONFIG(qqnx_pps)
, m_navigatorEventNotifier(0)
, m_inputContext(0)
, m_buttonsNotifier(new QQnxButtonEventNotifier())
@@ -150,7 +149,7 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
Q_SCREEN_CRITICALERROR(screen_create_context(&ms_screenContext, SCREEN_APPLICATION_CONTEXT),
"Failed to create screen context");
-#if defined(QQNX_PPS)
+#if QT_CONFIG(qqnx_pps)
// Create/start navigator event notifier
m_navigatorEventNotifier = new QQnxNavigatorEventNotifier(m_navigatorEventHandler);
@@ -168,7 +167,7 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
m_screenEventThread = new QQnxScreenEventThread(ms_screenContext, m_screenEventHandler);
m_screenEventThread->start();
-#if defined(QQNX_PPS)
+#if QT_CONFIG(qqnx_pps)
// Create/start the keyboard class.
m_virtualKeyboard = new QQnxVirtualKeyboardPps();
@@ -177,7 +176,7 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
QMetaObject::invokeMethod(m_virtualKeyboard, "start", Qt::QueuedConnection);
#endif
-#if defined(QQNX_PPS)
+#if QT_CONFIG(qqnx_pps)
m_navigator = new QQnxNavigatorPps();
#endif
@@ -192,16 +191,16 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
QObject::connect(m_virtualKeyboard, SIGNAL(heightChanged(int)),
primaryDisplay(), SLOT(keyboardHeightChanged(int)));
-#if defined(QQNX_PPS)
+#if QT_CONFIG(qqnx_pps)
// Set up the input context
m_inputContext = new QQnxInputContext(this, *m_virtualKeyboard);
-#if defined(QQNX_IMF)
+#if QT_CONFIG(qqnx_imf)
m_screenEventHandler->addScreenEventFilter(m_inputContext);
#endif
#endif
}
-#if defined(QQNX_PPS)
+#if QT_CONFIG(qqnx_pps)
// delay invocation of start() to the time the event loop is up and running
// needed to have the QThread internals of the main thread properly initialized
QMetaObject::invokeMethod(m_buttonsNotifier, "start", Qt::QueuedConnection);
@@ -224,7 +223,7 @@ QQnxIntegration::~QQnxIntegration()
#endif
// Stop/destroy navigator event notifier
-#if defined(QQNX_PPS)
+#if QT_CONFIG(qqnx_pps)
delete m_navigatorEventNotifier;
#endif
delete m_navigatorEventHandler;
@@ -248,7 +247,7 @@ QQnxIntegration::~QQnxIntegration()
QQnxGLContext::shutdownContext();
#endif
-#if defined(QQNX_PPS)
+#if QT_CONFIG(qqnx_pps)
// Destroy the hardware button notifier
delete m_buttonsNotifier;
@@ -318,7 +317,7 @@ QPlatformOpenGLContext *QQnxIntegration::createPlatformOpenGLContext(QOpenGLCont
}
#endif
-#if defined(QQNX_PPS)
+#if QT_CONFIG(qqnx_pps)
QPlatformInputContext *QQnxIntegration::inputContext() const
{
qIntegrationDebug();
@@ -361,7 +360,7 @@ QPlatformClipboard *QQnxIntegration::clipboard() const
{
qIntegrationDebug();
-#if defined(QQNX_PPS)
+#if QT_CONFIG(qqnx_pps)
if (!m_clipboard)
m_clipboard = new QQnxClipboard;
#endif
diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h
index b2008baa0c..d1ebb1d4bf 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.h
+++ b/src/plugins/platforms/qnx/qqnxintegration.h
@@ -41,7 +41,7 @@
#define QQNXINTEGRATION_H
#include <qpa/qplatformintegration.h>
-
+#include <private/qtguiglobal_p.h>
#include <QtCore/qmutex.h>
#include <screen/screen.h>
@@ -61,7 +61,7 @@ class QQnxServices;
class QSimpleDrag;
-#if defined(QQNX_PPS)
+#if QT_CONFIG(qqnx_pps)
class QQnxInputContext;
class QQnxNavigatorEventNotifier;
class QQnxButtonEventNotifier;
@@ -96,7 +96,7 @@ public:
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
#endif
-#if defined(QQNX_PPS)
+#if QT_CONFIG(qqnx_pps)
QPlatformInputContext *inputContext() const override;
#endif
@@ -143,7 +143,7 @@ private:
QQnxScreenEventThread *m_screenEventThread;
QQnxNavigatorEventHandler *m_navigatorEventHandler;
QQnxAbstractVirtualKeyboard *m_virtualKeyboard;
-#if defined(QQNX_PPS)
+#if QT_CONFIG(qqnx_pps)
QQnxNavigatorEventNotifier *m_navigatorEventNotifier;
QQnxInputContext *m_inputContext;
QQnxButtonEventNotifier *m_buttonsNotifier;
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
index a325b9d1d7..e1a5837201 100644
--- a/src/plugins/platforms/windows/qwindowscursor.cpp
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -548,6 +548,8 @@ CursorHandlePtr QWindowsCursor::standardWindowCursor(Qt::CursorShape shape)
return it != m_standardCursorCache.end() ? it.value() : CursorHandlePtr(new CursorHandle);
}
+HCURSOR QWindowsCursor::m_overriddenCursor = nullptr;
+
/*!
\brief Return cached pixmap cursor or create new one.
*/
@@ -623,7 +625,9 @@ void QWindowsCursor::setOverrideCursor(const QCursor &cursor)
{
const CursorHandlePtr wcursor = cursorHandle(cursor);
if (wcursor->handle()) {
- m_overriddenCursor = SetCursor(wcursor->handle());
+ const HCURSOR previousCursor = SetCursor(wcursor->handle());
+ if (m_overriddenCursor == nullptr)
+ m_overriddenCursor = previousCursor;
} else {
qWarning("%s: Unable to obtain system cursor for %d",
__FUNCTION__, cursor.shape());
diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h
index 8af56e4e0c..4772f3fce5 100644
--- a/src/plugins/platforms/windows/qwindowscursor.h
+++ b/src/plugins/platforms/windows/qwindowscursor.h
@@ -141,7 +141,7 @@ private:
mutable QPixmap m_linkDragCursor;
mutable QPixmap m_ignoreDragCursor;
- HCURSOR m_overriddenCursor = nullptr;
+ static HCURSOR m_overriddenCursor;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsmenu.cpp b/src/plugins/platforms/windows/qwindowsmenu.cpp
index 4e1997c4f8..72f11d54b4 100644
--- a/src/plugins/platforms/windows/qwindowsmenu.cpp
+++ b/src/plugins/platforms/windows/qwindowsmenu.cpp
@@ -686,9 +686,16 @@ void QWindowsPopupMenu::showPopup(const QWindow *parentWindow, const QRect &targ
bool QWindowsPopupMenu::trackPopupMenu(HWND windowHandle, int x, int y)
{
lastShownPopupMenu = this;
- return TrackPopupMenu(menuHandle(),
+ // Emulate Show()/Hide() signals. Could be implemented by catching the
+ // WM_EXITMENULOOP, WM_ENTERMENULOOP messages; but they do not carry
+ // information telling which menu was opened.
+ emit aboutToShow();
+ const bool result =
+ TrackPopupMenu(menuHandle(),
QGuiApplication::layoutDirection() == Qt::RightToLeft ? UINT(TPM_RIGHTALIGN) : UINT(0),
x, y, 0, windowHandle, nullptr) == TRUE;
+ emit aboutToHide();
+ return result;
}
bool QWindowsPopupMenu::notifyTriggered(uint id)
diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp
index b892f1610d..34e6041687 100644
--- a/src/plugins/platforms/windows/qwindowsmime.cpp
+++ b/src/plugins/platforms/windows/qwindowsmime.cpp
@@ -52,6 +52,7 @@
#include <QtGui/QImageWriter>
#include <shlobj.h>
+#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -1264,15 +1265,16 @@ bool QBuiltInMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData
QVector<FORMATETC> QBuiltInMimes::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
{
QVector<FORMATETC> formatetcs;
- if (!outFormats.keys(mimeType).isEmpty() && mimeData->formats().contains(mimeType))
- formatetcs += setCf(outFormats.key(mimeType));
+ const auto mit = std::find(outFormats.cbegin(), outFormats.cend(), mimeType);
+ if (mit != outFormats.cend() && mimeData->formats().contains(mimeType))
+ formatetcs += setCf(mit.key());
return formatetcs;
}
bool QBuiltInMimes::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
{
- return (!inFormats.keys(mimeType).isEmpty())
- && canGetData(inFormats.key(mimeType), pDataObj);
+ const auto mit = std::find(inFormats.cbegin(), inFormats.cend(), mimeType);
+ return mit != inFormats.cend() && canGetData(mit.key(), pDataObj);
}
QVariant QBuiltInMimes::convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const
@@ -1315,7 +1317,7 @@ public:
QString mimeForFormat(const FORMATETC &formatetc) const override;
private:
- QMap<int, QString> formats;
+ mutable QMap<int, QString> formats;
static QStringList ianaTypes;
static QStringList excludeList;
};
@@ -1380,15 +1382,13 @@ bool QLastResortMimes::convertFromMime(const FORMATETC &formatetc, const QMimeDa
QVector<FORMATETC> QLastResortMimes::formatsForMime(const QString &mimeType, const QMimeData * /*mimeData*/) const
{
QVector<FORMATETC> formatetcs;
- if (!formats.keys(mimeType).isEmpty()) {
- formatetcs += setCf(formats.key(mimeType));
- } else if (!excludeList.contains(mimeType, Qt::CaseInsensitive)){
- // register any other available formats
- int cf = QWindowsMime::registerMimeType(mimeType);
- QLastResortMimes *that = const_cast<QLastResortMimes *>(this);
- that->formats.insert(cf, mimeType);
- formatetcs += setCf(cf);
- }
+ auto mit = std::find(formats.begin(), formats.end(), mimeType);
+ // register any other available formats
+ if (mit == formats.end() && !excludeList.contains(mimeType, Qt::CaseInsensitive))
+ mit = formats.insert(QWindowsMime::registerMimeType(mimeType), mimeType);
+ if (mit != formats.end())
+ formatetcs += setCf(mit.key());
+
if (!formatetcs.isEmpty())
qCDebug(lcQpaMime) << __FUNCTION__ << mimeType << formatetcs;
return formatetcs;
@@ -1426,14 +1426,11 @@ bool QLastResortMimes::canConvertToMime(const QString &mimeType, IDataObject *pD
QString clipFormat = customMimeType(mimeType);
const UINT cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16()));
return canGetData(int(cf), pDataObj);
- } else if (formats.keys(mimeType).isEmpty()) {
- // if it is not in there then register it and see if we can get it
- int cf = QWindowsMime::registerMimeType(mimeType);
- return canGetData(cf, pDataObj);
- } else {
- return canGetData(formats.key(mimeType), pDataObj);
}
- return false;
+ // if it is not in there then register it and see if we can get it
+ const auto mit = std::find(formats.cbegin(), formats.cend(), mimeType);
+ const int cf = mit != formats.cend() ? mit.key() : QWindowsMime::registerMimeType(mimeType);
+ return canGetData(cf, pDataObj);
}
QVariant QLastResortMimes::convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const
@@ -1447,11 +1444,10 @@ QVariant QLastResortMimes::convertToMime(const QString &mimeType, IDataObject *p
QString clipFormat = customMimeType(mimeType, &lindex);
const UINT cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16()));
data = getData(int(cf), pDataObj, lindex);
- } else if (formats.keys(mimeType).isEmpty()) {
- int cf = QWindowsMime::registerMimeType(mimeType);
- data = getData(cf, pDataObj);
} else {
- data = getData(formats.key(mimeType), pDataObj);
+ const auto mit = std::find(formats.cbegin(), formats.cend(), mimeType);
+ const int cf = mit != formats.cend() ? mit.key() : QWindowsMime::registerMimeType(mimeType);
+ data = getData(cf, pDataObj);
}
if (!data.isEmpty())
val = data; // it should be enough to return the data and let QMimeData do the rest.
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp
index 5283d6b260..a511cc6164 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.cpp
+++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp
@@ -214,7 +214,7 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c
#else
QOpenGLConfig::Gpu qgpu = QOpenGLConfig::Gpu::fromDevice(gpu.vendorId, gpu.deviceId, gpu.driverVersion, gpu.description);
SupportedRenderersCache *srCache = supportedRenderersCache();
- SupportedRenderersCache::const_iterator it = srCache->find(qgpu);
+ SupportedRenderersCache::const_iterator it = srCache->constFind(qgpu);
if (it != srCache->cend())
return *it;
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
index fba4e8f386..5fdc664603 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
@@ -355,6 +355,8 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L
if (!LOWORD(lParam)) {
qCDebug(lcQpaTablet) << "leave proximity for device #" << m_currentDevice;
+ if (m_currentDevice < 0 || m_currentDevice >= m_devices.size()) // QTBUG-65120, spurious leave observed
+ return false;
if (totalPacks > 0) {
QWindowSystemInterface::handleTabletLeaveProximityEvent(proximityBuffer[0].pkTime,
m_devices.at(m_currentDevice).currentDevice,
diff --git a/src/plugins/platforms/xcb/README b/src/plugins/platforms/xcb/README
index 5efc9b7f99..8308db46dc 100644
--- a/src/plugins/platforms/xcb/README
+++ b/src/plugins/platforms/xcb/README
@@ -25,9 +25,8 @@ This should allow for binaries that are portable across most modern Linux distri
PACKAGE VERSION REQUIREMENTS
When using touch input via XInput 2.2 or higher, there is a potential issue on systems that ship with
-a libXi older than 1.7.4. This is because XIAllowTouchEvents can deadlock with libXi 1.7.3 and earlier.
+a libXi older than 1.7.5. This is because XIAllowTouchEvents can deadlock with libXi 1.7.4 and earlier.
When touch events are never received, this is not an issue, so plain mouse/keyboard systems are not affected.
-See http://lists.x.org/archives/xorg-devel/2014-July/043059.html for details on the libXi patch.
Qt versions before 5.8 attempted to recognize this scenario based on the pkg-config package version and skip
the call. This has been removed starting from 5.8 since relying on pkg-config package versions is unsafe given
that Qt must also support systems with limited or incomplete pkg-config setups.
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 2fc39012ce..315f295ff3 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -94,6 +94,7 @@ void QXcbConnection::xi2SelectStateEvents()
XIEventMask xiEventMask;
bitMask = XI_HierarchyChangedMask;
bitMask |= XI_DeviceChangedMask;
+ bitMask |= XI_PropertyEventMask;
xiEventMask.deviceid = XIAllDevices;
xiEventMask.mask_len = sizeof(bitMask);
xiEventMask.mask = xiBitMask;
@@ -115,7 +116,6 @@ void QXcbConnection::xi2SelectDeviceEvents(xcb_window_t window)
// core enter/leave events will be ignored in this case.
bitMask |= XI_EnterMask;
bitMask |= XI_LeaveMask;
- bitMask |= XI_PropertyEventMask;
#ifdef XCB_USE_XINPUT22
if (isAtLeastXI22()) {
bitMask |= XI_TouchBeginMask;
@@ -372,24 +372,25 @@ void QXcbConnection::xi2SelectDeviceEventsCompatibility(xcb_window_t window)
unsigned int mask = 0;
unsigned char *bitMask = reinterpret_cast<unsigned char *>(&mask);
- mask |= XI_PropertyEventMask;
+ Display *dpy = static_cast<Display *>(m_xlib_display);
+
#ifdef XCB_USE_XINPUT22
if (isAtLeastXI22()) {
mask |= XI_TouchBeginMask;
mask |= XI_TouchUpdateMask;
mask |= XI_TouchEndMask;
+
+ XIEventMask xiMask;
+ xiMask.mask_len = sizeof(mask);
+ xiMask.mask = bitMask;
+ xiMask.deviceid = XIAllMasterDevices;
+ Status result = XISelectEvents(dpy, window, &xiMask, 1);
+ if (result == Success)
+ QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false);
+ else
+ qCDebug(lcQpaXInput, "failed to select events, window %x, result %d", window, result);
}
#endif
- XIEventMask xiMask;
- xiMask.mask_len = sizeof(mask);
- xiMask.mask = bitMask;
- xiMask.deviceid = XIAllMasterDevices;
- Display *dpy = static_cast<Display *>(m_xlib_display);
- Status result = XISelectEvents(dpy, window, &xiMask, 1);
- if (result == Success)
- QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false);
- else
- qCDebug(lcQpaXInput, "failed to select events, window %x, result %d", window, result);
mask = XI_ButtonPressMask;
mask |= XI_ButtonReleaseMask;
@@ -428,6 +429,11 @@ void QXcbConnection::xi2SelectDeviceEventsCompatibility(xcb_window_t window)
XISelectEvents(dpy, window, xiEventMask.data(), i);
}
#endif
+
+#if !QT_CONFIG(tabletevent) && !defined(XCB_USE_XINPUT21)
+ Q_UNUSED(bitMask);
+ Q_UNUSED(dpy);
+#endif
}
QXcbConnection::TouchDeviceData *QXcbConnection::touchDeviceForId(int id)
@@ -749,8 +755,9 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
// Touches must be accepted when we are grabbing touch events. Otherwise the entire sequence
// will get replayed when the grab ends.
if (m_xiGrab) {
- // XIAllowTouchEvents deadlocks with libXi < 1.7.4 (this has nothing to do with the XI2 versions like 2.2)
- // http://lists.x.org/archives/xorg-devel/2014-July/043059.html
+ // Note that XIAllowTouchEvents is known to deadlock with older libXi versions,
+ // for details see qtbase/src/plugins/platforms/xcb/README. This has nothing to
+ // do with the XInput protocol version, but is a bug in libXi implementation instead.
XIAllowTouchEvents(static_cast<Display *>(m_xlib_display), xiDeviceEvent->deviceid,
xiDeviceEvent->detail, xiDeviceEvent->event, XIAcceptTouch);
}
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 18f5ff4f0d..8ea0ebf966 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -165,6 +165,9 @@ void QXcbDrag::init()
QXcbCursor::queryPointer(connection(), &current_virtual_desktop, 0);
drag_types.clear();
+
+ dropped = false;
+ canceled = false;
}
bool QXcbDrag::eventFilter(QObject *o, QEvent *e)
@@ -215,6 +218,10 @@ void QXcbDrag::startDrag()
void QXcbDrag::endDrag()
{
QBasicDrag::endDrag();
+ if (!dropped && !canceled && canDrop()) {
+ // Set executed drop action when dropping outside application.
+ setExecutedDropAction(accepted_drop_action);
+ }
initiatorWindow.clear();
}
@@ -989,6 +996,8 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e
// reset
target_time = XCB_CURRENT_TIME;
+
+ dropped = true;
}
@@ -1087,6 +1096,8 @@ void QXcbDrag::cancel()
// remove canceled object
currentDrag()->deleteLater();
+
+ canceled = true;
}
// find an ancestor with XdndAware on it
diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h
index f261cc1322..31f1c47d83 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.h
+++ b/src/plugins/platforms/xcb/qxcbdrag.h
@@ -135,6 +135,10 @@ private:
QRect source_sameanswer;
bool waiting_for_status;
+ // helpers for setting executed drop action outside application
+ bool dropped;
+ bool canceled;
+
// top-level window we sent position to last.
xcb_window_t current_target;
// window to send events to (always valid if current_target)
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index cdeafa8cba..e3d9bc7a3d 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -446,17 +446,24 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
m_cursor = new QXcbCursor(connection, this);
- // Parse EDID
- if (m_edid.parse(getEdid()))
- qCDebug(lcQpaScreen, "EDID data for output \"%s\": identifier '%s', manufacturer '%s', model '%s', serial '%s', physical size: %.2fx%.2f",
- name().toLatin1().constData(),
- m_edid.identifier.toLatin1().constData(),
- m_edid.manufacturer.toLatin1().constData(),
- m_edid.model.toLatin1().constData(),
- m_edid.serialNumber.toLatin1().constData(),
- m_edid.physicalSize.width(), m_edid.physicalSize.height());
- else
- qCDebug(lcQpaScreen) << "Failed to parse EDID data for output" << name(); // keep this debug, not warning
+ if (connection->hasXRandr()) { // Parse EDID
+ QByteArray edid = getEdid();
+ if (m_edid.parse(edid)) {
+ qCDebug(lcQpaScreen, "EDID data for output \"%s\": identifier '%s', manufacturer '%s',"
+ "model '%s', serial '%s', physical size: %.2fx%.2f",
+ name().toLatin1().constData(),
+ m_edid.identifier.toLatin1().constData(),
+ m_edid.manufacturer.toLatin1().constData(),
+ m_edid.model.toLatin1().constData(),
+ m_edid.serialNumber.toLatin1().constData(),
+ m_edid.physicalSize.width(), m_edid.physicalSize.height());
+ } else {
+ // This property is defined by the xrandr spec. Parsing failure indicates a valid error,
+ // but keep this as debug, for details see 4f515815efc318ddc909a0399b71b8a684962f38.
+ qCDebug(lcQpaScreen) << "Failed to parse EDID data for output" << name() <<
+ "edid data: " << edid;
+ }
+ }
}
QXcbScreen::~QXcbScreen()
@@ -901,9 +908,13 @@ QByteArray QXcbScreen::getOutputProperty(xcb_atom_t atom) const
QByteArray QXcbScreen::getEdid() const
{
+ QByteArray result;
+ if (!connection()->hasXRandr())
+ return result;
+
// Try a bunch of atoms
xcb_atom_t atom = connection()->internAtom("EDID");
- QByteArray result = getOutputProperty(atom);
+ result = getOutputProperty(atom);
if (result.isEmpty()) {
atom = connection()->internAtom("EDID_DATA");
result = getOutputProperty(atom);
diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
index a98a7892dd..00cce13fd0 100644
--- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro
+++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
@@ -99,4 +99,6 @@ qtConfig(vulkan) {
QMAKE_USE += xkbcommon
}
+qtConfig(dlopen): QMAKE_USE += libdl
+
load(qt_module)
diff --git a/src/plugins/sqldrivers/db2/db2.pro b/src/plugins/sqldrivers/db2/db2.pro
index eef65fac66..b99fe91fe3 100644
--- a/src/plugins/sqldrivers/db2/db2.pro
+++ b/src/plugins/sqldrivers/db2/db2.pro
@@ -7,5 +7,7 @@ QMAKE_USE += db2
OTHER_FILES += db2.json
+equals(QT_ARCH, x86_64): DEFINES += ODBC64
+
PLUGIN_CLASS_NAME = QDB2DriverPlugin
include(../qsqldriverbase.pri)
diff --git a/src/plugins/sqldrivers/db2/qsql_db2.cpp b/src/plugins/sqldrivers/db2/qsql_db2.cpp
index b457ced538..2c8097ed07 100644
--- a/src/plugins/sqldrivers/db2/qsql_db2.cpp
+++ b/src/plugins/sqldrivers/db2/qsql_db2.cpp
@@ -272,7 +272,7 @@ static QSqlField qMakeFieldInfo(const QDB2ResultPrivate* d, int i)
{
SQLSMALLINT colNameLen;
SQLSMALLINT colType;
- SQLUINTEGER colSize;
+ SQLULEN colSize;
SQLSMALLINT colScale;
SQLSMALLINT nullable;
SQLRETURN r = SQL_ERROR;
@@ -314,7 +314,7 @@ static int qGetIntData(SQLHANDLE hStmt, int column, bool& isNull)
{
SQLINTEGER intbuf;
isNull = false;
- SQLINTEGER lengthIndicator = 0;
+ SQLLEN lengthIndicator = 0;
SQLRETURN r = SQLGetData(hStmt,
column + 1,
SQL_C_SLONG,
@@ -332,7 +332,7 @@ static double qGetDoubleData(SQLHANDLE hStmt, int column, bool& isNull)
{
SQLDOUBLE dblbuf;
isNull = false;
- SQLINTEGER lengthIndicator = 0;
+ SQLLEN lengthIndicator = 0;
SQLRETURN r = SQLGetData(hStmt,
column+1,
SQL_C_DOUBLE,
@@ -351,7 +351,7 @@ static SQLBIGINT qGetBigIntData(SQLHANDLE hStmt, int column, bool& isNull)
{
SQLBIGINT lngbuf = Q_INT64_C(0);
isNull = false;
- SQLINTEGER lengthIndicator = 0;
+ SQLLEN lengthIndicator = 0;
SQLRETURN r = SQLGetData(hStmt,
column+1,
SQL_C_SBIGINT,
@@ -368,7 +368,7 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool& is
{
QString fieldVal;
SQLRETURN r = SQL_ERROR;
- SQLINTEGER lengthIndicator = 0;
+ SQLLEN lengthIndicator = 0;
if (colSize <= 0)
colSize = 255;
@@ -404,12 +404,12 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool& is
return fieldVal;
}
-static QByteArray qGetBinaryData(SQLHANDLE hStmt, int column, SQLINTEGER& lengthIndicator, bool& isNull)
+static QByteArray qGetBinaryData(SQLHANDLE hStmt, int column, SQLLEN& lengthIndicator, bool& isNull)
{
QByteArray fieldVal;
SQLSMALLINT colNameLen;
SQLSMALLINT colType;
- SQLUINTEGER colSize;
+ SQLULEN colSize;
SQLSMALLINT colScale;
SQLSMALLINT nullable;
SQLRETURN r = SQL_ERROR;
@@ -643,9 +643,9 @@ bool QDB2Result::exec()
{
Q_D(QDB2Result);
QList<QByteArray> tmpStorage; // holds temporary ptrs
- QVarLengthArray<SQLINTEGER, 32> indicators(boundValues().count());
+ QVarLengthArray<SQLLEN, 32> indicators(boundValues().count());
- memset(indicators.data(), 0, indicators.size() * sizeof(SQLINTEGER));
+ memset(indicators.data(), 0, indicators.size() * sizeof(SQLLEN));
setActive(false);
setAt(QSql::BeforeFirstRow);
SQLRETURN r;
@@ -661,7 +661,7 @@ bool QDB2Result::exec()
int i;
for (i = 0; i < values.count(); ++i) {
// bind parameters - only positional binding allowed
- SQLINTEGER *ind = &indicators[i];
+ SQLLEN *ind = &indicators[i];
if (values.at(i).isNull())
*ind = SQL_NULL_DATA;
if (bindValueType(i) & QSql::Out)
@@ -1006,7 +1006,7 @@ QVariant QDB2Result::data(int field)
return QVariant();
}
SQLRETURN r = 0;
- SQLINTEGER lengthIndicator = 0;
+ SQLLEN lengthIndicator = 0;
bool isNull = false;
const QSqlField info = d->recInf.field(field);
@@ -1119,7 +1119,7 @@ bool QDB2Result::isNull(int i)
int QDB2Result::numRowsAffected()
{
Q_D(const QDB2Result);
- SQLINTEGER affectedRowCount = 0;
+ SQLLEN affectedRowCount = 0;
SQLRETURN r = SQLRowCount(d->hStmt, &affectedRowCount);
if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO)
return affectedRowCount;
@@ -1248,7 +1248,7 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas
const QString opt(tmp.left(idx));
const QString val(tmp.mid(idx + 1).simplified());
- SQLUINTEGER v = 0;
+ SQLULEN v = 0;
r = SQL_SUCCESS;
if (opt == QLatin1String("SQL_ATTR_ACCESS_MODE")) {
if (val == QLatin1String("SQL_MODE_READ_ONLY")) {
@@ -1634,7 +1634,7 @@ bool QDB2Driver::rollbackTransaction()
bool QDB2Driver::setAutoCommit(bool autoCommit)
{
Q_D(QDB2Driver);
- SQLUINTEGER ac = autoCommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
+ SQLULEN ac = autoCommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
SQLRETURN r = SQLSetConnectAttr(d->hDbc,
SQL_ATTR_AUTOCOMMIT,
reinterpret_cast<SQLPOINTER>(ac),
diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp
index 0fd34f019b..ab9aa7f176 100644
--- a/src/plugins/sqldrivers/psql/qsql_psql.cpp
+++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp
@@ -222,7 +222,7 @@ class QPSQLResultPrivate : public QSqlResultPrivate
{
Q_DECLARE_PUBLIC(QPSQLResult)
public:
- Q_DECLARE_SQLDRIVER_PRIVATE(QPSQLDriver);
+ Q_DECLARE_SQLDRIVER_PRIVATE(QPSQLDriver)
QPSQLResultPrivate(QPSQLResult *q, const QPSQLDriver *drv)
: QSqlResultPrivate(q, drv),
result(0),
diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
index e1ddd4b25e..39070c32e8 100644
--- a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
+++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
@@ -467,7 +467,7 @@ bool QSQLiteResult::exec()
#if (SQLITE_VERSION_NUMBER >= 3003011)
// In the case of the reuse of a named placeholder
- if (!paramCountIsValid) {
+ if (paramCount < values.count()) {
const auto countIndexes = [](int counter, const QList<int>& indexList) {
return counter + indexList.length();
};
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index 4eb63a1cff..aee258fda0 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -4186,7 +4186,6 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
break;
}
- const int tabwidth = mi->tabWidth;
const int maxpmw = mi->maxIconWidth;
const bool enabled = mi->state & State_Enabled;
@@ -4244,21 +4243,37 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
}
QString s = mi->text;
- if (!s.isEmpty()) {
- int t = s.indexOf(QLatin1Char('\t'));
- int text_flags = Qt::AlignRight | Qt::AlignVCenter | Qt::TextHideMnemonic
- | Qt::TextSingleLine | Qt::AlignAbsolute;
- int yPos = mi->rect.y();
- if (widgetSize == QStyleHelper::SizeMini)
- yPos += 1;
- p->save();
- if (t >= 0) {
- p->setFont(qt_app_fonts_hash()->value("QMenuItem", p->font()));
- int xp = mi->rect.right() - tabwidth - macRightBorder - macItemHMargin - macItemFrame + 1;
- p->drawText(xp, yPos, tabwidth, mi->rect.height(), text_flags, s.mid(t + 1));
- s = s.left(t);
- }
+ const auto text_flags = Qt::AlignVCenter | Qt::TextHideMnemonic
+ | Qt::TextSingleLine | Qt::AlignAbsolute;
+ int yPos = mi->rect.y();
+ if (widgetSize == QStyleHelper::SizeMini)
+ yPos += 1;
+
+ const bool isSubMenu = mi->menuItemType == QStyleOptionMenuItem::SubMenu;
+ const int tabwidth = isSubMenu ? 9 : mi->tabWidth;
+
+ QString rightMarginText;
+ if (isSubMenu)
+ rightMarginText = QStringLiteral("\u25b6\ufe0e"); // U+25B6 U+FE0E: BLACK RIGHT-POINTING TRIANGLE
+
+ // If present, save and remove embedded shorcut from text
+ const int tabIndex = s.indexOf(QLatin1Char('\t'));
+ if (tabIndex >= 0) {
+ if (!isSubMenu) // ... but ignore it if it's a submenu.
+ rightMarginText = s.mid(tabIndex + 1);
+ s = s.left(tabIndex);
+ }
+ p->save();
+ if (!rightMarginText.isEmpty()) {
+ p->setFont(qt_app_fonts_hash()->value("QMenuItem", p->font()));
+ int xp = mi->rect.right() - tabwidth - macRightBorder + 2;
+ if (!isSubMenu)
+ xp -= macItemHMargin + macItemFrame + 3; // Adjust for shortcut
+ p->drawText(xp, yPos, tabwidth, mi->rect.height(), text_flags | Qt::AlignRight, rightMarginText);
+ }
+
+ if (!s.isEmpty()) {
const int xm = macItemFrame + maxpmw + macItemHMargin;
QFont myFont = mi->font;
// myFont may not have any "hard" flags set. We override
@@ -4269,9 +4284,9 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
myFont.setPointSizeF(QFontInfo(mi->font).pointSizeF());
p->setFont(myFont);
p->drawText(xpos, yPos, mi->rect.width() - xm - tabwidth + 1,
- mi->rect.height(), text_flags ^ Qt::AlignRight, s);
- p->restore();
+ mi->rect.height(), text_flags, s);
}
+ p->restore();
}
break;
case CE_MenuBarItem:
@@ -5158,11 +5173,11 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
const auto cw = QMacStylePrivate::CocoaControl(controlType, cocoaSize);
NSScroller *scroller = static_cast<NSScroller *>(d->cocoaControl(cw));
+ const QColor bgColor = QStyleHelper::backgroundColor(opt->palette, widget);
+ const bool hasDarkBg = bgColor.red() < 128 && bgColor.green() < 128 && bgColor.blue() < 128;
if (isTransient) {
// macOS behavior: as soon as one color channel is >= 128,
// the background is considered bright, scroller is dark.
- const QColor bgColor = QStyleHelper::backgroundColor(opt->palette, widget);
- const bool hasDarkBg = bgColor.red() < 128 && bgColor.green() < 128 && bgColor.blue() < 128;
scroller.knobStyle = hasDarkBg? NSScrollerKnobStyleLight : NSScrollerKnobStyleDark;
} else {
scroller.knobStyle = NSScrollerKnobStyleDefault;
@@ -5174,7 +5189,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
break;
if (isTransient) {
- CGContextBeginTransparencyLayer(cg, NULL);
+ CGContextBeginTransparencyLayerWithRect(cg, scroller.frame, nullptr);
CGContextSetAlpha(cg, opacity);
}
@@ -5212,7 +5227,8 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
QCFType<CGPathRef> knobPath = CGPathCreateWithRoundedRect(knobRect, knobRadius, knobRadius, nullptr);
CGContextAddPath(cg, knobPath);
CGContextSetAlpha(cg, 0.5);
- CGContextSetFillColorWithColor(cg, NSColor.blackColor.CGColor);
+ CGColorRef knobColor = hasDarkBg ? NSColor.whiteColor.CGColor : NSColor.blackColor.CGColor;
+ CGContextSetFillColorWithColor(cg, knobColor);
CGContextFillPath(cg);
} else {
[scroller drawKnob];
@@ -6363,8 +6379,8 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
}
if (mi->text.contains(QLatin1Char('\t')))
w += 12;
- if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
- w += 20;
+ else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
+ w += 35; // Not quite exactly as it seems to depend on other factors
if (maxpmw)
w += maxpmw + 6;
// add space for a check. All items have place for a check too.
diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
index 22c91db7ca..0c28a9900d 100644
--- a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
+++ b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
@@ -286,10 +286,10 @@ static inline HWND createTreeViewHelperWindow()
void *hwnd = 0;
void *wndProc = reinterpret_cast<void *>(DefWindowProc);
if (QMetaObject::invokeMethod(ni, "createMessageWindow", Qt::DirectConnection,
- Q_RETURN_ARG(void *, hwnd),
+ Q_RETURN_ARG(void*, hwnd),
Q_ARG(QString, QStringLiteral("QTreeViewThemeHelperWindowClass")),
Q_ARG(QString, QStringLiteral("QTreeViewThemeHelperWindow")),
- Q_ARG(void *, wndProc)) && hwnd) {
+ Q_ARG(void*, wndProc)) && hwnd) {
return reinterpret_cast<HWND>(hwnd);
}
}
diff --git a/src/printsupport/dialogs/qabstractprintdialog.cpp b/src/printsupport/dialogs/qabstractprintdialog.cpp
index f982da46d9..71b5500bab 100644
--- a/src/printsupport/dialogs/qabstractprintdialog.cpp
+++ b/src/printsupport/dialogs/qabstractprintdialog.cpp
@@ -471,7 +471,7 @@ void QPrintDialog::done(int result)
if (d->receiverToDisconnectOnClose) {
disconnect(this, SIGNAL(accepted(QPrinter*)),
d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
- d->receiverToDisconnectOnClose = 0;
+ d->receiverToDisconnectOnClose = nullptr;
}
d->memberToDisconnectOnClose.clear();
}
diff --git a/src/printsupport/dialogs/qabstractprintdialog_p.h b/src/printsupport/dialogs/qabstractprintdialog_p.h
index 2537fcbf80..a17a28f564 100644
--- a/src/printsupport/dialogs/qabstractprintdialog_p.h
+++ b/src/printsupport/dialogs/qabstractprintdialog_p.h
@@ -69,7 +69,7 @@ class QAbstractPrintDialogPrivate : public QDialogPrivate
public:
QAbstractPrintDialogPrivate()
- : printer(0), pd(0), ownsPrinter(false)
+ : printer(nullptr), pd(nullptr), ownsPrinter(false)
, options(QAbstractPrintDialog::PrintToFile | QAbstractPrintDialog::PrintPageRange |
QAbstractPrintDialog::PrintCollateCopies | QAbstractPrintDialog::PrintShowPageSize),
minPage(0), maxPage(INT_MAX)
diff --git a/src/printsupport/dialogs/qpagesetupdialog_p.h b/src/printsupport/dialogs/qpagesetupdialog_p.h
index 6a389b039a..a2b3f8363c 100644
--- a/src/printsupport/dialogs/qpagesetupdialog_p.h
+++ b/src/printsupport/dialogs/qpagesetupdialog_p.h
@@ -71,7 +71,7 @@ class QPageSetupDialogPrivate : public QDialogPrivate
Q_DECLARE_PUBLIC(QPageSetupDialog)
public:
- QPageSetupDialogPrivate(QPrinter *printer);
+ explicit QPageSetupDialogPrivate(QPrinter *printer);
void setPrinter(QPrinter *newPrinter);
diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
index 6f3bb0dd55..fcf7c8dddc 100644
--- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
@@ -230,8 +230,8 @@ void QUnixPageSetupDialogPrivate::init()
QPageSetupWidget::QPageSetupWidget(QWidget *parent)
: QWidget(parent),
- m_pagePreview(0),
- m_printer(0),
+ m_pagePreview(nullptr),
+ m_printer(nullptr),
m_outputFormat(QPrinter::PdfFormat),
m_units(QPageLayout::Point),
m_blockSignals(false)
@@ -260,21 +260,21 @@ QPageSetupWidget::QPageSetupWidget(QWidget *parent)
initUnits();
initPagesPerSheet();
- connect(m_ui.unitCombo, SIGNAL(activated(int)), this, SLOT(unitChanged()));
+ connect(m_ui.unitCombo, QOverload<int>::of(&QComboBox::activated), this, &QPageSetupWidget::unitChanged);
- connect(m_ui.pageSizeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(pageSizeChanged()));
- connect(m_ui.pageWidth, SIGNAL(valueChanged(double)), this, SLOT(pageSizeChanged()));
- connect(m_ui.pageHeight, SIGNAL(valueChanged(double)), this, SLOT(pageSizeChanged()));
+ connect(m_ui.pageSizeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QPageSetupWidget::pageSizeChanged);
+ connect(m_ui.pageWidth, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::pageSizeChanged);
+ connect(m_ui.pageHeight, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::pageSizeChanged);
- connect(m_ui.leftMargin, SIGNAL(valueChanged(double)), this, SLOT(leftMarginChanged(double)));
- connect(m_ui.topMargin, SIGNAL(valueChanged(double)), this, SLOT(topMarginChanged(double)));
- connect(m_ui.rightMargin, SIGNAL(valueChanged(double)), this, SLOT(rightMarginChanged(double)));
- connect(m_ui.bottomMargin, SIGNAL(valueChanged(double)), this, SLOT(bottomMarginChanged(double)));
+ connect(m_ui.leftMargin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::leftMarginChanged);
+ connect(m_ui.topMargin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::topMarginChanged);
+ connect(m_ui.rightMargin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::rightMarginChanged);
+ connect(m_ui.bottomMargin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::bottomMarginChanged);
- connect(m_ui.portrait, SIGNAL(clicked()), this, SLOT(pageOrientationChanged()));
- connect(m_ui.landscape, SIGNAL(clicked()), this, SLOT(pageOrientationChanged()));
+ connect(m_ui.portrait, &QRadioButton::clicked, this, &QPageSetupWidget::pageOrientationChanged);
+ connect(m_ui.landscape, &QRadioButton::clicked, this, &QPageSetupWidget::pageOrientationChanged);
- connect(m_ui.pagesPerSheetCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(pagesPerSheetChanged()));
+ connect(m_ui.pagesPerSheetCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QPageSetupWidget::pagesPerSheetChanged);
}
// Init the Units combo box
diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix_p.h b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h
index 574569de29..5b77a73871 100644
--- a/src/printsupport/dialogs/qpagesetupdialog_unix_p.h
+++ b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h
@@ -70,7 +70,7 @@ class QPagePreview;
class QPageSetupWidget : public QWidget {
Q_OBJECT
public:
- explicit QPageSetupWidget(QWidget *parent = 0);
+ explicit QPageSetupWidget(QWidget *parent = nullptr);
void setPrinter(QPrinter *printer, QPrintDevice *printDevice,
QPrinter::OutputFormat outputFormat, const QString &printerName);
diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp
index 6a7e679620..63d23cc162 100644
--- a/src/printsupport/dialogs/qprintdialog_unix.cpp
+++ b/src/printsupport/dialogs/qprintdialog_unix.cpp
@@ -335,8 +335,8 @@ QPrintPropertiesDialog::QPrintPropertiesDialog(QPrinter *printer, QPrintDevice *
lay->addWidget(content);
lay->addWidget(m_buttons);
- connect(m_buttons->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept()));
- connect(m_buttons->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject()));
+ connect(m_buttons->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &QPrintPropertiesDialog::accept);
+ connect(m_buttons->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &QPrintPropertiesDialog::reject);
widget.pageSetup->setPrinter(printer, currentPrintDevice, outputFormat, printerName);
@@ -726,7 +726,7 @@ QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent)
Constructs a print dialog with the given \a parent.
*/
QPrintDialog::QPrintDialog(QWidget *parent)
- : QAbstractPrintDialog(*(new QPrintDialogPrivate), 0, parent)
+ : QAbstractPrintDialog(*(new QPrintDialogPrivate), nullptr, parent)
{
Q_D(QPrintDialog);
d->init();
@@ -774,7 +774,7 @@ void QPrintDialog::accept()
/*! \internal
*/
QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p, QPrinter *prn)
- : parent(p), propertiesDialog(0), printer(prn), optionsPane(0),
+ : parent(p), propertiesDialog(nullptr), printer(prn), optionsPane(0),
filePrintersAdded(false), propertiesDialogShown(false)
{
q = 0;
@@ -791,7 +791,9 @@ QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p, QPrinter *
widget.printers->addItems(printers);
- const int idx = printers.indexOf(defaultPrinter);
+ const QString selectedPrinter = prn && !prn->printerName().isEmpty() ? prn->printerName() : defaultPrinter;
+ const int idx = printers.indexOf(selectedPrinter);
+
if (idx >= 0)
currentPrinterIndex = idx;
}
@@ -906,7 +908,7 @@ void QUnixPrintWidgetPrivate::_q_btnBrowseClicked()
QString filename = widget.filename->text();
#if QT_CONFIG(filedialog)
filename = QFileDialog::getSaveFileName(parent, QPrintDialog::tr("Print To File ..."), filename,
- QString(), 0, QFileDialog::DontConfirmOverwrite);
+ QString(), nullptr, QFileDialog::DontConfirmOverwrite);
#else
filename.clear();
#endif
@@ -971,8 +973,7 @@ bool QUnixPrintWidgetPrivate::checkFields()
void QUnixPrintWidgetPrivate::setupPrinterProperties()
{
- if (propertiesDialog)
- delete propertiesDialog;
+ delete propertiesDialog;
QPrinter::OutputFormat outputFormat;
QString printerName;
diff --git a/src/printsupport/dialogs/qprintpreviewdialog.cpp b/src/printsupport/dialogs/qprintpreviewdialog.cpp
index eada7968af..a4f721fbc8 100644
--- a/src/printsupport/dialogs/qprintpreviewdialog.cpp
+++ b/src/printsupport/dialogs/qprintpreviewdialog.cpp
@@ -79,7 +79,7 @@ class QPrintPreviewMainWindow : public QMainWindow
{
public:
QPrintPreviewMainWindow(QWidget *parent) : QMainWindow(parent) {}
- QMenu *createPopupMenu() override { return 0; }
+ QMenu *createPopupMenu() override { return nullptr; }
};
class ZoomFactorValidator : public QDoubleValidator
@@ -119,7 +119,7 @@ public:
: QLineEdit(parent)
{
setContextMenuPolicy(Qt::NoContextMenu);
- connect(this, SIGNAL(returnPressed()), SLOT(handleReturnPressed()));
+ connect(this, &LineEdit::returnPressed, this, &LineEdit::handleReturnPressed);
}
protected:
diff --git a/src/printsupport/kernel/qpaintengine_preview.cpp b/src/printsupport/kernel/qpaintengine_preview.cpp
index 4c00333097..7179249677 100644
--- a/src/printsupport/kernel/qpaintengine_preview.cpp
+++ b/src/printsupport/kernel/qpaintengine_preview.cpp
@@ -69,8 +69,8 @@ QPreviewPaintEngine::QPreviewPaintEngine()
: QPaintEngine(*(new QPreviewPaintEnginePrivate), PaintEngineFeatures(AllFeatures & ~ObjectBoundingModeGradients))
{
Q_D(QPreviewPaintEngine);
- d->proxy_print_engine = 0;
- d->proxy_paint_engine = 0;
+ d->proxy_print_engine = nullptr;
+ d->proxy_paint_engine = nullptr;
}
QPreviewPaintEngine::~QPreviewPaintEngine()
@@ -102,8 +102,8 @@ bool QPreviewPaintEngine::end()
Q_D(QPreviewPaintEngine);
delete d->painter;
- d->painter = 0;
- d->engine = 0;
+ d->painter = nullptr;
+ d->engine = nullptr;
d->state = QPrinter::Idle;
return true;
}
diff --git a/src/printsupport/kernel/qplatformprintersupport.cpp b/src/printsupport/kernel/qplatformprintersupport.cpp
index 388dd5ff8e..e12a292aec 100644
--- a/src/printsupport/kernel/qplatformprintersupport.cpp
+++ b/src/printsupport/kernel/qplatformprintersupport.cpp
@@ -70,12 +70,12 @@ QPlatformPrinterSupport::~QPlatformPrinterSupport()
QPrintEngine *QPlatformPrinterSupport::createNativePrintEngine(QPrinter::PrinterMode, const QString &)
{
- return 0;
+ return nullptr;
}
QPaintEngine *QPlatformPrinterSupport::createPaintEngine(QPrintEngine *, QPrinter::PrinterMode)
{
- return 0;
+ return nullptr;
}
QPrintDevice QPlatformPrinterSupport::createPrintDevice(QPlatformPrintDevice *device)
diff --git a/src/printsupport/kernel/qplatformprintplugin.cpp b/src/printsupport/kernel/qplatformprintplugin.cpp
index a80f369040..9a7656f7d6 100644
--- a/src/printsupport/kernel/qplatformprintplugin.cpp
+++ b/src/printsupport/kernel/qplatformprintplugin.cpp
@@ -60,12 +60,12 @@ QPlatformPrinterSupportPlugin::~QPlatformPrinterSupportPlugin()
{
}
-static QPlatformPrinterSupport *printerSupport = 0;
+static QPlatformPrinterSupport *printerSupport = nullptr;
static void cleanupPrinterSupport()
{
delete printerSupport;
- printerSupport = 0;
+ printerSupport = nullptr;
}
/*!
diff --git a/src/printsupport/kernel/qprintengine_pdf.cpp b/src/printsupport/kernel/qprintengine_pdf.cpp
index 080ff7ccf4..873e146eec 100644
--- a/src/printsupport/kernel/qprintengine_pdf.cpp
+++ b/src/printsupport/kernel/qprintengine_pdf.cpp
@@ -381,7 +381,7 @@ void QPdfPrintEnginePrivate::closePrintDevice()
#endif
fd = -1;
delete outDevice;
- outDevice = 0;
+ outDevice = nullptr;
}
}
diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp
index ba234b3aae..a943d24cb1 100644
--- a/src/printsupport/kernel/qprintengine_win.cpp
+++ b/src/printsupport/kernel/qprintengine_win.cpp
@@ -1499,7 +1499,7 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const
QList<QVariant> out;
const auto inputSlots = d->m_printDevice.supportedInputSlots();
out.reserve(inputSlots.size());
- for (const QPrint::InputSlot inputSlot : inputSlots)
+ for (const QPrint::InputSlot &inputSlot : inputSlots)
out << QVariant(inputSlot.id == QPrint::CustomInputSlot ? inputSlot.windowsId : int(inputSlot.id));
value = out;
break;
diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp
index dd0fa8639b..8a2cdcb34f 100644
--- a/src/printsupport/kernel/qprinter.cpp
+++ b/src/printsupport/kernel/qprinter.cpp
@@ -132,7 +132,7 @@ void QPrinterPrivate::initEngines(QPrinter::OutputFormat format, const QPrinterI
{
// Default to PdfFormat
outputFormat = QPrinter::PdfFormat;
- QPlatformPrinterSupport *ps = 0;
+ QPlatformPrinterSupport *ps = nullptr;
QString printerName;
// Only set NativeFormat if we have a valid plugin and printer to use
diff --git a/src/printsupport/widgets/qcupsjobwidget.cpp b/src/printsupport/widgets/qcupsjobwidget.cpp
index 5d026d4c3d..7525d7f1e1 100644
--- a/src/printsupport/widgets/qcupsjobwidget.cpp
+++ b/src/printsupport/widgets/qcupsjobwidget.cpp
@@ -102,7 +102,7 @@ void QCupsJobWidget::initJobHold()
m_ui.jobHoldComboBox->addItem(tr("Weekend (Saturday to Sunday)"), QVariant::fromValue(QCUPSSupport::Weekend));
m_ui.jobHoldComboBox->addItem(tr("Specific Time"), QVariant::fromValue(QCUPSSupport::SpecificTime));
- connect(m_ui.jobHoldComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(toggleJobHoldTime()));
+ connect(m_ui.jobHoldComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QCupsJobWidget::toggleJobHoldTime);
QCUPSSupport::JobHoldUntilWithTime jobHoldWithTime;
diff --git a/src/printsupport/widgets/qprintpreviewwidget.cpp b/src/printsupport/widgets/qprintpreviewwidget.cpp
index d036a4394a..92370be2bd 100644
--- a/src/printsupport/widgets/qprintpreviewwidget.cpp
+++ b/src/printsupport/widgets/qprintpreviewwidget.cpp
@@ -145,7 +145,7 @@ class GraphicsView : public QGraphicsView
{
Q_OBJECT
public:
- GraphicsView(QWidget* parent = 0)
+ GraphicsView(QWidget* parent = nullptr)
: QGraphicsView(parent)
{
#ifdef Q_OS_MAC
@@ -179,7 +179,7 @@ class QPrintPreviewWidgetPrivate : public QWidgetPrivate
Q_DECLARE_PUBLIC(QPrintPreviewWidget)
public:
QPrintPreviewWidgetPrivate()
- : scene(0), curPage(1),
+ : scene(nullptr), curPage(1),
viewMode(QPrintPreviewWidget::SinglePageView),
zoomMode(QPrintPreviewWidget::FitInView),
zoomFactor(1), initialized(false), fitting(true)
diff --git a/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc b/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc
index 87c1d0c69b..04ea30915d 100644
--- a/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc
+++ b/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc
@@ -49,14 +49,16 @@
****************************************************************************/
//! [0]
--no-sql-<driver> ... Disable SQL <driver> entirely.
--qt-sql-<driver> ... Enable a SQL <driver> in the Qt Library, by default
- none are turned on.
--plugin-sql-<driver> Enable SQL <driver> as a plugin to be linked to
- at run time.
-
- Possible values for <driver>:
- [ db2 ibase mysql oci odbc psql sqlite sqlite2 tds ]
+[...]
+
+Database options:
+
+ -sql-<driver> ........ Enable SQL <driver> plugin. Supported drivers:
+ db2 ibase mysql oci odbc psql sqlite2 sqlite tds
+ [all auto]
+ -sqlite .............. Select used sqlite3 [system/qt]
+
+[...]
//! [0]
@@ -70,9 +72,9 @@ END
//! [3]
-cd $QTDIR/qtbase/src/plugins/sqldrivers/mysql
-qmake "INCLUDEPATH+=/usr/local/include" "LIBS+=-L/usr/local/lib -lmysqlclient_r" mysql.pro
-make
+cd $QTDIR/qtbase/src/plugins/sqldrivers
+qmake -- MYSQL_PREFIX=/usr/local
+make sub-mysql
//! [3]
@@ -83,32 +85,30 @@ make install
//! [5]
-cd %QTDIR%\qtbase\src\plugins\sqldrivers\mysql
-qmake "INCLUDEPATH+=C:/MySQL/include" "LIBS+=C:/MYSQL/MySQL Server <version>/lib/opt/libmysql.lib" mysql.pro
-nmake
+cd %QTDIR%\qtbase\src\plugins\sqldrivers
+qmake -- MYSQL_INCDIR=C:/MySQL/include "MYSQL_LIBDIR=C:/MYSQL/MySQL Server <version>/lib/opt"
+nmake sub-mysql
//! [5]
//! [6]
-cd $QTDIR/qtbase/src/plugins/sqldrivers/oci
-qmake "INCLUDEPATH+=$ORACLE_HOME/rdbms/public $ORACLE_HOME/rdbms/demo" "LIBS+=-L$ORACLE_HOME/lib -lclntsh -lwtc9" oci.pro
-make
+cd $QTDIR/qtbase/src/plugins/sqldrivers
+qmake -- "OCI_INCDIR=$ORACLE_HOME/rdbms/public" OCI_LIBDIR=$ORACLE_HOME/lib "OCI_LIBS=-lclntsh -lwtc9"
+make sub-oci
//! [6]
//! [7]
-cd $QTDIR/qtbase/src/plugins/sqldrivers/oci
-qmake "INCLUDEPATH+=/usr/include/oracle/10.1.0.3/client/" "LIBS+=-L/usr/lib/oracle/10.1.0.3/client/lib -lclntsh" oci.pro
-make
+cd $QTDIR/qtbase/src/plugins/sqldrivers
+qmake -- OCI_INCDIR=/usr/include/oracle/10.1.0.3/client OCI_LIBDIR=/usr/lib/oracle/10.1.0.3/client/lib
+make sub-oci
//! [7]
//! [8]
-set INCLUDE=%INCLUDE%;c:\oracle\oci\include
-set LIB=%LIB%;c:\oracle\oci\lib\msvc
-cd %QTDIR%\qtbase\src\plugins\sqldrivers\oci
-qmake oci.pro
-nmake
+cd %QTDIR%\qtbase\src\plugins\sqldrivers
+qmake -- OCI_INCDIR=c:/oracle/oci/include OCI_LIBDIR=c:/oracle/oci/lib/msvc
+nmake sub-oci
//! [8]
@@ -118,128 +118,110 @@ set PATH=%PATH%;c:\oracle\bin
//! [11]
-cd $QTDIR/qtbase/src/plugins/sqldrivers/odbc
-qmake "INCLUDEPATH+=/usr/local/unixODBC/include" "LIBS+=-L/usr/local/unixODBC/lib -lodbc"
-make
+cd $QTDIR/qtbase/src/plugins/sqldrivers
+qmake -- ODBC_PREFIX=/usr/local/unixODBC
+make sub-odbc
//! [11]
//! [12]
-cd %QTDIR%\qtbase\src\plugins\sqldrivers\odbc
-qmake odbc.pro
-nmake
+cd %QTDIR%\qtbase\src\plugins\sqldrivers
+qmake
+nmake sub-odbc
//! [12]
//! [13]
-cd $QTDIR/qtbase/src/plugins/sqldrivers/psql
-qmake "INCLUDEPATH+=/usr/include/pgsql" "LIBS+=-L/usr/lib -lpq" psql.pro
-make
+cd $QTDIR/qtbase/src/plugins/sqldrivers
+qmake -- PSQL_INCDIR=/usr/include/pgsql
+make sub-psql
//! [13]
-//! [14]
-cd $QTDIR/qtbase/src/plugins/sqldrivers/psql
-make install
-//! [14]
-
-
//! [15]
-cd %QTDIR%\qtbase\src\plugins\sqldrivers\psql
-qmake "INCLUDEPATH+=C:/psql/include" "LIBS+=C:/psql/lib/ms/libpq.lib" psql.pro
-nmake
+cd %QTDIR%\qtbase\src\plugins\sqldrivers
+qmake -- PSQL_INCDIR=C:/psql/include PSQL_LIBDIR=C:/psql/lib/ms
+nmake sub-psql
//! [15]
//! [16]
-cd $QTDIR/qtbase/src/plugins/sqldrivers/tds
-qmake "INCLUDEPATH=$SYBASE/include" "LIBS=-L$SYBASE/lib -lsybdb"
-make
+cd $QTDIR/qtbase/src/plugins/sqldrivers
+qmake -- TDS_PREFIX=$SYBASE
+make sub-tds
//! [16]
//! [17]
-cd %QTDIR%\qtbase\src\plugins\sqldrivers\tds
-qmake "LIBS+=NTWDBLIB.LIB" tds.pro
-nmake
+cd %QTDIR%\qtbase\src\plugins\sqldrivers
+qmake
+nmake sub-tds
//! [17]
//! [18]
-cd $QTDIR/qtbase/src/plugins/sqldrivers/db2
-qmake "INCLUDEPATH+=$DB2DIR/include" "LIBS+=-L$DB2DIR/lib -ldb2"
-make
+cd $QTDIR/qtbase/src/plugins/sqldrivers
+qmake -- DB2_PREFIX=$DB2DIR
+make sub-db2
//! [18]
-//! [19]
-cd $QTDIR/qtbase/src/plugins/sqldrivers/db2
-make install
-//! [19]
-
-
//! [20]
-cd %QTDIR%\qtbase\src\plugins\sqldrivers\db2
-qmake "INCLUDEPATH+=<DB2 home>/sqllib/include" "LIBS+=<DB2 home>/sqllib/lib/db2cli.lib"
-nmake
+cd %QTDIR%\qtbase\src\plugins\sqldrivers
+qmake -- "DB2_PREFIX=<DB2 home>/sqllib"
+nmake sub-db2
//! [20]
//! [21]
-cd $QTDIR/qtbase/src/plugins/sqldrivers/sqlite
-qmake "INCLUDEPATH+=$SQLITE/include" "LIBS+=-L$SQLITE/lib -lsqlite"
-make
+cd $QTDIR/qtbase/src/plugins/sqldrivers
+qmake -- -system-sqlite SQLITE3_PREFIX=$SQLITE
+make sub-sqlite
//! [21]
-//! [22]
-cd $QTDIR/qtbase/src/plugins/sqldrivers/sqlite
-make install
-//! [22]
-
-
//! [23]
-cd %QTDIR%\qtbase\src\plugins\sqldrivers\sqlite
-qmake "INCLUDEPATH+=C:/SQLITE/INCLUDE" "LIBS+=C:/SQLITE/LIB/SQLITE3.LIB" sqlite.pro
-nmake
+cd %QTDIR%\qtbase\src\plugins\sqldrivers
+qmake -- -system-sqlite SQLITE3_PREFIX=C:/SQLITE
+nmake sub-sqlite
//! [23]
//! [27]
-cd $QTDIR/qtbase/src/plugins/sqldrivers/ibase
-qmake "INCLUDEPATH+=/opt/interbase/include" "LIBS+=-L/opt/interbase/lib" ibase.pro
-make
+cd $QTDIR/qtbase/src/plugins/sqldrivers
+qmake -- IBASE_PREFIX=/opt/interbase
+make sub-ibase
//! [27]
//! [28]
-cd $QTDIR/qtbase/src/plugins/sqldrivers/ibase
-qmake "INCLUDEPATH+=/opt/interbase/include" "LIBS+=-L/opt/interbase/lib -lfbclient" ibase.pro
-make
+cd $QTDIR/qtbase/src/plugins/sqldrivers
+qmake -- IBASE_PREFIX=/opt/interbase IBASE_LIBS=-lfbclient
+make sub-ibase
//! [28]
//! [29]
-cd %QTDIR%\qtbase\src\plugins\sqldrivers\ibase
-qmake "INCLUDEPATH+=C:/interbase/include" ibase.pro
-nmake
+cd %QTDIR%\qtbase\src\plugins\sqldrivers
+qmake -- IBASE_INCDIR=C:/interbase/include
+nmake sub-ibase
//! [29]
//! [30]
-cd %QTDIR%\qtbase\src\plugins\sqldrivers\ibase
-qmake "INCLUDEPATH+=C:/interbase/include" "LIBS+=-lfbclient" ibase.pro
-nmake
+cd %QTDIR%\qtbase\src\plugins\sqldrivers
+qmake -- IBASE_INCDIR=C:/interbase/include IBASE_LIBS=-lfbclient
+nmake sub-ibase
//! [30]
//! [32]
-configure -I /usr/include/oracle/10.1.0.3/client -L /usr/lib/oracle/10.1.0.3/client/lib -R /usr/lib/oracle/10.1.0.3/client/lib -lclntsh -lnnz10
+configure OCI_INCDIR=/usr/include/oracle/10.1.0.3/client OCI_LIBDIR=/usr/lib/oracle/10.1.0.3/client/lib -R /usr/lib/oracle/10.1.0.3/client/lib "OCI_LIBS=-lclntsh -lnnz10"
make
//! [32]
//! [33]
-cd $QTDIR/qtbase/src/plugins/sqldrivers/oci
-qmake "INCLUDEPATH+=/usr/include/oracle/10.1.0.3/client" "LIBS+=-L/usr/lib/oracle/10.1.0.3/client/lib -Wl,-rpath,/usr/lib/oracle/10.1.0.3/client/lib -lclntsh -lnnz10" oci.pro
-make
+cd $QTDIR/qtbase/src/plugins/sqldrivers
+qmake -- OCI_INCDIR=/usr/include/oracle/10.1.0.3/client OCI_LIBDIR=/usr/lib/oracle/10.1.0.3/client/lib "OCI_LIBS=-Wl,-rpath,/usr/lib/oracle/10.1.0.3/client/lib -lclntsh -lnnz10"
+make sub-oci
//! [33]
diff --git a/src/sql/doc/src/sql-driver.qdoc b/src/sql/doc/src/sql-driver.qdoc
index 2811230106..025cd43ef7 100644
--- a/src/sql/doc/src/sql-driver.qdoc
+++ b/src/sql/doc/src/sql-driver.qdoc
@@ -34,7 +34,7 @@
Plugins}{plugins} to communicate with the different database
APIs. Since Qt's SQL Module API is database-independent, all
database-specific code is contained within these drivers. Several
- drivers are supplied with Qt and other drivers can be added. The
+ drivers are supplied with Qt, and other drivers can be added. The
driver source code is supplied and can be used as a model for
\l{#development}{writing your own drivers}.
@@ -42,9 +42,7 @@
\section1 Supported Databases
- The table below lists the drivers included with Qt. Due to
- license incompatibilities with the GPL, not all of the plugins
- are provided with Open Source Versions of Qt.
+ The table below lists the drivers included with Qt:
\table
\header \li Driver name \li DBMS
@@ -74,10 +72,14 @@
libraries", and these are what you need. These libraries are responsible
for the low-level communication with the DBMS.
+ \note When using Qt under Open Source terms but with a proprietary
+ database, verify the client library's license compatibility with
+ the LGPL.
+
\target building
- \section1 Building the Drivers Using Configure
+ \section1 Building the Drivers
- On Unix and \macos, the Qt \c configure script tries to
+ The Qt \c configure script tries to
automatically detect the available client libraries on your
machine. Run \c{configure -help} to see what drivers can be
built. You should get an output similar to this:
@@ -86,23 +88,28 @@
The \c configure script cannot detect the necessary libraries
and include files if they are not in the standard paths, so it
- may be necessary to specify these paths using the \c -I and \c -L
- command-line options. For example, if your MySQL include files
- are installed in \c /usr/local/mysql (or in \c{C:\mysql\include}
- on Windows), then pass the following parameter to configure: \c
- -I/usr/local/mysql (or \c{-I C:\mysql\include} for Windows).
-
- On Windows, the \c -I parameter doesn't accept spaces in
- filenames, so use the 8.3 name instead; for example, use
- \c{C:\progra~1\mysql} instead of \c{C:\Program Files\mysql}.
+ may be necessary to specify these paths using the \c *_INCDIR=,
+ \c *_LIBDIR=, or \c *_PREFIX= command-line options. For example,
+ if your MySQL files are installed in \c /usr/local/mysql (or in
+ \c{C:\mysql} on Windows), then pass the following parameter to
+ configure: \c MYSQL_PREFIX=/usr/local/mysql
+ (or \c{MYSQL_PREFIX=C:\mysql} for Windows).
+ The particulars for each driver are explained below.
+
+ Due to the practicalities of dealing with external dependencies,
+ only the SQLite3 plugin is shipped with binary builds of Qt.
+ To be able to add additional drivers to the Qt installation
+ without re-building all of Qt, it is possible to configure
+ and build the \c qtbase/src/plugins/sqldrivers directory outside
+ of a full Qt build directory. Note that it is not possible to
+ \e configure each driver separately, only all of them at once.
+ Drivers can be \e built separately, though.
+ If the Qt build is configured with \c{-prefix}, it is necessary to
+ install the plugins after building them, too. For example:
- Use the \c{-qt-sql-<driver>} parameter to build the database driver
- statically into your Qt library or \c{-plugin-sql-<driver>} to build
- the driver as a plugin. Look at the sections that follow for
- additional information about required libraries.
+ \snippet code/doc_src_sql-driver.qdoc 4
- \target buildingmanually
- \section1 Building the Plugins Manually
+ \section1 Driver Specifics
\target QMYSQL
\section2 QMYSQL for MySQL 4 and higher
@@ -132,9 +139,8 @@
not required to use MySQL functionality.
To use the embedded MySQL server, simply link the Qt plugin to \c
- libmysqld instead of libmysqlclient. This can be done by replacing
- \c -lmysqlclient_r by \c -lmysqld in the \c qmake command in the
- section below.
+ libmysqld instead of \c libmysqlclient. This can be done by adding
+ \c MYSQL_LIBS=-lmysqld to the configure command line.
Please refer to the MySQL documentation, chapter "libmysqld, the Embedded
MySQL Server Library" for more information about the MySQL embedded server.
@@ -151,11 +157,6 @@
\snippet code/doc_src_sql-driver.qdoc 3
- After installing Qt, you also need to install the plugin in the standard
- location:
-
- \snippet code/doc_src_sql-driver.qdoc 4
-
\section3 How to Build the QMYSQL Plugin on Windows
You need to get the MySQL installation files. Run \c SETUP.EXE and
@@ -166,18 +167,11 @@
\snippet code/doc_src_sql-driver.qdoc 5
If you are not using a Microsoft compiler, replace \c nmake with \c
- make in the line above.
-
- \note Including \c{"-o Makefile"} as an argument to \l qmake, to
- tell it where to build the makefile, can cause the plugin to be
- built in release mode only. If you intend to build a debug version
- as well, don't use the \c{"-o Makefile"} option.
+ mingw32-make in the line above.
\target QOCI
\section2 QOCI for the Oracle Call Interface (OCI)
- \section3 General Information about the OCI plugin
-
The Qt OCI plugin supports Oracle 9i, 10g and higher. After
connecting to the Oracle server, the plugin will auto-detect the
database version and enable features accordingly.
@@ -252,7 +246,7 @@
\snippet code/doc_src_sql-driver.qdoc 8
If you are not using a Microsoft compiler, replace \c nmake with \c
- make in the line above.
+ mingw32-make in the line above.
When you run your application, you will also need to add the \c oci.dll
path to your \c PATH environment variable:
@@ -262,8 +256,6 @@
\target QODBC
\section2 QODBC for Open Database Connectivity (ODBC)
- \section3 General Information about the ODBC plugin
-
ODBC is a general interface that allows you to connect to multiple
DBMSs using a common interface. The QODBC driver allows you to connect
to an ODBC driver manager and access the available data sources. Note
@@ -277,7 +269,7 @@
On Windows, an ODBC driver manager should be installed by default.
For Unix systems, there are some implementations which must be
- installed first. Note that every client that uses your application is
+ installed first. Note that every end user of your application is
required to have an ODBC driver manager installed, otherwise the
QODBC plugin will not work.
@@ -290,7 +282,7 @@
but do not offer all the necessary functionality. The QODBC plugin
therefore checks whether the data source can be used after a
connection has been established, and refuses to work if the check
- fails. If you don't like this behavior, you can remove the \c{#define
+ fails. If you do not like this behavior, you can remove the \c{#define
ODBC_CHECK_DRIVER} line from the file \c{qsql_odbc.cpp}. Do this at
your own risk!
@@ -310,7 +302,7 @@
If you experience very slow access of the ODBC datasource, make sure
that ODBC call tracing is turned off in the ODBC datasource manager.
- Some drivers don't support scrollable cursors. In that case case only
+ Some drivers do not support scrollable cursors. In that case, only
queries in forwardOnly mode can be used successfully.
\section3 ODBC Stored Procedure Support
@@ -331,7 +323,7 @@
Windows NT based systems, this is the default. Note that the ODBC
driver and the DBMS must also support Unicode.
- Some driver managers and drivers don't support UNICODE. To use the
+ Some driver managers and drivers do not support UNICODE. To use the
QODBC plugin with such drivers, it has to be compiled with
Q_ODBC_VERSION_2 defined.
@@ -359,18 +351,12 @@
\snippet code/doc_src_sql-driver.qdoc 12
If you are not using a Microsoft compiler, replace \c nmake with \c
- make in the line above.
+ mingw32-make in the line above.
\target QPSQL
\section2 QPSQL for PostgreSQL (Version 7.3 and Above)
- \section3 General Information about the QPSQL driver
-
The QPSQL driver supports version 7.3 and higher of the PostgreSQL server.
- We recommend that you use a client library from version 7.3.15, 7.4.13,
- 8.0.8, 8.1.4, or more recent, as these versions contain security fixes, and
- as the QPSQL driver might not build with older versions of the client
- library, depending on your platform.
For more information about PostgreSQL visit \l http://www.postgresql.org.
@@ -404,11 +390,6 @@
\snippet code/doc_src_sql-driver.qdoc 13
- After installing Qt, you also need to install the plugin in the standard
- location:
-
- \snippet code/doc_src_sql-driver.qdoc 14
-
\section3 How to Build the QPSQL Plugin on Windows
Install the appropriate PostgreSQL developer libraries for your
@@ -426,8 +407,6 @@
\note TDS is no longer used by MS Sql Server, and is superceded by
\l{QODBC}{ODBC}. QTDS is obsolete from Qt 4.7.
- \section3 General Information about QTDS
-
It is not possible to set the port with QSqlDatabase::setPort() due to limitations in the
Sybase client library. Refer to the Sybase documentation for information on how to set up
a Sybase client configuration file to enable connections to databases on non-default ports.
@@ -438,12 +417,9 @@
\list
\li FreeTDS, a free implementation of the TDS protocol
- (\l{http://www.freetds.org}). Note that FreeTDS is not yet stable,
- so some functionality may not work as expected.
+ (\l{http://www.freetds.org}).
- \li Sybase Open Client, available from \l{http://www.sybase.com}.
- Note for Linux users: Get the Open Client RPM from
- \l{http://linux.sybase.com}.
+ \li Sybase Open Client, available from \l{https://support.sap.com}.
\endlist
Regardless of which library you use, the shared object file
@@ -456,22 +432,21 @@
\section3 How to Build the QDTS Plugin on Windows
You can either use the DB-Library supplied by Microsoft or the Sybase
- Open Client (\l{http://www.sybase.com}). You must include \c
+ Open Client (\l{https://support.sap.com}). Configure will try to find
NTWDBLIB.LIB to build the plugin:
\snippet code/doc_src_sql-driver.qdoc 17
- By default the Microsoft library is used on Windows, if you want to
+ By default, the Microsoft library is used on Windows. If you want to
force the use of the Sybase Open Client, you must define \c
- Q_USE_SYBASE in \c{%QTDIR%\qtbase\src\sql\drivers\tds\qsql_tds.cpp}. If you
- are not using a Microsoft compiler, replace \c nmake with \c make in
- the line above.
+ Q_USE_SYBASE in \c{%QTDIR%\qtbase\src\plugins\sqldrivers\tds\qsql_tds.cpp}.
+
+ If you are not using a Microsoft compiler, replace \c nmake
+ with \c mingw32-make in the line above.
\target QDB2
\section2 QDB2 for IBM DB2 (Version 7.1 and Above)
- \section3 General Information about QDB2
-
The Qt DB2 plugin makes it possible to access IBM DB2 databases. It
has been tested with IBM DB2 v7.1 and 7.2. You must install the IBM
DB2 development client library, which contains the header and library
@@ -487,11 +462,6 @@
\snippet code/doc_src_sql-driver.qdoc 18
- After installing Qt, you also need to install the plugin in the standard
- location:
-
- \snippet code/doc_src_sql-driver.qdoc 19
-
\section3 How to Build the QDB2 Plugin on Windows
The DB2 header and include files should already be installed in the
@@ -500,7 +470,7 @@
\snippet code/doc_src_sql-driver.qdoc 20
If you are not using a Microsoft compiler, replace \c nmake
- with \c make in the line above.
+ with \c mingw32-make in the line above.
\target QSQLITE2
\section2 QSQLITE2 for SQLite Version 2
@@ -512,8 +482,6 @@
\target QSQLITE
\section2 QSQLITE for SQLite (Version 3 and Above)
- \section3 General Information about QSQLITE
-
The Qt SQLite plugin makes it possible to access SQLite
databases. SQLite is an in-process database, which means that it
is not necessary to have a database server. SQLite operates on a
@@ -548,21 +516,19 @@
\section3 How to Build the QSQLITE Plugin
SQLite version 3 is included as a third-party library within Qt.
- It can be built by passing the following parameters to the
- configure script: \c{-plugin-sql-sqlite} (build as a plugin) or
- \c{-qt-sql-sqlite} (linked directly into the Qt library).
-
- If you don't want to use the SQLite library included with Qt, you
- can pass \c{-system-sqlite} to the configure script to use sqlite
- libraries in the operating system. Alternatively, you can build
- it manually (replace \c $SQLITE with the directory where
- SQLite resides):
+ It can be built by passing the \c{-qt-sqlite} parameter to the
+ configure script.
- \snippet code/doc_src_sql-driver.qdoc 21
+ If you do not want to use the SQLite library included with Qt, you
+ can pass \c{-system-sqlite} to the configure script to use the SQLite
+ libraries of the operating system. This is recommended whenever possible,
+ as it reduces the installation size and removes one component for which
+ you need to track security advisories.
- After installing Qt, you also need to install the plugin in the standard location:
+ On Unix and \macos (replace \c $SQLITE with the directory where
+ SQLite resides):
- \snippet code/doc_src_sql-driver.qdoc 22
+ \snippet code/doc_src_sql-driver.qdoc 21
On Windows:
@@ -604,8 +570,6 @@
\target QIBASE
\section2 QIBASE for Borland InterBase
- \section3 General Information about QIBASE
-
The Qt InterBase plugin makes it possible to access the InterBase and
Firebird databases. InterBase can either be used as a client/server or
without a server in which case it operates on local files. The
@@ -633,7 +597,7 @@
\snippet code/doc_src_sql-driver.cpp 25
- If Qt doesn't support the given text encoding the driver will issue a
+ If Qt does not support the given text encoding the driver will issue a
warning message and connect to the database using UNICODE_FSS.
Note that if the text encoding set when connecting to the database is
@@ -674,7 +638,7 @@
\snippet code/doc_src_sql-driver.qdoc 30
If you are not using a Microsoft compiler, replace \c nmake
- with \c make in the line above.
+ with \c mingw32-make in the line above.
Note that \c{C:\interbase\bin} must be in the \c PATH.
@@ -694,14 +658,12 @@
make sure that the following requirements are met:
\list
- \li Ensure that you are using a shared Qt library; you cannot use the
- plugins with a static build.
\li Ensure that the plugin is in the correct directory. You can use
QApplication::libraryPaths() to determine where Qt looks for plugins.
\li Ensure that the client libraries of the DBMS are available on the
system. On Unix, run the command \c{ldd} and pass the name of the
plugin as parameter, for example \c{ldd libqsqlmysql.so}. You will
- get a warning if any of the client libraries couldn't be found.
+ get a warning if any of the client libraries could not be found.
On Windows, you can use Visual Studio's dependency walker. With
Qt Creator, you can update the \c PATH environment variable in the
\gui Run section of the \gui Project panel to include the path to
@@ -711,12 +673,6 @@
\endlist
Make sure you have followed the guide to \l{Deploying Plugins}.
- If you experience plugin load problems and see output like this:
-
- \snippet code/doc_src_sql-driver.cpp 31
-
- the problem is usually that the plugin had the wrong build key.
- This might require removing an entry from the plugin cache.
\target development
\section1 How to Write Your Own Database Driver
@@ -753,7 +709,7 @@
must use the Q_PLUGIN_METADATA() macro. Read \l{How to Create Qt
Plugins} for more information on this. You can also check out how
this is done in the SQL plugins that are provided with Qt in
- \c{QTDIR/qtbase/src/plugins/sqldrivers} and \c{QTDIR/qtbase/src/sql/drivers}.
+ \c{QTDIR/qtbase/src/plugins/sqldrivers}.
The following code can be used as a skeleton for a SQL driver:
diff --git a/src/sql/kernel/qsqlfield.cpp b/src/sql/kernel/qsqlfield.cpp
index 59b992e803..a258d44df7 100644
--- a/src/sql/kernel/qsqlfield.cpp
+++ b/src/sql/kernel/qsqlfield.cpp
@@ -155,6 +155,19 @@ public:
*/
/*!
+ Constructs an empty field called \a fieldName of variant type \a type.
+
+ \sa setRequiredStatus(), setLength(), setPrecision(), setDefaultValue(),
+ setGenerated(), setReadOnly()
+*/
+QSqlField::QSqlField(const QString &fieldName, QVariant::Type type)
+{
+ d = new QSqlFieldPrivate(fieldName, type, QString());
+ val = QVariant(type);
+}
+
+/*!
+ \overload
Constructs an empty field called \a fieldName of variant type \a
type in \a table.
diff --git a/src/sql/kernel/qsqlfield.h b/src/sql/kernel/qsqlfield.h
index 30474735f4..8650ba8715 100644
--- a/src/sql/kernel/qsqlfield.h
+++ b/src/sql/kernel/qsqlfield.h
@@ -55,8 +55,9 @@ public:
enum RequiredStatus { Unknown = -1, Optional = 0, Required = 1 };
explicit QSqlField(const QString& fieldName = QString(),
- QVariant::Type type = QVariant::Invalid,
- const QString &tableName = QString());
+ QVariant::Type type = QVariant::Invalid);
+ QSqlField(const QString &fieldName, QVariant::Type type,
+ const QString &tableName);
QSqlField(const QSqlField& other);
QSqlField& operator=(const QSqlField& other);
diff --git a/src/sql/kernel/qsqlquery.cpp b/src/sql/kernel/qsqlquery.cpp
index f9cc07daa1..b89d20976f 100644
--- a/src/sql/kernel/qsqlquery.cpp
+++ b/src/sql/kernel/qsqlquery.cpp
@@ -649,11 +649,10 @@ bool QSqlQuery::next()
{
if (!isSelect() || !isActive())
return false;
- bool b = false;
+
switch (at()) {
case QSql::BeforeFirstRow:
- b = d->sqlResult->fetchFirst();
- return b;
+ return d->sqlResult->fetchFirst();
case QSql::AfterLastRow:
return false;
default:
@@ -703,13 +702,11 @@ bool QSqlQuery::previous()
return false;
}
- bool b = false;
switch (at()) {
case QSql::BeforeFirstRow:
return false;
case QSql::AfterLastRow:
- b = d->sqlResult->fetchLast();
- return b;
+ return d->sqlResult->fetchLast();
default:
if (!d->sqlResult->fetchPrevious()) {
d->sqlResult->setAt(QSql::BeforeFirstRow);
@@ -737,9 +734,7 @@ bool QSqlQuery::first()
qWarning("QSqlQuery::seek: cannot seek backwards in a forward only query");
return false;
}
- bool b = false;
- b = d->sqlResult->fetchFirst();
- return b;
+ return d->sqlResult->fetchFirst();
}
/*!
@@ -758,9 +753,7 @@ bool QSqlQuery::last()
{
if (!isSelect() || !isActive())
return false;
- bool b = false;
- b = d->sqlResult->fetchLast();
- return b;
+ return d->sqlResult->fetchLast();
}
/*!
diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp
index 075285e4ea..ba559b572f 100644
--- a/src/tools/moc/main.cpp
+++ b/src/tools/moc/main.cpp
@@ -486,8 +486,8 @@ int runMoc(int argc, char **argv)
// 3. and output meta object code
if (output.size()) { // output file specified
-#if defined(_MSC_VER) && _MSC_VER >= 1400
- if (fopen_s(&out, QFile::encodeName(output).constData(), "w"))
+#if defined(_MSC_VER)
+ if (_wfopen_s(&out, reinterpret_cast<const wchar_t *>(output.utf16()), L"w") != 0)
#else
out = fopen(QFile::encodeName(output).constData(), "w"); // create output file
if (!out)
diff --git a/src/tools/qlalr/examples/qparser/calc.l b/src/tools/qlalr/examples/qparser/calc.l
index e619e34dab..fe542680a8 100644
--- a/src/tools/qlalr/examples/qparser/calc.l
+++ b/src/tools/qlalr/examples/qparser/calc.l
@@ -33,6 +33,9 @@
#include "calc_parser.h"
#include <cstdlib>
+// Work around flex bug
+#include <unistd.h>
+
#define YY_DECL int CalcParser::nextToken()
%}
diff --git a/src/widgets/dialogs/qfileinfogatherer.cpp b/src/widgets/dialogs/qfileinfogatherer.cpp
index 710ee611b9..aef13a563f 100644
--- a/src/widgets/dialogs/qfileinfogatherer.cpp
+++ b/src/widgets/dialogs/qfileinfogatherer.cpp
@@ -196,7 +196,7 @@ void QFileInfoGatherer::fetchExtendedInformation(const QString &path, const QStr
*/
void QFileInfoGatherer::updateFile(const QString &filePath)
{
- QString dir = filePath.mid(0, filePath.lastIndexOf(QDir::separator()));
+ QString dir = filePath.mid(0, filePath.lastIndexOf(QLatin1Char('/')));
QString fileName = filePath.mid(dir.length() + 1);
fetchExtendedInformation(dir, QStringList(fileName));
}
@@ -267,19 +267,19 @@ QExtendedInformation QFileInfoGatherer::getInfo(const QFileInfo &fileInfo) const
info.icon = m_iconProvider->icon(fileInfo);
info.displayType = m_iconProvider->type(fileInfo);
#ifndef QT_NO_FILESYSTEMWATCHER
- // ### Not ready to listen all modifications
- #if 0
- // Enable the next two commented out lines to get updates when the file sizes change...
+ // ### Not ready to listen all modifications by default
+ static const bool watchFiles = qEnvironmentVariableIsSet("QT_FILESYSTEMMODEL_WATCH_FILES");
+ if (watchFiles) {
if (!fileInfo.exists() && !fileInfo.isSymLink()) {
- info.size = -1;
- //watcher->removePath(fileInfo.absoluteFilePath());
+ watcher->removePath(fileInfo.absoluteFilePath());
} else {
- if (!fileInfo.absoluteFilePath().isEmpty() && fileInfo.exists() && fileInfo.isReadable()
- && !watcher->files().contains(fileInfo.absoluteFilePath())) {
- //watcher->addPath(fileInfo.absoluteFilePath());
+ const QString path = fileInfo.absoluteFilePath();
+ if (!path.isEmpty() && fileInfo.exists() && fileInfo.isFile() && fileInfo.isReadable()
+ && !watcher->files().contains(path)) {
+ watcher->addPath(path);
}
}
- #endif
+ }
#endif
#ifdef Q_OS_WIN
@@ -329,14 +329,15 @@ void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &fil
QVector<QPair<QString, QFileInfo> > updatedFiles;
QStringList filesToCheck = files;
- QString itPath = QDir::fromNativeSeparators(files.isEmpty() ? path : QLatin1String(""));
- QDirIterator dirIt(itPath, QDir::AllEntries | QDir::System | QDir::Hidden);
QStringList allFiles;
- while (!abort.load() && dirIt.hasNext()) {
- dirIt.next();
- fileInfo = dirIt.fileInfo();
- allFiles.append(fileInfo.fileName());
- fetch(fileInfo, base, firstTime, updatedFiles, path);
+ if (files.isEmpty()) {
+ QDirIterator dirIt(path, QDir::AllEntries | QDir::System | QDir::Hidden);
+ while (!abort.load() && dirIt.hasNext()) {
+ dirIt.next();
+ fileInfo = dirIt.fileInfo();
+ allFiles.append(fileInfo.fileName());
+ fetch(fileInfo, base, firstTime, updatedFiles, path);
+ }
}
if (!allFiles.isEmpty())
emit newListOfFiles(path, allFiles);
diff --git a/src/widgets/dialogs/qfileinfogatherer_p.h b/src/widgets/dialogs/qfileinfogatherer_p.h
index 1e97cc3558..bb13d4eb01 100644
--- a/src/widgets/dialogs/qfileinfogatherer_p.h
+++ b/src/widgets/dialogs/qfileinfogatherer_p.h
@@ -84,7 +84,8 @@ public:
bool operator ==(const QExtendedInformation &fileInfo) const {
return mFileInfo == fileInfo.mFileInfo
&& displayType == fileInfo.displayType
- && permissions() == fileInfo.permissions();
+ && permissions() == fileInfo.permissions()
+ && lastModified() == fileInfo.lastModified();
}
#ifndef QT_NO_FSFILEENGINE
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index f88ac71cf3..2b79831a74 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -260,7 +260,10 @@ QModelIndex QFileSystemModel::index(int row, int column, const QModelIndex &pare
Q_ASSERT(parentNode);
// now get the internal pointer for the index
- const QString &childName = parentNode->visibleChildren.at(d->translateVisibleLocation(parentNode, row));
+ const int i = d->translateVisibleLocation(parentNode, row);
+ if (i >= parentNode->visibleChildren.size())
+ return QModelIndex();
+ const QString &childName = parentNode->visibleChildren.at(i);
const QFileSystemModelPrivate::QFileSystemNode *indexNode = parentNode->children.value(childName);
Q_ASSERT(indexNode);
@@ -744,7 +747,7 @@ QVariant QFileSystemModel::data(const QModelIndex &index, int role) const
break;
case Qt::TextAlignmentRole:
if (index.column() == 1)
- return Qt::AlignRight;
+ return QVariant(Qt::AlignTrailing | Qt::AlignVCenter);
break;
case FilePermissions:
int p = permissions(index);
diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp
index 6ca4541980..e7b4870e35 100644
--- a/src/widgets/dialogs/qwizard_win.cpp
+++ b/src/widgets/dialogs/qwizard_win.cpp
@@ -260,7 +260,7 @@ static bool getCaptionQFont(int dpi, QFont *result)
QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface();
return ni && QMetaObject::invokeMethod(ni, "logFontToQFont", Qt::DirectConnection,
Q_RETURN_ARG(QFont, *result),
- Q_ARG(const void *, &logFont),
+ Q_ARG(const void*, &logFont),
Q_ARG(int, dpi));
}
diff --git a/src/widgets/doc/qtwidgets.qdocconf b/src/widgets/doc/qtwidgets.qdocconf
index a49eb439af..88957b0f94 100644
--- a/src/widgets/doc/qtwidgets.qdocconf
+++ b/src/widgets/doc/qtwidgets.qdocconf
@@ -48,4 +48,6 @@ imagedirs += images \
navigation.landingpage = "Qt Widgets"
navigation.cppclassespage = "Qt Widgets C++ Classes"
manifestmeta.highlighted.names = "QtWidgets/Calendar Widget Example" \
- "QtWidgets/Simple Tree Model Example"
+ "QtWidgets/Editable Tree Model Example" \
+ "QtWidgets/Address Book Example" \
+ "QtWidgets/Application Example"
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index abd5997ea1..3555c276ac 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -2331,18 +2331,20 @@ void QHeaderView::paintEvent(QPaintEvent *e)
d->prepareSectionSelected(); // clear and resize the bit array
QRect currentSectionRect;
- int logical;
const int width = d->viewport->width();
const int height = d->viewport->height();
+ const int rtlHorizontalOffset = d->reverse() ? 1 : 0;
for (int i = start; i <= end; ++i) {
if (d->isVisualIndexHidden(i))
continue;
painter.save();
- logical = logicalIndex(i);
+ const int logical = logicalIndex(i);
if (d->orientation == Qt::Horizontal) {
- currentSectionRect.setRect(sectionViewportPosition(logical), 0, sectionSize(logical), height);
+ currentSectionRect.setRect(sectionViewportPosition(logical) + rtlHorizontalOffset,
+ 0, sectionSize(logical), height);
} else {
- currentSectionRect.setRect(0, sectionViewportPosition(logical), width, sectionSize(logical));
+ currentSectionRect.setRect(0, sectionViewportPosition(logical),
+ width, sectionSize(logical));
}
currentSectionRect.translate(offset);
@@ -2800,9 +2802,9 @@ void QHeaderView::paintSection(QPainter *painter, const QRect &rect, int logical
if (first && last)
opt.position = QStyleOptionHeader::OnlyOneSection;
else if (first)
- opt.position = QStyleOptionHeader::Beginning;
+ opt.position = d->reverse() ? QStyleOptionHeader::End : QStyleOptionHeader::Beginning;
else if (last)
- opt.position = QStyleOptionHeader::End;
+ opt.position = d->reverse() ? QStyleOptionHeader::Beginning : QStyleOptionHeader::End;
else
opt.position = QStyleOptionHeader::Middle;
opt.orientation = d->orientation;
@@ -3181,6 +3183,15 @@ void QHeaderViewPrivate::setupSectionIndicator(int section, int position)
QRect rect(0, 0, w, h);
QPainter painter(&pm);
+ const QVariant variant = model->headerData(section, orientation,
+ Qt::FontRole);
+ if (variant.isValid() && variant.canConvert<QFont>()) {
+ const QFont sectionFont = qvariant_cast<QFont>(variant);
+ painter.setFont(sectionFont);
+ } else {
+ painter.setFont(q->font());
+ }
+
painter.setOpacity(0.75);
q->paintSection(&painter, rect, section);
painter.end();
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 6ea180dcf2..03e0441390 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -237,9 +237,6 @@ void QTreeView::setModel(QAbstractItemModel *model)
// QAbstractItemView connects to a private slot
disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
- // do header layout after the tree
- disconnect(d->model, SIGNAL(layoutChanged()),
- d->header, SLOT(_q_layoutChanged()));
// QTreeView has a public slot for this
connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(rowsRemoved(QModelIndex,int,int)));
diff --git a/src/widgets/kernel/qgesturemanager_p.h b/src/widgets/kernel/qgesturemanager_p.h
index e57652afba..3df80bab55 100644
--- a/src/widgets/kernel/qgesturemanager_p.h
+++ b/src/widgets/kernel/qgesturemanager_p.h
@@ -59,6 +59,8 @@
#ifndef QT_NO_GESTURES
+#include <functional>
+
QT_BEGIN_NAMESPACE
class QBasicTimer;
@@ -112,7 +114,7 @@ private:
ObjectGesture(QObject *o, const Qt::GestureType &g) : object(o), gesture(g) { }
inline bool operator<(const ObjectGesture &rhs) const
{
- if (object < rhs.object)
+ if (std::less<QObject *>{}(object, rhs.object))
return true;
if (object == rhs.object)
return gesture < rhs.gesture;
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index c5eea1c514..5eab2d1038 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -126,15 +126,6 @@
QT_BEGIN_NAMESPACE
-static bool qt_enable_backingstore = true;
-#if 0 // Used to be included in Qt4 for Q_WS_X11
-// for compatibility with Qt 4.0
-Q_WIDGETS_EXPORT void qt_x11_set_global_double_buffer(bool enable)
-{
- qt_enable_backingstore = enable;
-}
-#endif
-
#if 0 // Used to be included in Qt4 for Q_WS_MAC
bool qt_mac_clearDirtyOnWidgetInsideDrawWidget = false;
#endif
@@ -145,11 +136,6 @@ static inline bool qRectIntersects(const QRect &r1, const QRect &r2)
qMax(r1.top(), r2.top()) <= qMin(r1.bottom(), r2.bottom()));
}
-static inline bool hasBackingStoreSupport()
-{
- return true;
-}
-
#if 0 // Used to be included in Qt4 for Q_WS_MAC
# define QT_NO_PAINT_DEBUG
#endif
@@ -1200,6 +1186,7 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute()
adjustQuitOnCloseAttribute();
+ q->setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea);
q->setAttribute(Qt::WA_WState_Hidden);
//give potential windows a bigger "pre-initial" size; create_sys() will give them a new size later
@@ -1352,8 +1339,7 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
// a real toplevel window needs a backing store
if (isWindow() && windowType() != Qt::Desktop) {
d->topData()->backingStoreTracker.destroy();
- if (hasBackingStoreSupport())
- d->topData()->backingStoreTracker.create(this);
+ d->topData()->backingStoreTracker.create(this);
}
d->setModal_sys();
@@ -1425,8 +1411,6 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
Q_UNUSED(initializeWindow);
Q_UNUSED(destroyOldWindow);
- Qt::WindowFlags flags = data.window_flags;
-
if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow())
return; // we only care about real toplevels
@@ -1444,12 +1428,19 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
win->setProperty(propertyName, q->property(propertyName));
}
+ Qt::WindowFlags &flags = data.window_flags;
+
+#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
+ if (q->testAttribute(Qt::WA_ContentsMarginsRespectsSafeArea))
+ flags |= Qt::MaximizeUsingFullscreenGeometryHint;
+#endif
+
if (q->testAttribute(Qt::WA_ShowWithoutActivating))
win->setProperty("_q_showWithoutActivating", QVariant(true));
if (q->testAttribute(Qt::WA_MacAlwaysShowToolWindow))
win->setProperty("_q_macAlwaysShowToolWindow", QVariant(true));
setNetWmWindowTypes(true); // do nothing if none of WA_X11NetWmWindowType* is set
- win->setFlags(data.window_flags);
+ win->setFlags(flags);
fixPosIncludesFrame();
if (q->testAttribute(Qt::WA_Moved)
|| !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowManagement))
@@ -2312,7 +2303,7 @@ bool QWidgetPrivate::paintOnScreen() const
return true;
}
- return !qt_enable_backingstore;
+ return false;
#endif
}
@@ -5490,11 +5481,11 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
setSystemClip(pdev->paintEngine(), pdev->devicePixelRatioF(), rgn.translated(offset));
QPainter p(pdev);
p.translate(offset);
- context.painter = &p;
+ context.painter = context.sharedPainter = &p;
graphicsEffect->draw(&p);
setSystemClip(pdev->paintEngine(), 1, QRegion());
} else {
- context.painter = sharedPainter;
+ context.painter = context.sharedPainter = sharedPainter;
if (sharedPainter->worldTransform() != sourced->lastEffectTransform) {
sourced->invalidateCache();
sourced->lastEffectTransform = sharedPainter->worldTransform();
@@ -5980,9 +5971,9 @@ void QWidgetPrivate::resolveLocale()
Q_Q(const QWidget);
if (!q->testAttribute(Qt::WA_SetLocale)) {
- setLocale_helper(q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)
- ? QLocale()
- : q->parentWidget()->locale());
+ QWidget *parent = q->parentWidget();
+ setLocale_helper(!parent || (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation))
+ ? QLocale() : parent->locale());
}
}
@@ -7585,21 +7576,7 @@ void QWidget::setContentsMargins(int left, int top, int right, int bottom)
d->rightmargin = right;
d->bottommargin = bottom;
- if (QLayout *l=d->layout)
- l->update(); //force activate; will do updateGeometry
- else
- updateGeometry();
-
- if (isVisible()) {
- update();
- QResizeEvent e(data->crect.size(), data->crect.size());
- QApplication::sendEvent(this, &e);
- } else {
- setAttribute(Qt::WA_PendingResizeEvent, true);
- }
-
- QEvent e(QEvent::ContentsRectChange);
- QApplication::sendEvent(this, &e);
+ d->updateContentsRect();
}
/*!
@@ -7624,6 +7601,27 @@ void QWidget::setContentsMargins(const QMargins &margins)
margins.right(), margins.bottom());
}
+void QWidgetPrivate::updateContentsRect()
+{
+ Q_Q(QWidget);
+
+ if (layout)
+ layout->update(); //force activate; will do updateGeometry
+ else
+ q->updateGeometry();
+
+ if (q->isVisible()) {
+ q->update();
+ QResizeEvent e(q->data->crect.size(), q->data->crect.size());
+ QApplication::sendEvent(q, &e);
+ } else {
+ q->setAttribute(Qt::WA_PendingResizeEvent, true);
+ }
+
+ QEvent e(QEvent::ContentsRectChange);
+ QApplication::sendEvent(q, &e);
+}
+
/*!
Returns the widget's contents margins for \a left, \a top, \a
right, and \a bottom.
@@ -7632,15 +7630,22 @@ void QWidget::setContentsMargins(const QMargins &margins)
*/
void QWidget::getContentsMargins(int *left, int *top, int *right, int *bottom) const
{
- Q_D(const QWidget);
+ QMargins m = contentsMargins();
if (left)
- *left = d->leftmargin;
+ *left = m.left();
if (top)
- *top = d->topmargin;
+ *top = m.top();
if (right)
- *right = d->rightmargin;
+ *right = m.right();
if (bottom)
- *bottom = d->bottommargin;
+ *bottom = m.bottom();
+}
+
+// FIXME: Move to qmargins.h for next minor Qt release
+QMargins operator|(const QMargins &m1, const QMargins &m2)
+{
+ return QMargins(qMax(m1.left(), m2.left()), qMax(m1.top(), m2.top()),
+ qMax(m1.right(), m2.right()), qMax(m1.bottom(), m2.bottom()));
}
/*!
@@ -7653,10 +7658,11 @@ void QWidget::getContentsMargins(int *left, int *top, int *right, int *bottom) c
QMargins QWidget::contentsMargins() const
{
Q_D(const QWidget);
- return QMargins(d->leftmargin, d->topmargin, d->rightmargin, d->bottommargin);
+ QMargins userMargins(d->leftmargin, d->topmargin, d->rightmargin, d->bottommargin);
+ return testAttribute(Qt::WA_ContentsMarginsRespectsSafeArea) ?
+ userMargins | d->safeAreaMargins() : userMargins;
}
-
/*!
Returns the area inside the widget's margins.
@@ -7664,14 +7670,87 @@ QMargins QWidget::contentsMargins() const
*/
QRect QWidget::contentsRect() const
{
- Q_D(const QWidget);
- return QRect(QPoint(d->leftmargin, d->topmargin),
- QPoint(data->crect.width() - 1 - d->rightmargin,
- data->crect.height() - 1 - d->bottommargin));
-
+ return rect() - contentsMargins();
}
+QMargins QWidgetPrivate::safeAreaMargins() const
+{
+ Q_Q(const QWidget);
+ QWidget *nativeWidget = q->window();
+ if (!nativeWidget->windowHandle())
+ return QMargins();
+
+ QPlatformWindow *platformWindow = nativeWidget->windowHandle()->handle();
+ if (!platformWindow)
+ return QMargins();
+ QMargins safeAreaMargins = platformWindow->safeAreaMargins();
+
+ if (!q->isWindow()) {
+ // In theory the native parent widget already has a contents rect reflecting
+ // the safe area of that widget, but we can't be sure that the widget or child
+ // widgets of that widget have respected the contents rect when setting their
+ // geometry, so we need to manually compute the safe area.
+
+ // Unless the native widget doesn't have any margins, in which case there's
+ // nothing for us to compute.
+ if (safeAreaMargins.isNull())
+ return QMargins();
+
+ // Or, if one of our ancestors are in a layout that does not have WA_LayoutOnEntireRect
+ // set, then we know that the layout has already taken care of placing us inside the
+ // safe area, by taking the contents rect of its parent widget into account.
+ const QWidget *assumedSafeWidget = nullptr;
+ for (const QWidget *w = q; w != nativeWidget; w = w->parentWidget()) {
+ QWidget *parentWidget = w->parentWidget();
+ if (parentWidget->testAttribute(Qt::WA_LayoutOnEntireRect))
+ continue; // Layout not going to help us
+
+ QLayout *layout = parentWidget->layout();
+ if (!layout)
+ continue;
+
+ if (layout->geometry().isNull())
+ continue; // Layout hasn't been activated yet
+
+ if (layout->indexOf(const_cast<QWidget *>(w)) < 0)
+ continue; // Widget is not in layout
+
+ assumedSafeWidget = w;
+ break;
+ }
+
+#if !defined(QT_DEBUG)
+ if (assumedSafeWidget) {
+ // We found a layout that we assume will take care of keeping us within the safe area
+ // For debug builds we still map the safe area using the fallback logic, so that we
+ // can detect any misbehaving layouts.
+ return QMargins();
+ }
+#endif
+
+ // In all other cases we need to map the safe area of the native parent to the widget.
+ // This depends on the widget being positioned and sized already, which means the initial
+ // layout will be wrong, but the layout will then adjust itself.
+ QPoint topLeftMargins = q->mapFrom(nativeWidget, QPoint(safeAreaMargins.left(), safeAreaMargins.top()));
+ QRect widgetRect = q->isVisible() ? q->visibleRegion().boundingRect() : q->rect();
+ QPoint bottomRightMargins = widgetRect.bottomRight() - q->mapFrom(nativeWidget,
+ nativeWidget->rect().bottomRight() - QPoint(safeAreaMargins.right(), safeAreaMargins.bottom()));
+
+ // Margins should never be negative
+ safeAreaMargins = QMargins(qMax(0, topLeftMargins.x()), qMax(0, topLeftMargins.y()),
+ qMax(0, bottomRightMargins.x()), qMax(0, bottomRightMargins.y()));
+
+ if (!safeAreaMargins.isNull() && assumedSafeWidget) {
+ QLayout *layout = assumedSafeWidget->parentWidget()->layout();
+ qWarning() << layout << "is laying out" << assumedSafeWidget
+ << "outside of the contents rect of" << layout->parentWidget();
+ return QMargins(); // Return empty margin to visually highlight the error
+ }
+ }
+
+ return safeAreaMargins;
+}
/*!
\fn void QWidget::customContextMenuRequested(const QPoint &pos)
@@ -10931,25 +11010,7 @@ void QWidget::repaint(int x, int y, int w, int h)
void QWidget::repaint(const QRect &rect)
{
Q_D(QWidget);
-
- if (testAttribute(Qt::WA_WState_ConfigPending)) {
- update(rect);
- return;
- }
-
- if (!isVisible() || !updatesEnabled() || rect.isEmpty())
- return;
-
- if (hasBackingStoreSupport()) {
- QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
- if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
- tlwExtra->inRepaint = true;
- tlwExtra->backingStoreTracker->markDirty(rect, this, QWidgetBackingStore::UpdateNow);
- tlwExtra->inRepaint = false;
- }
- } else {
- d->repaint_sys(rect);
- }
+ d->repaint(rect);
}
/*!
@@ -10960,24 +11021,22 @@ void QWidget::repaint(const QRect &rect)
void QWidget::repaint(const QRegion &rgn)
{
Q_D(QWidget);
+ d->repaint(rgn);
+}
- if (testAttribute(Qt::WA_WState_ConfigPending)) {
- update(rgn);
- return;
- }
+template <typename T>
+void QWidgetPrivate::repaint(T r)
+{
+ Q_Q(QWidget);
- if (!isVisible() || !updatesEnabled() || rgn.isEmpty())
+ if (!q->isVisible() || !q->updatesEnabled() || r.isEmpty())
return;
- if (hasBackingStoreSupport()) {
- QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
- if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
- tlwExtra->inRepaint = true;
- tlwExtra->backingStoreTracker->markDirty(rgn, this, QWidgetBackingStore::UpdateNow);
- tlwExtra->inRepaint = false;
- }
- } else {
- d->repaint_sys(rgn);
+ QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
+ if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
+ tlwExtra->inRepaint = true;
+ tlwExtra->backingStoreTracker->markDirty(r, q, QWidgetBackingStore::UpdateNow);
+ tlwExtra->inRepaint = false;
}
}
@@ -11018,26 +11077,8 @@ void QWidget::update()
*/
void QWidget::update(const QRect &rect)
{
- if (!isVisible() || !updatesEnabled())
- return;
-
- QRect r = rect & QWidget::rect();
-
- if (r.isEmpty())
- return;
-
- if (testAttribute(Qt::WA_WState_InPaintEvent)) {
- QApplication::postEvent(this, new QUpdateLaterEvent(r));
- return;
- }
-
- if (hasBackingStoreSupport()) {
- QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
- if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
- tlwExtra->backingStoreTracker->markDirty(r, this);
- } else {
- d_func()->repaint_sys(r);
- }
+ Q_D(QWidget);
+ d->update(rect);
}
/*!
@@ -11047,29 +11088,33 @@ void QWidget::update(const QRect &rect)
*/
void QWidget::update(const QRegion &rgn)
{
- if (!isVisible() || !updatesEnabled())
+ Q_D(QWidget);
+ d->update(rgn);
+}
+
+template <typename T>
+void QWidgetPrivate::update(T r)
+{
+ Q_Q(QWidget);
+
+ if (!q->isVisible() || !q->updatesEnabled())
return;
- QRegion r = rgn & QWidget::rect();
+ T clipped = r & q->rect();
- if (r.isEmpty())
+ if (clipped.isEmpty())
return;
- if (testAttribute(Qt::WA_WState_InPaintEvent)) {
- QApplication::postEvent(this, new QUpdateLaterEvent(r));
+ if (q->testAttribute(Qt::WA_WState_InPaintEvent)) {
+ QApplication::postEvent(q, new QUpdateLaterEvent(clipped));
return;
}
- if (hasBackingStoreSupport()) {
- QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
- if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
- tlwExtra->backingStoreTracker->markDirty(r, this);
- } else {
- d_func()->repaint_sys(r);
- }
+ QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
+ if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
+ tlwExtra->backingStoreTracker->markDirty(clipped, q);
}
-
/*!
\internal
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index 26f8b53392..a9c73c6a26 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -344,6 +344,13 @@ public:
void setSharedPainter(QPainter *painter);
QWidgetBackingStore *maybeBackingStore() const;
QWidgetWindow *windowHandle() const;
+
+ template <typename T>
+ void repaint(T t);
+
+ template <typename T>
+ void update(T t);
+
void init(QWidget *desktopWidget, Qt::WindowFlags f);
void create_sys(WId window, bool initializeWindow, bool destroyOldWindow);
void createRecursively();
@@ -516,6 +523,9 @@ public:
void setLayoutItemMargins(int left, int top, int right, int bottom);
void setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt = 0);
+ void updateContentsRect();
+ QMargins safeAreaMargins() const;
+
// aboutToDestroy() is called just before the contents of
// QWidget::destroy() is executed. It's used to signal QWidget
// sub-classes that their internals are about to be released.
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index ac32c32e12..d5a18b525b 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -99,6 +99,13 @@ public:
#if QT_CONFIG(opengl)
QOpenGLContext *shareContext() const override;
#endif
+
+ void processSafeAreaMarginsChanged() override
+ {
+ Q_Q(QWidgetWindow);
+ if (QWidget *widget = q->widget())
+ QWidgetPrivate::get(widget)->updateContentsRect();
+ }
};
QRectF QWidgetWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const
diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp
index c01fb9e0db..80196a39a2 100644
--- a/src/widgets/styles/qfusionstyle.cpp
+++ b/src/widgets/styles/qfusionstyle.cpp
@@ -763,7 +763,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
painter->drawRect(rect);
QColor checkMarkColor = option->palette.text().color().darker(120);
- const int checkMarkPadding = QStyleHelper::dpiScaled(3);
+ const int checkMarkPadding = 1 + rect.width() * 0.2; // at least one pixel padding
if (checkbox->state & State_NoChange) {
gradient = QLinearGradient(rect.topLeft(), rect.bottomLeft());
@@ -777,18 +777,20 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
painter->drawRect(rect.adjusted(checkMarkPadding, checkMarkPadding, -checkMarkPadding, -checkMarkPadding));
} else if (checkbox->state & (State_On)) {
- QPen checkPen = QPen(checkMarkColor, QStyleHelper::dpiScaled(1.8));
+ qreal penWidth = QStyleHelper::dpiScaled(1.8);
+ penWidth = qMax(penWidth , 0.18 * rect.height());
+ penWidth = qMin(penWidth , 0.30 * rect.height());
+ QPen checkPen = QPen(checkMarkColor, penWidth);
checkMarkColor.setAlpha(210);
- painter->translate(-1, 0.5);
+ painter->translate(-0.8, 0.5);
painter->setPen(checkPen);
painter->setBrush(Qt::NoBrush);
- painter->translate(0.2, 0.0);
// Draw checkmark
QPainterPath path;
- path.moveTo(2 + checkMarkPadding, rect.height() / 2.0);
+ path.moveTo(1.33 * checkMarkPadding, rect.height() / 2.0);
path.lineTo(rect.width() / 2.0, rect.height() - checkMarkPadding);
- path.lineTo(rect.width() - checkMarkPadding - 0.5, checkMarkPadding);
+ path.lineTo(rect.width() - checkMarkPadding * 0.92, checkMarkPadding);
painter->drawPath(path.translated(rect.topLeft()));
}
}
@@ -1558,9 +1560,9 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
bool enabled = menuItem->state & State_Enabled;
bool ignoreCheckMark = false;
- int checkcol = qMax<int>(menuItem->maxIconWidth, QStyleHelper::dpiScaled(20));
- const int margin = QStyleHelper::dpiScaled(4);
-
+ const int checkColHOffset = windowsItemHMargin + windowsItemFrame - 1;
+ int checkcol = qMax(menuItem->rect.height() * 0.7,
+ qMax(menuItem->maxIconWidth * 1.0, dpiScaled(17))); // icon checkbox's highlihgt column width
if (
#if QT_CONFIG(combobox)
qobject_cast<const QComboBox*>(widget) ||
@@ -1570,10 +1572,9 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
if (!ignoreCheckMark) {
// Check
- const int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget);
- const int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, option, widget);
- QRect checkRect(option->rect.left() + indicatorWidth / 2,
- option->rect.center().y() - indicatorHeight / 2 + 1, indicatorWidth, indicatorHeight);
+ const int boxMargin = dpiScaled(4);
+ const int boxWidth = checkcol - 2 * boxMargin;
+ QRect checkRect(option->rect.left() + boxMargin + checkColHOffset, option->rect.center().y() - boxWidth/2 + 1, boxWidth, boxWidth);
checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect);
if (checkable) {
if (menuItem->checkType & QStyleOptionMenuItem::Exclusive) {
@@ -1585,7 +1586,8 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
QPalette::ColorRole textRole = !enabled ? QPalette::Text:
selected ? QPalette::HighlightedText : QPalette::ButtonText;
painter->setBrush(option->palette.brush( option->palette.currentColorGroup(), textRole));
- painter->drawEllipse(checkRect.adjusted(margin, margin, -margin, -margin));
+ const int adjustment = checkRect.height() * 0.3;
+ painter->drawEllipse(checkRect.adjusted(adjustment, adjustment, -adjustment, -adjustment));
}
} else {
// Check box
@@ -1614,7 +1616,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
QPainter *p = painter;
QRect vCheckRect = visualRect(opt->direction, menuitem->rect,
- QRect(menuitem->rect.x() + margin, menuitem->rect.y(),
+ QRect(menuitem->rect.x() + checkColHOffset, menuitem->rect.y(),
checkcol, menuitem->rect.height()));
if (!menuItem->icon.isNull()) {
QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
@@ -1665,11 +1667,10 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
discol = menuitem->palette.text().color();
p->setPen(discol);
}
- const int lm = QStyleHelper::dpiScaled(windowsItemFrame + windowsItemHMargin + 2) + checkcol;
- const int rm = QStyleHelper::dpiScaled(windowsRightBorder + 1) + tab;
- const int xpos = menuitem->rect.x() + lm;
+ int xm = checkColHOffset + checkcol + windowsItemHMargin;
+ int xpos = menuitem->rect.x() + xm;
- QRect textRect(xpos, y + windowsItemVMargin, w - lm - rm, h - 2 * windowsItemVMargin);
+ QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
QStringRef s(&menuitem->text);
if (!s.isEmpty()) { // draw text
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index 4e4576940a..14f81afe83 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -3657,7 +3657,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
if ((pseudo == PseudoElement_MenuSeparator) && subRule.hasDrawable()) {
subRule.drawRule(p, opt->rect);
} else if ((pseudo == PseudoElement_Item)
- && (allRules.hasBox() || allRules.hasBorder()
+ && (allRules.hasBox() || allRules.hasBorder() || subRule.hasFont
|| (allRules.background() && !allRules.background()->pixmap.isNull()))) {
subRule.drawRule(p, opt->rect);
if (subRule.hasBackground()) {
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index 249ebd35d3..c6d66bafd4 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -334,16 +334,27 @@ void QAbstractScrollAreaPrivate::setSingleFingerPanEnabled(bool on)
void QAbstractScrollAreaPrivate::layoutChildren()
{
+ bool needH = false;
+ bool needV = false;
+ layoutChildren_helper(&needH, &needV);
+ // Call a second time if one scrollbar was needed and not the other to
+ // check if it needs to readjust accordingly
+ if (needH != needV)
+ layoutChildren_helper(&needH, &needV);
+}
+
+void QAbstractScrollAreaPrivate::layoutChildren_helper(bool *needHorizontalScrollbar, bool *needVerticalScrollbar)
+{
Q_Q(QAbstractScrollArea);
bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, hbar);
- bool needh = (hbarpolicy != Qt::ScrollBarAlwaysOff) && ((hbarpolicy == Qt::ScrollBarAlwaysOn && !htransient)
- || ((hbarpolicy == Qt::ScrollBarAsNeeded || htransient)
- && hbar->minimum() < hbar->maximum() && !hbar->sizeHint().isEmpty()));
+ bool needh = *needHorizontalScrollbar || ((hbarpolicy != Qt::ScrollBarAlwaysOff) && ((hbarpolicy == Qt::ScrollBarAlwaysOn && !htransient)
+ || ((hbarpolicy == Qt::ScrollBarAsNeeded || htransient)
+ && hbar->minimum() < hbar->maximum() && !hbar->sizeHint().isEmpty())));
bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, vbar);
- bool needv = (vbarpolicy != Qt::ScrollBarAlwaysOff) && ((vbarpolicy == Qt::ScrollBarAlwaysOn && !vtransient)
- || ((vbarpolicy == Qt::ScrollBarAsNeeded || vtransient)
- && vbar->minimum() < vbar->maximum() && !vbar->sizeHint().isEmpty()));
+ bool needv = *needVerticalScrollbar || ((vbarpolicy != Qt::ScrollBarAlwaysOff) && ((vbarpolicy == Qt::ScrollBarAlwaysOn && !vtransient)
+ || ((vbarpolicy == Qt::ScrollBarAsNeeded || vtransient)
+ && vbar->minimum() < vbar->maximum() && !vbar->sizeHint().isEmpty())));
QStyleOption opt(0);
opt.init(q);
@@ -522,6 +533,8 @@ void QAbstractScrollAreaPrivate::layoutChildren()
viewportRect.adjust(left, top, -right, -bottom);
viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last
+ *needHorizontalScrollbar = needh;
+ *needVerticalScrollbar = needv;
}
/*!
diff --git a/src/widgets/widgets/qabstractscrollarea_p.h b/src/widgets/widgets/qabstractscrollarea_p.h
index 251e563724..732a2ab40d 100644
--- a/src/widgets/widgets/qabstractscrollarea_p.h
+++ b/src/widgets/widgets/qabstractscrollarea_p.h
@@ -95,6 +95,7 @@ public:
void init();
void layoutChildren();
+ void layoutChildren_helper(bool *needHorizontalScrollbar, bool *needVerticalScrollbar);
// ### Fix for 4.4, talk to Bjoern E or Girish.
virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {}
bool canStartScrollingAt( const QPoint &startPos );
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 64c4fc5666..4796ed43d3 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -902,8 +902,7 @@ void QMenuPrivate::adjustMenuScreen(const QPoint &p)
// The windowHandle must point to the screen where the menu will be shown.
// The (item) size calculations depend on the menu screen,
// so a wrong screen would often cause wrong sizes (on high DPI)
- const QScreen *primaryScreen = QApplication::primaryScreen();
- const QScreen *currentScreen = q->windowHandle() ? q->windowHandle()->screen() : primaryScreen;
+ const QScreen *currentScreen = q->windowHandle() ? q->windowHandle()->screen() : nullptr;
QScreen *actualScreen = QGuiApplication::screenAt(p);
if (actualScreen && currentScreen != actualScreen) {
if (!q->windowHandle()) // Try to create a window handle if not created.
diff --git a/src/widgets/widgets/qwidgetresizehandler.cpp b/src/widgets/widgets/qwidgetresizehandler.cpp
index d4f14ad1d4..45010d1768 100644
--- a/src/widgets/widgets/qwidgetresizehandler.cpp
+++ b/src/widgets/widgets/qwidgetresizehandler.cpp
@@ -121,7 +121,7 @@ bool QWidgetResizeHandler::eventFilter(QObject *o, QEvent *ee)
break;
const QRect widgetRect = widget->rect().marginsAdded(QMargins(range, range, range, range));
const QPoint cursorPoint = widget->mapFromGlobal(e->globalPos());
- if (!widgetRect.contains(cursorPoint) || mode == Center || mode == Nowhere)
+ if (!widgetRect.contains(cursorPoint) || mode == Nowhere)
return false;
if (e->button() == Qt::LeftButton) {
#if 0 // Used to be included in Qt4 for Q_WS_X11