summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config_help.txt10
-rw-r--r--configure.pri2
-rw-r--r--mkspecs/common/msvc-desktop.conf5
-rw-r--r--mkspecs/devices/integrity-armv8-msm8996au/qmake.conf57
-rw-r--r--mkspecs/devices/integrity-armv8-msm8996au/qplatformdefs.h45
-rw-r--r--mkspecs/features/data/configure.json2
-rw-r--r--mkspecs/features/default_pre.prf3
-rw-r--r--mkspecs/features/qt_configure.prf61
-rw-r--r--mkspecs/features/qt_plugin.prf2
-rw-r--r--mkspecs/features/toolchain.prf19
-rw-r--r--mkspecs/features/uikit/xcodebuild.mk2
-rw-r--r--mkspecs/integrity-armv8-rcar/qmake.conf33
-rw-r--r--mkspecs/integrity-armv8-rcar/qplatformdefs.h39
-rw-r--r--mkspecs/win32-g++/qmake.conf11
-rw-r--r--mkspecs/win32-icc/qmake.conf9
-rw-r--r--qmake/Makefile.unix.mingw2
-rw-r--r--qmake/generators/mac/pbuilder_pbx.cpp3
-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/angle/patches/0016-ANGLE-Fix-resizing-of-windows.patch57
-rw-r--r--src/corelib/animation/qabstractanimation.cpp4
-rw-r--r--src/corelib/configure.json4
-rw-r--r--src/corelib/doc/snippets/qstring/main.cpp1
-rw-r--r--src/corelib/global/global.pri5
-rw-r--r--src/corelib/global/qfloat16_p.h4
-rw-r--r--src/corelib/global/qglobal.cpp3
-rw-r--r--src/corelib/global/qlogging.cpp2
-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
-rwxr-xr-x[-rw-r--r--]src/corelib/io/qfilesystemengine_win.cpp64
-rw-r--r--src/corelib/io/qloggingregistry.cpp4
-rw-r--r--src/corelib/io/qloggingregistry_p.h2
-rw-r--r--src/corelib/io/qurl.cpp110
-rw-r--r--src/corelib/kernel/kernel.pri2
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp6
-rw-r--r--src/corelib/kernel/qobject.cpp2
-rw-r--r--src/corelib/kernel/qppsobjectprivate_p.h4
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp6
-rw-r--r--src/corelib/thread/qfuturewatcher.h2
-rw-r--r--src/corelib/tools/qmap.h4
-rw-r--r--src/corelib/tools/qstring.cpp32
-rw-r--r--src/corelib/tools/qunicodetables.cpp20
-rw-r--r--src/corelib/tools/qunicodetables_p.h4
-rw-r--r--src/corelib/xml/qxmlstream.cpp1
-rw-r--r--src/gui/configure.json41
-rw-r--r--src/gui/kernel/qguiapplication.cpp16
-rw-r--r--src/gui/kernel/qguiapplication_p.h2
-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_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/network/access/qnetworkaccessmanager.cpp5
-rw-r--r--src/network/bearer/qbearerengine.cpp3
-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/kernel/qdnslookup_unix.cpp27
-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/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.cpp6
-rw-r--r--src/platformsupport/input/libinput/qlibinputpointer.cpp8
-rw-r--r--src/plugins/bearer/bearer.pro5
-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/qcocoamenuloader.mm8
-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/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.mm71
-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.mm72
-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/qwindowsopengltester.cpp2
-rw-r--r--src/plugins/platforms/xcb/README3
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp5
-rw-r--r--src/plugins/platforms/xcb/xcb_qpa_lib.pro2
-rw-r--r--src/printsupport/kernel/qprintengine_win.cpp2
-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/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/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/qwidgetresizehandler.cpp2
-rw-r--r--tests/auto/auto.pro2
-rw-r--r--tests/auto/corelib/animation/qpauseanimation/BLACKLIST2
-rw-r--r--tests/auto/corelib/animation/qpropertyanimation/BLACKLIST2
-rw-r--r--tests/auto/corelib/animation/qpropertyanimation/qpropertyanimation.pro2
-rw-r--r--tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp235
-rw-r--r--tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp2
-rwxr-xr-x[-rw-r--r--]tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp26
-rw-r--r--tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp6
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp11
-rw-r--r--tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp32
-rw-r--r--tests/auto/corelib/tools/qdatetime/BLACKLIST3
-rw-r--r--tests/auto/network/socket/qudpsocket/BLACKLIST5
-rw-r--r--tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp20
-rw-r--r--tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp12
-rw-r--r--tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp21
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp24
-rw-r--r--tests/auto/widgets/widgets/qsplitter/BLACKLIST2
-rw-r--r--util/unicode/main.cpp30
153 files changed, 2668 insertions, 818 deletions
diff --git a/config_help.txt b/config_help.txt
index 6b1401c618..9c424391a9 100644
--- a/config_help.txt
+++ b/config_help.txt
@@ -9,6 +9,12 @@ ICU_PREFIX=/opt/icu42 ICU_LIBS="-licui18n -licuuc -licudata".
It is also possible to manipulate any QMAKE_* variable, to amend the values
from the mkspec for the build of Qt itself, e.g., QMAKE_CXXFLAGS+=-g3.
+Note that the *_LIBS* and QMAKE_* assignments manipulate lists, so items
+containing meta characters (spaces in particular) need to be quoted according
+to qmake rules. On top of that, the assignments as a whole need to be quoted
+according to shell rules. It is recommended to use single quotes for the inner
+quoting and double quotes for the outer quoting.
+
Top-level installation directories:
-prefix <dir> ...... The deployment directory, as seen on the target device.
[/usr/local/Qt-$QT_VERSION, $PWD if -developer-build]
@@ -60,8 +66,10 @@ Configure meta:
-redo ................ Re-configure with previously used options.
Additional options may be passed, but will not be
saved for later use by -redo.
- -recheck ............. Discard cached negative configure test results.
+ -recheck [test,...] .. Discard cached negative configure test results.
Use this after installing missing dependencies.
+ Alternatively, if tests are specified, only their
+ results are discarded.
-recheck-all ......... Discard all cached configure test results.
-feature-<feature> ... Enable <feature>
diff --git a/configure.pri b/configure.pri
index 021cc1bd1e..ea482552c4 100644
--- a/configure.pri
+++ b/configure.pri
@@ -557,7 +557,7 @@ defineTest(qtConfOutput_prepareOptions) {
else: \
qtConfFatalError("Cannot detect the Android host." \
"Please use -android-ndk-host option to specify one.")
- qtConfAddNotice("Available Android host does not match host architecture.")
+ qtConfAddNote("Available Android host does not match host architecture.")
}
} else {
!exists($$ndk_tc_pfx/$$ndk_host/*): \
diff --git a/mkspecs/common/msvc-desktop.conf b/mkspecs/common/msvc-desktop.conf
index 20f594c601..1a38f70205 100644
--- a/mkspecs/common/msvc-desktop.conf
+++ b/mkspecs/common/msvc-desktop.conf
@@ -15,7 +15,7 @@
MAKEFILE_GENERATOR = MSVC.NET
QMAKE_PLATFORM = win32
QMAKE_COMPILER = msvc
-CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
+CONFIG += incremental flat debug_and_release debug_and_release_target precompile_header autogen_precompile_source embed_manifest_dll embed_manifest_exe
DEFINES += UNICODE _UNICODE WIN32
QMAKE_COMPILER_DEFINES += _WIN32
contains(QMAKE_TARGET.arch, x86_64) {
@@ -35,7 +35,7 @@ QMAKE_CFLAGS = -nologo -Zc:wchar_t
QMAKE_CFLAGS_WARN_ON = -W3
QMAKE_CFLAGS_WARN_OFF = -W0
QMAKE_CFLAGS_RELEASE = $$QMAKE_CFLAGS_OPTIMIZE -MD
-QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_OPTIMIZE -MD -Zi
+QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_OPTIMIZE -Zi -MD
QMAKE_CFLAGS_DEBUG = -Zi -MDd
QMAKE_CFLAGS_YACC =
QMAKE_CFLAGS_LTCG = -GL
@@ -100,7 +100,6 @@ QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2 = gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2_DEBUG = gdi32.lib user32.lib
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
-
QMAKE_LIBS_QT_ENTRY = -lqtmain
QMAKE_IDL = midl /NOLOGO
diff --git a/mkspecs/devices/integrity-armv8-msm8996au/qmake.conf b/mkspecs/devices/integrity-armv8-msm8996au/qmake.conf
new file mode 100644
index 0000000000..90299bf3e9
--- /dev/null
+++ b/mkspecs/devices/integrity-armv8-msm8996au/qmake.conf
@@ -0,0 +1,57 @@
+#
+# qmake configuration for INTEGRITY Qualcomm s820 Snapdragon MSM8996AU
+#
+
+load(device_config)
+
+include(../../common/ghs-integrity-armv8.conf)
+
+QT_QPA_DEFAULT_PLATFORM = eglfs
+EGLFS_DEVICE_INTEGRATION = eglfs_openwfd
+
+bsp_name = $$(INTEGRITY_BSP)
+isEmpty(bsp_name): \
+ error("This qmakespec requires $INTEGRITY_BSP to be set")
+
+os_directory = $$(INTEGRITY_DIR)
+isEmpty(os_directory): \
+ error("This qmakespec requires $INTEGRITY_DIR to be set")
+
+qclibs_directory = $$(QCLIBS_DIR)
+isEmpty(qclibs_directory): \
+ error("This qmakespec requires $QCLIBS_DIR to be set")
+
+qc_multimedia_inc_directory = $$(QC_MULTIMEDIA_INC_DIR)
+isEmpty(qc_multimedia_inc_directory): \
+ error("This qmakespec requires $QC_MULTIMEDIA_INC_DIR to be set")
+
+gl_inc_directory = $$(GL_INC_DIR)
+isEmpty(gl_inc_directory): \
+ error("This qmakespec requires $GL_INC_DIR to be set")
+
+gl_lib_directory = $$(GL_LIB_DIR)
+isEmpty(gl_lib_directory): \
+ error("This qmakespec requires $GL_LIB_DIR to be set")
+
+QMAKE_LIBDIR += $$(QCLIBS_DIR)/base
+QMAKE_LIBDIR += $$(QCLIBS_DIR)/multimedia/display
+
+QMAKE_INCDIR += $$(QC_MULTIMEDIA_INC_DIR)
+
+QMAKE_LIBS_EGL += -lESXEGL_Adreno -lESXGLESv2_Adreno -ladreno_utils -lGSLUser -lOSUser -lpanel -livfs -lposix -lpmem -ltzbsp -lpaged_alloc -lglnext-llvm -lopenwfd
+QMAKE_LIBS_OPENGL_ES2 += $${QMAKE_LIBS_EGL}
+
+QMAKE_CFLAGS += -DINTEGRITY
+QMAKE_CXXFLAGS += -DINTEGRITY
+
+QMAKE_CFLAGS += -bigswitch
+QMAKE_CXXFLAGS += -bigswitch
+QMAKE_LFLAGS += -bigswitch
+
+# OpenGL libraries have a dependency on libEGL
+QMAKE_INCDIR_EGL = $$(GL_INC_DIR)
+QMAKE_LIBDIR_EGL = $$(GL_LIB_DIR)
+QMAKE_INCDIR_OPENGL_ES2 = $$(GL_INC_DIR)
+QMAKE_LIBDIR_OPENGL_ES2 = $$(GL_LIB_DIR)
+
+load(qt_config)
diff --git a/mkspecs/devices/integrity-armv8-msm8996au/qplatformdefs.h b/mkspecs/devices/integrity-armv8-msm8996au/qplatformdefs.h
new file mode 100644
index 0000000000..c8361113a0
--- /dev/null
+++ b/mkspecs/devices/integrity-armv8-msm8996au/qplatformdefs.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the qmake spec 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 QPLATFORMDEFS_H
+#define QPLATFORMDEFS_H
+
+#include "../../common/integrity/qplatformdefs.h"
+
+#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/features/data/configure.json b/mkspecs/features/data/configure.json
index 38623d46a4..167c502e82 100644
--- a/mkspecs/features/data/configure.json
+++ b/mkspecs/features/data/configure.json
@@ -9,7 +9,7 @@
"continue": "void",
- "recheck": { "type": "void", "name": "cache_use", "value": "positive" },
+ "recheck": { "type": "optionalString", "name": "cache_recheck" },
"recheck-all": { "type": "void", "name": "cache_use", "value": "none" },
"redo": { "type": "redo" },
diff --git a/mkspecs/features/default_pre.prf b/mkspecs/features/default_pre.prf
index 2d52525190..07a9b1c401 100644
--- a/mkspecs/features/default_pre.prf
+++ b/mkspecs/features/default_pre.prf
@@ -2,6 +2,9 @@
# Note that evaluating variable assignments from the command line
# still happens in between these two steps.
+# In early configure setup; nothing useful to be done here.
+isEmpty(QMAKE_CXX): return()
+
load(exclusive_builds)
CONFIG = \
lex yacc debug exceptions depend_includepath \
diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf
index 1ba96767be..d5dcda22ac 100644
--- a/mkspecs/features/qt_configure.prf
+++ b/mkspecs/features/qt_configure.prf
@@ -499,30 +499,37 @@ defineTest(qtConfLibrary_inline) {
# to make them recognize the same input variables.
input = $$eval($${2}.alias)
- # direct libs. overwrites inline libs.
- defined(config.input.$${input}.libs, var) {
- $${1}.libs = $$eval(config.input.$${input}.libs)
- export($${1}.libs)
- }
-
# build-specific direct libs. overwrites inline libs.
vars =
any = false
all = true
- for (b, $${1}.builds._KEYS_) {
+ for (b, $$list(debug release)) {
iv = $${input}.libs.$${b}
vars += $$eval(config.commandline.rev_assignments.$${iv})
defined(config.input.$${iv}, var) {
- $${1}.builds.$${b}.libs = $$eval(config.input.$${iv})
- export($${1}.builds.$${b}.libs)
+ $${1}.builds.$${b} = $$eval(config.input.$${iv})
+ export($${1}.builds.$${b})
+ $${1}.builds._KEYS_ *= $${b}
any = true
} else {
all = false
}
}
- $$any:!$$all {
- qtConfAddError("Either none or all of $$join(vars, ", ", [, ]) must be specified.")
- return(false)
+ $$any {
+ !$$all {
+ qtConfAddError("Either none or all of $$join(vars, ", ", [, ]) must be specified.")
+ return(false)
+ }
+ export($${1}.builds._KEYS_)
+ # we also reset the generic libs, to avoid surprises.
+ $${1}.libs =
+ export($${1}.libs)
+ }
+
+ # direct libs. overwrites inline libs.
+ defined(config.input.$${input}.libs, var) {
+ $${1}.libs = $$eval(config.input.$${input}.libs)
+ export($${1}.libs)
}
# prefix. prepends to (possibly overwritten) inline libs.
@@ -670,9 +677,10 @@ defineTest(qtConfExportLibrary) {
NAME = $$upper($$name)
# LIBS is emitted even if empty, as this allows the library to be "seen".
qtConfOutputVar(assign, $$output, QMAKE_LIBS_$$NAME, $$libs)
- for (b, $${spfx}.builds._KEYS_): \
- qtConfOutputVar(assign, $$output, QMAKE_LIBS_$${NAME}_$$upper($$b), \
- $$eval($${spfx}.builds.$${b}))
+ for (b, $${spfx}.builds._KEYS_) {
+ eval(blibs = $$eval($${spfx}.builds.$${b}))
+ qtConfOutputVar(assign, $$output, QMAKE_LIBS_$${NAME}_$$upper($$b), $$blibs)
+ }
!isEmpty(defines): qtConfOutputVar(assign, $$output, QMAKE_DEFINES_$$NAME, $$defines)
!isEmpty(includes): qtConfOutputVar(assign, $$output, QMAKE_INCDIR_$$NAME, $$includes)
!isEmpty($${currentConfig}.module): \
@@ -1044,8 +1052,13 @@ defineTest(qtConfSaveResult) {
return()
keys = result $$eval($${1}.cache)
cont = "cache.$${2}._KEYS_ = $$keys"
- for (k, keys): \
+ cache.$${2}._KEYS_ = $$keys
+ export(cache.$${2}._KEYS_)
+ for (k, keys) {
cont += "cache.$${2}.$${k} = $$val_escape($${1}.$${k})"
+ cache.$${2}.$${k} = $$eval($${1}.$${k})
+ export(cache.$${2}.$${k})
+ }
write_file($$QMAKE_CONFIG_CACHE, cont, append)|error()
}
@@ -2033,14 +2046,28 @@ qtConfCheckErrors()
QMAKE_CONFIG_CACHE = $$OUT_PWD/config.cache
QMAKE_CONFIG_CACHE_USE = $$eval(config.input.cache_use)
+cache_recheck = $$eval(config.input.cache_recheck)
+equals(cache_recheck, yes) {
+ QMAKE_CONFIG_CACHE_USE = positive
+ cache_recheck =
+}
isEmpty(QMAKE_CONFIG_CACHE_USE): \
QMAKE_CONFIG_CACHE_USE = all
!equals(QMAKE_CONFIG_CACHE_USE, none) {
include($$QMAKE_CONFIG_CACHE, , true)
# this crudely determines when to discard the cache. this also catches the case
# of no cache being there in the first place.
- !equals(cache.platform, $$[QMAKE_SPEC])|!equals(cache.xplatform, $$[QMAKE_XSPEC]): \
+ !equals(cache.platform, $$[QMAKE_SPEC])|!equals(cache.xplatform, $$[QMAKE_XSPEC]) {
QMAKE_CONFIG_CACHE_USE = none
+ } else: !isEmpty(cache_recheck) {
+ for (cr, $$list($$split(cache_recheck, ","))) {
+ !isEmpty(cache.$${cr}._KEYS_) {
+ cache.$${cr}._KEYS_ =
+ } else {
+ qtConfAddWarning("Attempting to discard non-cached result '$$cr'.")
+ }
+ }
+ }
}
equals(QMAKE_CONFIG_CACHE_USE, none) {
cont = \
diff --git a/mkspecs/features/qt_plugin.prf b/mkspecs/features/qt_plugin.prf
index 62e1b69fde..14fc5f9a94 100644
--- a/mkspecs/features/qt_plugin.prf
+++ b/mkspecs/features/qt_plugin.prf
@@ -48,7 +48,7 @@ CONFIG(static, static|shared)|prefix_build {
!build_pass {
qt_plugin_deps = $$QT $$QT_PRIVATE
- qt_plugin_deps = s,-private$,_private,g
+ qt_plugin_deps ~= s,-private$,_private,g
MODULE_PRI_CONT = \
"QT_PLUGIN.$${MODULE}.TYPE = $$PLUGIN_TYPE" \
diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf
index ba41598be1..fdf3d1cdd3 100644
--- a/mkspecs/features/toolchain.prf
+++ b/mkspecs/features/toolchain.prf
@@ -1,7 +1,4 @@
-# In early configure setup; nothing useful to be done here.
-isEmpty(QMAKE_CXX): return()
-
defineReplace(qtMakeExpand) {
out = "$$1"
for(ever) {
@@ -19,7 +16,13 @@ defineTest(qtCompilerErrror) {
what = " host"
else: \
what = " target"
- error("Cannot run$$what compiler '$$1'. Maybe you forgot to setup the environment?")
+ msg = \
+ "Cannot run$$what compiler '$$1'. Output:" \
+ "===================" \
+ $$2 \
+ "===================" \
+ "Maybe you forgot to setup the environment?"
+ error($$join(msg, $$escape_expand(\\n)))
}
cross_compile:host_build: \
@@ -64,7 +67,7 @@ isEmpty($${target_prefix}.INCDIRS) {
cxx_flags += -E -v
output = $$system("$$cmd_prefix $$QMAKE_CXX $$qtMakeExpand($$cxx_flags) -xc++ - 2>&1 $$cmd_suffix", lines, ec)
- !equals(ec, 0): qtCompilerErrror($$QMAKE_CXX)
+ !equals(ec, 0): qtCompilerErrror($$QMAKE_CXX, $$output)
rim_qcc {
for (line, output) {
@@ -124,7 +127,7 @@ isEmpty($${target_prefix}.INCDIRS) {
# What's more, -print-search-dirs can't be used on clang on Apple because it
# won't print all the library paths (only the clang-internal ones).
output = $$system("$$cmd_prefix $$QMAKE_CXX -print-search-dirs", lines, ec)
- !equals(ec, 0): qtCompilerErrror($$QMAKE_CXX)
+ !equals(ec, 0): qtCompilerErrror($$QMAKE_CXX, $$output)
for (line, output) {
contains(line, "^libraries: .*") {
@@ -166,14 +169,14 @@ isEmpty($${target_prefix}.INCDIRS) {
defineReplace(qtVariablesFromMSVC) {
ret = $$system("$$1 -nologo -E $$2 $$system_quote($$PWD/data/macros.cpp) <NUL 2>NUL", lines, ec)
- !equals(ec, 0): qtCompilerErrror($$1)
+ !equals(ec, 0): qtCompilerErrror($$1, $$ret)
return($$ret)
}
defineReplace(qtVariablesFromGCC) {
ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) \
<$$QMAKE_SYSTEM_NULL_DEVICE 2>$$QMAKE_SYSTEM_NULL_DEVICE", lines, ec)
- !equals(ec, 0): qtCompilerErrror($$1)
+ !equals(ec, 0): qtCompilerErrror($$1, $$ret)
return($$ret)
}
diff --git a/mkspecs/features/uikit/xcodebuild.mk b/mkspecs/features/uikit/xcodebuild.mk
index 435b9dbdf2..0c8d99f4b8 100644
--- a/mkspecs/features/uikit/xcodebuild.mk
+++ b/mkspecs/features/uikit/xcodebuild.mk
@@ -90,7 +90,7 @@ DESTINATION_MESSAGE = "Running $(call tolower,$(CONFIGURATION)) $(ACTION) \
xcodebuild-%:
@$(if $(DESTINATION_NAME), echo $(DESTINATION_MESSAGE),)
- xcodebuild $(ACTION) $(XCODEBUILD_FLAGS) -project $(TARGET).xcodeproj -scheme $(TARGET) $(if $(SDK), -sdk $(SDK),) $(if $(CONFIGURATION), -configuration $(CONFIGURATION),) $(if $(DESTINATION), -destination $(DESTINATION) -destination-timeout 1,) $(if $(INSTALL_ROOT), DSTROOT=$(INSTALL_ROOT),)
+ xcodebuild $(ACTION) $(XCODEBUILD_FLAGS) -project $(TARGET).xcodeproj -scheme $(TARGET) $(if $(SDK), -sdk $(SDK),) $(if $(CONFIGURATION), -configuration $(CONFIGURATION),) $(if $(DESTINATION), -destination $(DESTINATION) -destination-timeout 1,) $(if $(DESTINATION_ID),, ENABLE_ONLY_ACTIVE_RESOURCES=NO) $(if $(INSTALL_ROOT), DSTROOT=$(INSTALL_ROOT),)
xcodebuild-check-device_%: DESTINATION_ID=$(lastword $(subst _, ,$@))
diff --git a/mkspecs/integrity-armv8-rcar/qmake.conf b/mkspecs/integrity-armv8-rcar/qmake.conf
new file mode 100644
index 0000000000..46091f6a91
--- /dev/null
+++ b/mkspecs/integrity-armv8-rcar/qmake.conf
@@ -0,0 +1,33 @@
+#
+# qmake configuration for INTEGRITY armv7 targets
+#
+
+# armv7 common includes work for armv8-A as well
+include(../common/ghs-integrity-armv7.conf)
+
+DEFINES += INTEGRITY
+
+# This define is used because the RCar INTEGRITY EGL library expects same
+# parameter types as Symbian. The parameter types are defined in eglplatform.h.
+DEFINES += __WINSCW__
+
+QTPLUGIN.platforms += qeglfs
+QT_QPA_DEFAULT_PLATFORM = eglfs
+
+QMAKE_LIBS_EGL += -lEGL -lIMGegl -lsrv_um -lsrv_init -lpvrWSEGL_WM -lncg_usr.a -lmmgr_usr -lwm_usr -lprr_usr
+QMAKE_LIBS_OPENGL_ES2 += -lGLESv2 -lIMGegl -lglslcompiler -lusc -lsrv_um -lsrv_init -lpvrWSEGL_WM -lncg_usr.a -lmmgr_usr -lwm_usr -lprr_usr
+QMAKE_LIBS_GUI = -lmmgr_usr -lwm_usr -lprr_usr
+
+QMAKE_CFLAGS += -bigswitch
+QMAKE_CXXFLAGS += -bigswitch
+QMAKE_LFLAGS += -bigswitch
+
+EGLFS_DEVICE_INTEGRATION = eglfs_rcar
+
+# OpenGL libraries have a dependency on libEGL
+dirs = $$(GL_INC_DIR)
+QMAKE_INCDIR_EGL = $$split(dirs, $$QMAKE_DIRLIST_SEP)
+QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_EGL
+dirs = $$(GL_LIB_DIR)
+QMAKE_LIBDIR_EGL = $$split(dirs, $$QMAKE_DIRLIST_SEP)
+QMAKE_LIBDIR_OPENGL_ES2 = $$QMAKE_LIBDIR_EGL
diff --git a/mkspecs/integrity-armv8-rcar/qplatformdefs.h b/mkspecs/integrity-armv8-rcar/qplatformdefs.h
new file mode 100644
index 0000000000..55afd0c3c7
--- /dev/null
+++ b/mkspecs/integrity-armv8-rcar/qplatformdefs.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Green Hills Software. All rights reserved.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the qmake spec of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMDEFS_H
+#define QPLATFORMDEFS_H
+
+#include "../common/integrity/qplatformdefs.h"
+
+#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf
index 36ec1c5c78..d728047765 100644
--- a/mkspecs/win32-g++/qmake.conf
+++ b/mkspecs/win32-g++/qmake.conf
@@ -8,18 +8,17 @@
#
load(device_config)
+include(../common/gcc-base.conf)
include(../common/g++-base.conf)
+# modifications to gcc-base.conf and g++-base.conf
+
MAKEFILE_GENERATOR = MINGW
QMAKE_PLATFORM = win32 mingw
CONFIG += debug_and_release debug_and_release_target precompile_header
DEFINES += UNICODE _UNICODE
QMAKE_COMPILER_DEFINES += __GNUC__ WIN32
-QMAKE_EXT_OBJ = .o
-QMAKE_EXT_RES = _res.o
-
-
QMAKE_CC = $${CROSS_COMPILE}gcc
QMAKE_LEX = flex
QMAKE_LEXFLAGS =
@@ -27,12 +26,12 @@ QMAKE_YACC = bison -y
QMAKE_YACCFLAGS = -d
QMAKE_CFLAGS += -fno-keep-inline-dllexport
QMAKE_CFLAGS_WARN_ON += -Wextra
+
QMAKE_CFLAGS_SSE2 += -mstackrealign
QMAKE_CFLAGS_AESNI = -maes
QMAKE_CFLAGS_SHANI = -msha
QMAKE_CXX = $${CROSS_COMPILE}g++
-QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
QMAKE_CXXFLAGS_RTTI_ON = -frtti
QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti
QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads
@@ -56,6 +55,8 @@ equals(QMAKE_HOST.os, Windows) {
QMAKE_LINK_OBJECT_MAX = 10
QMAKE_LINK_OBJECT_SCRIPT = object_script
}
+QMAKE_EXT_OBJ = .o
+QMAKE_EXT_RES = _res.o
QMAKE_PREFIX_SHLIB =
QMAKE_EXTENSION_SHLIB = dll
QMAKE_PREFIX_STATICLIB = lib
diff --git a/mkspecs/win32-icc/qmake.conf b/mkspecs/win32-icc/qmake.conf
index 8c14a6609e..a539bfba72 100644
--- a/mkspecs/win32-icc/qmake.conf
+++ b/mkspecs/win32-icc/qmake.conf
@@ -17,9 +17,10 @@ QMAKE_CC = icl
QMAKE_CFLAGS = -nologo -Zm200 /Qprec /Qwd1744,1738,809,3373
QMAKE_CFLAGS_WARN_ON = -W3 /Qwd673
QMAKE_CFLAGS_WARN_OFF = -W0 /Qwd673
-QMAKE_CFLAGS_DEBUG = -Zi -MDd -Od
+QMAKE_CFLAGS_DEBUG = -Od -Zi -MDd
QMAKE_CFLAGS_LTCG = -Qipo
QMAKE_CFLAGS_DISABLE_LTCG = -Qno-ipo
+
QMAKE_CFLAGS_SSE2 = -QxSSE2
QMAKE_CFLAGS_SSE3 = -QxSSE3
QMAKE_CFLAGS_SSSE3 = -QxSSSE3
@@ -50,16 +51,10 @@ QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
QMAKE_CXXFLAGS_DISABLE_LTCG = $$QMAKE_CFLAGS_DISABLE_LTCG
QMAKE_LINK = xilink
-QMAKE_LFLAGS = /NOLOGO
-QMAKE_LFLAGS_RELEASE =
-QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO =
-QMAKE_LFLAGS_DEBUG = /DEBUG
QMAKE_LFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
QMAKE_LIB = xilib /NOLOGO
-DSP_EXTENSION = .dsp
-
include(../common/angle.conf)
include(../common/windows-vulkan.conf)
diff --git a/qmake/Makefile.unix.mingw b/qmake/Makefile.unix.mingw
index 2c52c07dca..6480171c69 100644
--- a/qmake/Makefile.unix.mingw
+++ b/qmake/Makefile.unix.mingw
@@ -9,7 +9,7 @@
# sh-compatible shell. This is not a problem, because configure.bat
# will not do that.
ifeq ($(SHELL), sh.exe)
- ifeq ($(wildcard $(CURDIR)/sh.exe), )
+ ifeq ($(wildcard ./sh.exe), )
SH = 0
else
SH = 1
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp
index 63926e7ef0..0622ace71b 100644
--- a/qmake/generators/mac/pbuilder_pbx.cpp
+++ b/qmake/generators/mac/pbuilder_pbx.cpp
@@ -280,8 +280,6 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
QMap<QString, QString> settings;
settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO"));
- if(as_release)
- settings.insert("GCC_GENERATE_DEBUGGING_SYMBOLS", "NO");
if(project->isActiveConfig("sdk") && !project->isEmpty("QMAKE_MAC_SDK"))
settings.insert("SDKROOT", project->first("QMAKE_MAC_SDK").toQString());
{
@@ -1499,7 +1497,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
settings.insert("APPLICATION_EXTENSION_API_ONLY", project->isActiveConfig("app_extension_api_only") ? "YES" : "NO");
// required for tvOS (and watchos), optional on iOS (deployment target >= iOS 6.0)
settings.insert("ENABLE_BITCODE", project->isActiveConfig("bitcode") ? "YES" : "NO");
- settings.insert("GCC_GENERATE_DEBUGGING_SYMBOLS", as_release ? "NO" : "YES");
if(!as_release)
settings.insert("GCC_OPTIMIZATION_LEVEL", "0");
if(project->isActiveConfig("sdk") && !project->isEmpty("QMAKE_MAC_SDK"))
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/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/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 bf44f2649d..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": "",
@@ -608,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/snippets/qstring/main.cpp b/src/corelib/doc/snippets/qstring/main.cpp
index 63918afbcd..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]
}
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index e1ca8828f9..0f8935d4b5 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -42,7 +42,10 @@ SOURCES += \
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/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 2c2dcb663b..0444926df5 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>
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 7623de8423..0861763492 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -61,7 +61,7 @@
#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>
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index ab83730caa..2a8345195d 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/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/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/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/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 350be50082..34a3d7ef7e 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -2196,11 +2196,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/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 3b0f7ead09..bc1af5d66f 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/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 2808ba2ced..c2b5afd241 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 3357e27037..8a6716a8f7 100644
--- a/src/corelib/thread/qfuturewatcher.h
+++ b/src/corelib/thread/qfuturewatcher.h
@@ -115,7 +115,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/qmap.h b/src/corelib/tools/qmap.h
index 16442014ff..b400e69f0c 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 4e59686d97..e63f1ce253 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -5517,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()
@@ -6042,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()
*/
/*!
@@ -8515,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:
@@ -8531,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)
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/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp
index f6ae3571ab..ef5fafbd76 100644
--- a/src/corelib/xml/qxmlstream.cpp
+++ b/src/corelib/xml/qxmlstream.cpp
@@ -3706,7 +3706,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/gui/configure.json b/src/gui/configure.json
index 2c1fe6c86e..a7f08f2cc0 100644
--- a/src/gui/configure.json
+++ b/src/gui/configure.json
@@ -722,6 +722,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",
@@ -952,7 +979,7 @@
"label": "IMF",
"emitIf": "config.qnx",
"condition": "libs.imf",
- "output": [ "privateConfig" ]
+ "output": [ "privateFeature" ]
},
"integrityfb": {
"label": "INTEGRITY framebuffer",
@@ -1119,11 +1146,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",
@@ -1610,7 +1647,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/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index b26567ad0c..5baadd425f 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -1767,6 +1767,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); }
@@ -2220,6 +2223,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)
@@ -2887,7 +2901,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 014ed861df..becaa7ceb3 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/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 ae39411729..7a4be7b8a8 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 dff8f618e2..cf5f38d249 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_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 2cecb444c3..c47d940e4a 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 b1ca6238cb..bd6416cc95 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -181,6 +181,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 6a1360a26a..f781d6e3b8 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 d74c4d0711..6b6a1e800e 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);
@@ -78,7 +80,7 @@ Q_GUI_EXPORT CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *
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
@@ -124,4 +126,6 @@ private:
QT_END_NAMESPACE
+#undef HAVE_APPKIT
+
#endif // QCOREGRAPHICS_P_H
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 67b765d9e6..d5a0261f43 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -1881,7 +1881,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)) {
@@ -1923,9 +1924,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 9be49da8a2..677da08cb6 100644
--- a/src/network/bearer/qbearerengine.cpp
+++ b/src/network/bearer/qbearerengine.cpp
@@ -93,7 +93,8 @@ bool QBearerEngine::configurationsInUse() const
|| hasUsedConfiguration(userChoiceConfigurations);
}
+QT_END_NAMESPACE
+
#include "moc_qbearerengine_p.cpp"
-QT_END_NAMESPACE
#endif // QT_NO_BEARERMANAGEMENT
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 d46fbfc101..770921f9a6 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/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/ssl/qsslkey_qt.cpp b/src/network/ssl/qsslkey_qt.cpp
index 3c5dc830d3..fd76d3353a 100644
--- a/src/network/ssl/qsslkey_qt.cpp
+++ b/src/network/ssl/qsslkey_qt.cpp
@@ -94,7 +94,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 8d2efe74be..5312464964 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/qdatastream.h>
#include <QtCore/qsysinfo.h>
@@ -1245,13 +1246,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 ca65f8a015..762b393738 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 38370c0e62..76233967e7 100644
--- a/src/platformsupport/eglconvenience/qeglpbuffer_p.h
+++ b/src/platformsupport/eglconvenience/qeglpbuffer_p.h
@@ -64,7 +64,7 @@ public:
~QEGLPbuffer();
QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; }
- bool isValid() const Q_DECL_OVERRIDE { return m_pbuffer != EGL_NO_SURFACE; }
+ bool isValid() const Q_DECL_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/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 2b4c4e3ceb..7e41e50a04 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 960f1d2f12..1046b86ec6 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 f14a2e8f04..3722c1ceca 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,8 @@ 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(Q_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 6879d0cd83..7ac4dbf6f3 100644
--- a/src/platformsupport/input/libinput/qlibinputpointer.cpp
+++ b/src/platformsupport/input/libinput/qlibinputpointer.cpp
@@ -41,6 +41,8 @@
#include <libinput.h>
#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>
@@ -78,7 +80,8 @@ void QLibInputPointer::processButton(libinput_event_pointer *e)
m_buttons.setFlag(button, pressed);
- QWindowSystemInterface::handleMouseEvent(Q_NULLPTR, m_pos, m_pos, m_buttons, QGuiApplication::keyboardModifiers());
+ QWindowSystemInterface::handleMouseEvent(Q_NULLPTR, m_pos, m_pos, m_buttons,
+ QGuiApplicationPrivate::inputDeviceManager()->keyboardModifiers());
}
void QLibInputPointer::processMotion(libinput_event_pointer *e)
@@ -91,7 +94,8 @@ 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()));
- QWindowSystemInterface::handleMouseEvent(Q_NULLPTR, m_pos, m_pos, m_buttons, QGuiApplication::keyboardModifiers());
+ QWindowSystemInterface::handleMouseEvent(Q_NULLPTR, m_pos, m_pos, m_buttons,
+ QGuiApplicationPrivate::inputDeviceManager()->keyboardModifiers());
}
void QLibInputPointer::processAxis(libinput_event_pointer *e)
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/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/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
index 0d9bb5009d..b986833f6d 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>
@@ -343,10 +344,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/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 7c8e1f9927..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(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 5b7917f7b4..ce50eff1d9 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/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 6f3f18af48..522cc032ff 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 9fcce42825..be0f301710 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 Q_DECL_OVERRIDE;
QRect availableGeometry() const Q_DECL_OVERRIDE;
int depth() const Q_DECL_OVERRIDE;
@@ -63,6 +69,7 @@ public:
QSizeF physicalSize() const Q_DECL_OVERRIDE;
QDpi logicalDpi() const Q_DECL_OVERRIDE;
qreal devicePixelRatio() const Q_DECL_OVERRIDE;
+ qreal refreshRate() const override;
Qt::ScreenOrientation nativeOrientation() const Q_DECL_OVERRIDE;
Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index 7c88cddd54..c394592d76 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -174,6 +174,41 @@ 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
@@ -245,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];
}
@@ -264,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]) {
@@ -396,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/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 da8a6aabdc..14fa2084c9 100644
--- a/src/plugins/platforms/ios/qioswindow.h
+++ b/src/plugins/platforms/ios/qioswindow.h
@@ -71,6 +71,8 @@ public:
bool isExposed() const Q_DECL_OVERRIDE;
void propagateSizeHints() Q_DECL_OVERRIDE {}
+ QMargins safeAreaMargins() const override;
+
void raise() Q_DECL_OVERRIDE{ raiseOrLower(true); }
void lower() Q_DECL_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 1500f0b41c..1ce9007a35 100644
--- a/src/plugins/platforms/ios/quiview.h
+++ b/src/plugins/platforms/ios/quiview.h
@@ -77,5 +77,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 a2ecc8c3cd..42e57d0f4f 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"
@@ -54,6 +55,24 @@
@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];
@@ -98,6 +117,22 @@
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;
@@ -197,6 +232,11 @@
QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region);
}
+- (void)safeAreaInsetsDidChange
+{
+ QWindowSystemInterface::handleSafeAreaMarginsChanged(m_qioswindow->window());
+}
+
// -------------------------------------------------------------------------
- (BOOL)canBecomeFirstResponder
@@ -354,7 +394,21 @@
- (void)sendTouchEventWithTimestamp:(ulong)timeStamp
{
QIOSIntegration *iosIntegration = QIOSIntegration::instance();
- QWindowSystemInterface::handleTouchEvent(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
@@ -540,6 +594,22 @@
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/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/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 ce6dd7c035..b2dcf7c3e7 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -761,8 +761,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/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/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp
index e399118cc9..b479ecacb1 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/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/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 52578126de..0cf2ed1f58 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/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index c7966f624f..c3c9bdf51c 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -2319,18 +2319,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);
@@ -2788,9 +2790,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;
@@ -3169,6 +3171,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 d6d0fd4322..e593d82576 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 2ee9d307c9..680c179bd9 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 4a86f87c71..37690b9719 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 d8d6eab7b1..34b12a74b2 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 e002b49d25..88c98f45f9 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 a721357ddc..494b28c909 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 c52e7f9fd4..49f97bcb61 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/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
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index a1ffe5b3ce..fbd89e4045 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -35,7 +35,7 @@ else:!qtConfig(process): SUBDIRS -= tools
# Disable the QtDBus tests if we can't connect to the session bus
!cross_compile:qtHaveModule(dbus) {
- !system("dbus-send --session --type=signal / local.AutotestCheck.Hello >/dev/null 2>&1") {
+ !system("dbus-send --session --type=signal / local.AutotestCheck.Hello >$$QMAKE_SYSTEM_NULL_DEVICE 2>&1") {
qtConfig(dbus-linked): \
error("QtDBus is enabled but session bus is not available. Please check the installation.")
else: \
diff --git a/tests/auto/corelib/animation/qpauseanimation/BLACKLIST b/tests/auto/corelib/animation/qpauseanimation/BLACKLIST
index 8fc1b07502..a49ed2a617 100644
--- a/tests/auto/corelib/animation/qpauseanimation/BLACKLIST
+++ b/tests/auto/corelib/animation/qpauseanimation/BLACKLIST
@@ -4,3 +4,5 @@ osx-10.9
*
[multipleSequentialGroups]
osx
+[noTimerUpdates]
+osx
diff --git a/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST b/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST
index a7e95b1e97..a8719b241a 100644
--- a/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST
+++ b/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST
@@ -2,3 +2,5 @@
windows
[startBackwardWithoutEndValue]
windows
+[startWithoutStartValue]
+osx
diff --git a/tests/auto/corelib/animation/qpropertyanimation/qpropertyanimation.pro b/tests/auto/corelib/animation/qpropertyanimation/qpropertyanimation.pro
index bfeb183abf..72a36876b7 100644
--- a/tests/auto/corelib/animation/qpropertyanimation/qpropertyanimation.pro
+++ b/tests/auto/corelib/animation/qpropertyanimation/qpropertyanimation.pro
@@ -1,4 +1,4 @@
CONFIG += testcase
TARGET = tst_qpropertyanimation
-QT = core gui widgets testlib
+QT = core gui widgets testlib core-private
SOURCES = tst_qpropertyanimation.cpp
diff --git a/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp
index cf4c4e1bdb..41a051a719 100644
--- a/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp
+++ b/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp
@@ -29,6 +29,7 @@
#include <QtTest/QtTest>
#include <QtCore/qpropertyanimation.h>
#include <QtCore/qvariantanimation.h>
+#include <private/qabstractanimation_p.h>
#include <QtGui/qtouchdevice.h>
#include <QtWidgets/qwidget.h>
@@ -74,6 +75,80 @@ public:
MyObject o;
};
+class TestAnimationDriver : public QAnimationDriver
+{
+public:
+ TestAnimationDriver()
+ : QAnimationDriver()
+ , m_elapsed(0)
+ {
+ QUnifiedTimer::instance()->installAnimationDriver(this);
+ }
+
+ ~TestAnimationDriver()
+ {
+ // This is to ensure that running animations are removed from the list of actual running
+ // animations.
+ QCoreApplication::sendPostedEvents();
+ QUnifiedTimer::instance()->uninstallAnimationDriver(this);
+ }
+
+ void wait(qint64 ms)
+ {
+ /*
+ * When QAbstractAnimation::start() is called it will end up calling
+ * QAnimationTimer::registerAnimation(). This will do
+ *
+ * QMetaObject::invokeMethod(inst, "startAnimations", Qt::QueuedConnection); // typeof(inst) == QAnimationTimer
+ *
+ * startAnimations() will again fire a queued connection to actually add the animation
+ * to the list of running animations:
+ *
+ * QMetaObject::invokeMethod(inst, "startTimers", Qt::QueuedConnection); // typeof(inst) == QUnifiedTimer
+ *
+ * We therefore have to call QCoreApplication::sendPostedEvents() twice here.
+ */
+ QCoreApplication::sendPostedEvents();
+ QCoreApplication::sendPostedEvents();
+
+ // Simulates the ideal animation update freqency (approx. 60Hz)
+ static const int interval = 1000/60;
+ qint64 until = m_elapsed + ms;
+ while (m_elapsed < until) {
+ advanceAnimation(m_elapsed);
+ m_elapsed += interval;
+ }
+ advanceAnimation(m_elapsed);
+ // This is to make sure that animations that were started with DeleteWhenStopped
+ // will actually delete themselves within the test function.
+ // Normally, they won't be deleted until the main event loop is processed.
+ // Therefore, have to explicitly say that we want to process DeferredDelete events. Same
+ // trick is used by QTest::qWait().
+ QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
+ }
+
+ qint64 elapsed() const override
+ {
+ return m_elapsed;
+ }
+
+ void start() override
+ {
+ d_func()->running = true;
+ m_elapsed = 0;
+ emit started();
+ }
+
+ void stop() override
+ {
+ d_func()->running = false;
+ emit stopped();
+ }
+
+private:
+ qint64 m_elapsed;
+ Q_DECLARE_PRIVATE(QAnimationDriver)
+};
class tst_QPropertyAnimation : public QObject
{
@@ -261,40 +336,44 @@ void tst_QPropertyAnimation::statesAndSignals()
QCOMPARE(currentLoopSpy.count(), 2);
runningSpy.clear();
- anim->start();
- QTest::qWait(1000);
- QTRY_COMPARE(anim->state(), QAnimationGroup::Stopped);
- QCOMPARE(runningSpy.count(), 2); //started and stopped again
- runningSpy.clear();
- QCOMPARE(finishedSpy.count(), 1);
- QCOMPARE(anim->currentLoopTime(), 100);
- QCOMPARE(anim->currentLoop(), 2);
- QCOMPARE(currentLoopSpy.count(), 4);
-
- anim->start(); // auto-rewinds
- QCOMPARE(anim->state(), QAnimationGroup::Running);
- QCOMPARE(anim->currentTime(), 0);
- QCOMPARE(anim->currentLoop(), 0);
- QCOMPARE(currentLoopSpy.count(), 5);
- QCOMPARE(runningSpy.count(), 1); // anim has started
- QCOMPARE(finishedSpy.count(), 1);
- QCOMPARE(anim->currentLoop(), 0);
- runningSpy.clear();
-
- QTest::qWait(1000);
-
- QCOMPARE(currentLoopSpy.count(), 7);
- QCOMPARE(anim->state(), QAnimationGroup::Stopped);
- QCOMPARE(anim->currentLoop(), 2);
- QCOMPARE(runningSpy.count(), 1); // anim has stopped
- QCOMPARE(finishedSpy.count(), 2);
- QCOMPARE(anim->currentLoopTime(), 100);
-
- delete anim;
+ {
+ TestAnimationDriver timeDriver;
+ anim->start();
+ timeDriver.wait(1000);
+ QCOMPARE(anim->state(), QAnimationGroup::Stopped);
+ QCOMPARE(runningSpy.count(), 2); //started and stopped again
+ runningSpy.clear();
+ QCOMPARE(finishedSpy.count(), 1);
+ QCOMPARE(anim->currentLoopTime(), 100);
+ QCOMPARE(anim->currentLoop(), 2);
+ QCOMPARE(currentLoopSpy.count(), 4);
+
+ anim->start(); // auto-rewinds
+ QCOMPARE(anim->state(), QAnimationGroup::Running);
+ QCOMPARE(anim->currentTime(), 0);
+ QCOMPARE(anim->currentLoop(), 0);
+ QCOMPARE(currentLoopSpy.count(), 5);
+ QCOMPARE(runningSpy.count(), 1); // anim has started
+ QCOMPARE(finishedSpy.count(), 1);
+ QCOMPARE(anim->currentLoop(), 0);
+ runningSpy.clear();
+
+ timeDriver.wait(1000);
+
+ QCOMPARE(currentLoopSpy.count(), 7);
+ QCOMPARE(anim->state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim->currentLoop(), 2);
+ QCOMPARE(runningSpy.count(), 1); // anim has stopped
+ QCOMPARE(finishedSpy.count(), 2);
+ QCOMPARE(anim->currentLoopTime(), 100);
+
+ delete anim;
+ }
}
void tst_QPropertyAnimation::deletion1()
{
+ TestAnimationDriver timeDriver;
QObject *object = new QWidget;
QPointer<QPropertyAnimation> anim = new QPropertyAnimation(object, "minimumWidth");
@@ -312,23 +391,23 @@ void tst_QPropertyAnimation::deletion1()
QVERIFY(anim);
QCOMPARE(anim->state(), QAnimationGroup::Running);
- QTest::qWait(100);
+ timeDriver.wait(100);
QVERIFY(anim);
QCOMPARE(anim->state(), QAnimationGroup::Running);
- QTest::qWait(150);
+ timeDriver.wait(150);
QVERIFY(anim); //The animation should not have been deleted
- QTRY_COMPARE(anim->state(), QAnimationGroup::Stopped);
+ QCOMPARE(anim->state(), QAnimationGroup::Stopped);
QCOMPARE(runningSpy.count(), 2);
QCOMPARE(finishedSpy.count(), 1);
anim->start(QVariantAnimation::DeleteWhenStopped);
QVERIFY(anim);
QCOMPARE(anim->state(), QAnimationGroup::Running);
- QTest::qWait(100);
+ timeDriver.wait(100);
QVERIFY(anim);
QCOMPARE(anim->state(), QAnimationGroup::Running);
- QTest::qWait(150);
- QTRY_COMPARE(runningSpy.count(), 4);
+ timeDriver.wait(150);
+ QCOMPARE(runningSpy.count(), 4);
QCOMPARE(finishedSpy.count(), 2);
QVERIFY(!anim); //The animation must have been deleted
delete object;
@@ -336,6 +415,7 @@ void tst_QPropertyAnimation::deletion1()
void tst_QPropertyAnimation::deletion2()
{
+ TestAnimationDriver timeDriver;
//test that the animation get deleted if the object is deleted
QObject *object = new QWidget;
QPointer<QPropertyAnimation> anim = new QPropertyAnimation(object,"minimumWidth");
@@ -354,7 +434,7 @@ void tst_QPropertyAnimation::deletion2()
anim->setDuration(200);
anim->start();
- QTest::qWait(50);
+ timeDriver.wait(50);
QVERIFY(anim);
QCOMPARE(anim->state(), QAnimationGroup::Running);
@@ -363,7 +443,7 @@ void tst_QPropertyAnimation::deletion2()
//we can't call deletaLater directly because the delete would only happen in the next loop of _this_ event loop
QTimer::singleShot(0, object, SLOT(deleteLater()));
- QTest::qWait(50);
+ timeDriver.wait(50);
QVERIFY(!anim->targetObject());
}
@@ -371,6 +451,7 @@ void tst_QPropertyAnimation::deletion2()
void tst_QPropertyAnimation::deletion3()
{
//test that the stopped signal is emit when the animation is destroyed
+ TestAnimationDriver timeDriver;
QObject *object = new QWidget;
QPropertyAnimation *anim = new QPropertyAnimation(object,"minimumWidth");
anim->setStartValue(10);
@@ -385,7 +466,7 @@ void tst_QPropertyAnimation::deletion3()
anim->start();
- QTest::qWait(50);
+ timeDriver.wait(50);
QCOMPARE(anim->state(), QAnimationGroup::Running);
QCOMPARE(runningSpy.count(), 1);
QCOMPARE(finishedSpy.count(), 0);
@@ -432,6 +513,7 @@ public:
void tst_QPropertyAnimation::noStartValue()
{
+ TestAnimationDriver timeDriver;
StartValueTester o;
o.setProperty("ole", 42);
o.values.clear();
@@ -441,7 +523,8 @@ void tst_QPropertyAnimation::noStartValue()
a.setDuration(250);
a.start();
- QTRY_COMPARE(o.values.value(o.values.size() - 1, -1), 420);
+ timeDriver.wait(a.duration());
+ QCOMPARE(o.values.value(o.values.size() - 1, -1), 420);
QCOMPARE(o.values.first(), 42);
}
@@ -471,6 +554,7 @@ void tst_QPropertyAnimation::startWhenAnotherIsRunning()
StartValueTester o;
o.setProperty("ole", 42);
o.values.clear();
+ TestAnimationDriver timeDriver;
{
//normal case: the animation finishes and is deleted
@@ -479,18 +563,17 @@ void tst_QPropertyAnimation::startWhenAnotherIsRunning()
QSignalSpy runningSpy(anim.data(), &QVariantAnimation::stateChanged);
QVERIFY(runningSpy.isValid());
anim->start(QVariantAnimation::DeleteWhenStopped);
- QTest::qWait(anim->duration() + 100);
- QTRY_COMPARE(runningSpy.count(), 2); //started and then stopped
+ timeDriver.wait(anim->duration());
+ QCOMPARE(runningSpy.count(), 2); //started and then stopped
QVERIFY(!anim);
}
-
{
QPointer<QVariantAnimation> anim = new QPropertyAnimation(&o, "ole");
anim->setEndValue(100);
QSignalSpy runningSpy(anim.data(), &QVariantAnimation::stateChanged);
QVERIFY(runningSpy.isValid());
anim->start(QVariantAnimation::DeleteWhenStopped);
- QTest::qWait(anim->duration()/2);
+ timeDriver.wait(anim->duration()/2);
QPointer<QVariantAnimation> anim2 = new QPropertyAnimation(&o, "ole");
anim2->setEndValue(100);
QCOMPARE(runningSpy.count(), 1);
@@ -498,11 +581,11 @@ void tst_QPropertyAnimation::startWhenAnotherIsRunning()
//anim2 will interrupt anim1
QMetaObject::invokeMethod(anim2, "start", Qt::QueuedConnection, Q_ARG(QAbstractAnimation::DeletionPolicy, QVariantAnimation::DeleteWhenStopped));
- QTest::qWait(50);
+ timeDriver.wait(50);
QVERIFY(!anim); //anim should have been deleted
QVERIFY(anim2);
- QTest::qWait(anim2->duration());
- QTRY_VERIFY(!anim2); //anim2 is finished: it should have been deleted by now
+ timeDriver.wait(anim2->duration());
+ QVERIFY(!anim2); //anim2 is finished: it should have been deleted by now
QVERIFY(!anim);
}
@@ -559,6 +642,7 @@ void tst_QPropertyAnimation::easingcurve()
void tst_QPropertyAnimation::startWithoutStartValue()
{
+ TestAnimationDriver timeDriver;
QObject o;
o.setProperty("ole", 42);
QCOMPARE(o.property("ole").toInt(), 42);
@@ -568,14 +652,14 @@ void tst_QPropertyAnimation::startWithoutStartValue()
anim.start();
- QTest::qWait(100);
+ timeDriver.wait(100);
int current = anim.currentValue().toInt();
//it is somewhere in the animation
QVERIFY(current > 42);
QVERIFY(current < 100);
- QTest::qWait(200);
- QTRY_COMPARE(anim.state(), QVariantAnimation::Stopped);
+ timeDriver.wait(200);
+ QCOMPARE(anim.state(), QVariantAnimation::Stopped);
current = anim.currentValue().toInt();
QCOMPARE(current, 100);
QCOMPARE(o.property("ole").toInt(), current);
@@ -586,7 +670,7 @@ void tst_QPropertyAnimation::startWithoutStartValue()
// the default start value will reevaluate the current property
// and set it to the end value of the last iteration
QCOMPARE(current, 100);
- QTest::qWait(100);
+ timeDriver.wait(100);
current = anim.currentValue().toInt();
//it is somewhere in the animation
QVERIFY(current >= 100);
@@ -595,6 +679,7 @@ void tst_QPropertyAnimation::startWithoutStartValue()
void tst_QPropertyAnimation::startBackwardWithoutEndValue()
{
+ TestAnimationDriver timeDriver;
QObject o;
o.setProperty("ole", 42);
QCOMPARE(o.property("ole").toInt(), 42);
@@ -608,14 +693,14 @@ void tst_QPropertyAnimation::startBackwardWithoutEndValue()
QCOMPARE(anim.state(), QAbstractAnimation::Running);
QCOMPARE(o.property("ole").toInt(), 42); //the initial value
- QTest::qWait(100);
+ timeDriver.wait(100);
int current = anim.currentValue().toInt();
//it is somewhere in the animation
QVERIFY(current > 42);
QVERIFY(current < 100);
- QTest::qWait(200);
- QTRY_COMPARE(anim.state(), QVariantAnimation::Stopped);
+ timeDriver.wait(200);
+ QCOMPARE(anim.state(), QVariantAnimation::Stopped);
current = anim.currentValue().toInt();
QCOMPARE(current, 100);
QCOMPARE(o.property("ole").toInt(), current);
@@ -626,7 +711,7 @@ void tst_QPropertyAnimation::startBackwardWithoutEndValue()
// the default start value will reevaluate the current property
// and set it to the end value of the last iteration
QCOMPARE(current, 100);
- QTest::qWait(100);
+ timeDriver.wait(100);
current = anim.currentValue().toInt();
//it is somewhere in the animation
QVERIFY(current >= 100);
@@ -636,6 +721,7 @@ void tst_QPropertyAnimation::startBackwardWithoutEndValue()
void tst_QPropertyAnimation::playForwardBackward()
{
+ TestAnimationDriver timeDriver;
QObject o;
o.setProperty("ole", 0);
QCOMPARE(o.property("ole").toInt(), 0);
@@ -644,16 +730,16 @@ void tst_QPropertyAnimation::playForwardBackward()
anim.setStartValue(0);
anim.setEndValue(100);
anim.start();
- QTest::qWait(anim.duration() + 100);
- QTRY_COMPARE(anim.state(), QAbstractAnimation::Stopped);
+ timeDriver.wait(anim.duration());
+ QCOMPARE(anim.state(), QAbstractAnimation::Stopped);
QCOMPARE(anim.currentTime(), anim.duration());
//the animation is at the end
anim.setDirection(QVariantAnimation::Backward);
anim.start();
QCOMPARE(anim.state(), QAbstractAnimation::Running);
- QTest::qWait(anim.duration() + 100);
- QTRY_COMPARE(anim.state(), QAbstractAnimation::Stopped);
+ timeDriver.wait(anim.duration());
+ QCOMPARE(anim.state(), QAbstractAnimation::Stopped);
QCOMPARE(anim.currentTime(), 0);
//the direction is backward
@@ -661,8 +747,8 @@ void tst_QPropertyAnimation::playForwardBackward()
anim.start();
QCOMPARE(anim.state(), QAbstractAnimation::Running);
QCOMPARE(anim.currentTime(), anim.duration());
- QTest::qWait(anim.duration() + 100);
- QTRY_COMPARE(anim.state(), QAbstractAnimation::Stopped);
+ timeDriver.wait(anim.duration());
+ QCOMPARE(anim.state(), QAbstractAnimation::Stopped);
QCOMPARE(anim.currentTime(), 0);
}
@@ -1106,21 +1192,21 @@ void tst_QPropertyAnimation::restart()
void tst_QPropertyAnimation::valueChanged()
{
-
+ TestAnimationDriver timeDriver;
//we check that we receive the valueChanged signal
MyErrorObject o;
o.setOle(0);
QCOMPARE(o.property("ole").toInt(), 0);
QPropertyAnimation anim(&o, "ole");
anim.setEndValue(5);
- anim.setDuration(1000);
+ anim.setDuration(200);
QSignalSpy spy(&anim, &QPropertyAnimation::valueChanged);
QVERIFY(spy.isValid());
anim.start();
+ // Drive animation forward to its end
+ timeDriver.wait(anim.duration());
- QTest::qWait(anim.duration() + 100);
-
- QTRY_COMPARE(anim.state(), QAbstractAnimation::Stopped);
+ QCOMPARE(anim.state(), QAbstractAnimation::Stopped);
QCOMPARE(anim.currentTime(), anim.duration());
//let's check that the values go forward
@@ -1153,6 +1239,7 @@ public:
void tst_QPropertyAnimation::twoAnimations()
{
+ TestAnimationDriver timeDriver;
MySyncObject o1, o2;
o1.setOle(0);
o2.setOle(0);
@@ -1169,8 +1256,8 @@ void tst_QPropertyAnimation::twoAnimations()
o1.anim.start();
o2.anim.start();
- QTest::qWait(o1.anim.duration() + 100);
- QTRY_COMPARE(o1.anim.state(), QAbstractAnimation::Stopped);
+ timeDriver.wait(o1.anim.duration());
+ QCOMPARE(o1.anim.state(), QAbstractAnimation::Stopped);
QCOMPARE(o2.anim.state(), QAbstractAnimation::Stopped);
QCOMPARE(o1.ole(), 1000);
@@ -1209,6 +1296,7 @@ public:
void tst_QPropertyAnimation::deletedInUpdateCurrentTime()
{
+ TestAnimationDriver timeDriver;
// this test case reproduces an animation being deleted in the updateCurrentTime of
// another animation(was causing segfault).
// the deleted animation must have been started after the animation that is deleting.
@@ -1219,9 +1307,9 @@ void tst_QPropertyAnimation::deletedInUpdateCurrentTime()
MyComposedAnimation composedAnimation(&o, "value", "realValue");
composedAnimation.start();
QCOMPARE(composedAnimation.state(), QAbstractAnimation::Running);
- QTest::qWait(composedAnimation.duration() + 100);
+ timeDriver.wait(composedAnimation.duration());
- QTRY_COMPARE(composedAnimation.state(), QAbstractAnimation::Stopped);
+ QCOMPARE(composedAnimation.state(), QAbstractAnimation::Stopped);
QCOMPARE(o.value(), 1000);
}
@@ -1293,6 +1381,7 @@ public:
void tst_QPropertyAnimation::recursiveAnimations()
{
+ TestAnimationDriver timeDriver;
RecursiveObject o;
QPropertyAnimation anim;
anim.setTargetObject(&o);
@@ -1301,9 +1390,9 @@ void tst_QPropertyAnimation::recursiveAnimations()
anim.setEndValue(4000);
anim.start();
- QTest::qWait(anim.duration() + o.animation.duration());
- QTRY_COMPARE(anim.state(), QAbstractAnimation::Stopped);
- QTRY_COMPARE(o.animation.state(), QAbstractAnimation::Stopped);
+ timeDriver.wait(anim.duration() + o.animation.duration());
+ QCOMPARE(anim.state(), QAbstractAnimation::Stopped);
+ QCOMPARE(o.animation.state(), QAbstractAnimation::Stopped);
QCOMPARE(o.y(), qreal(4000));
}
diff --git a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp
index 9bd87e3f21..6b98e3a823 100644
--- a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp
+++ b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp
@@ -158,12 +158,14 @@ void tst_qfloat16::qNan()
qfloat16 nan = qQNaN();
QVERIFY(!(0. > nan));
QVERIFY(!(0. < nan));
+ QVERIFY(!qIsInf(nan));
QVERIFY(qIsNaN(nan));
QVERIFY(qIsNaN(nan + 1.f));
QVERIFY(qIsNaN(-nan));
qfloat16 inf = qInf();
QVERIFY(inf > qfloat16(0));
QVERIFY(-inf < qfloat16(0));
+ QVERIFY(!qIsNaN(inf));
QVERIFY(qIsInf(inf));
QVERIFY(qIsInf(-inf));
QVERIFY(qIsInf(2.f*inf));
diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
index 44e79985d4..02b70c317e 100644..100755
--- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
+++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
@@ -64,6 +64,15 @@
#define Q_NO_SYMLINKS
#endif
+#if defined(Q_OS_WIN)
+QT_BEGIN_NAMESPACE
+extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;
+QT_END_NAMESPACE
+# ifndef Q_OS_WINRT
+bool IsUserAdmin();
+# endif
+#endif
+
inline bool qIsLikelyToBeFat(const QString &path)
{
QByteArray name = QStorageInfo(path).fileSystemType().toLower();
@@ -1592,6 +1601,15 @@ void tst_QFileInfo::isWritable()
QVERIFY2(fi.exists(), msgDoesNotExist(fi.absoluteFilePath()).constData());
QVERIFY(!fi.isWritable());
#endif
+
+#if defined (Q_OS_WIN) && !defined(Q_OS_WINRT)
+ QScopedValueRollback<int> ntfsMode(qt_ntfs_permission_lookup);
+ qt_ntfs_permission_lookup = 1;
+ QFileInfo fi2(QFile::decodeName(qgetenv("SystemRoot") + "/system.ini"));
+ QVERIFY(fi2.exists());
+ QCOMPARE(fi2.isWritable(), IsUserAdmin());
+#endif
+
#if defined (Q_OS_QNX) // On QNX /etc is usually on a read-only filesystem
QVERIFY(!QFileInfo("/etc/passwd").isWritable());
#elif defined (Q_OS_UNIX) && !defined(Q_OS_VXWORKS) // VxWorks does not have users/groups
@@ -1765,7 +1783,7 @@ void tst_QFileInfo::detachingOperations()
}
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
-BOOL IsUserAdmin()
+bool IsUserAdmin()
{
BOOL b;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
@@ -1783,13 +1801,9 @@ BOOL IsUserAdmin()
FreeSid(AdministratorsGroup);
}
- return(b);
+ return b != FALSE;
}
-QT_BEGIN_NAMESPACE
-extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;
-QT_END_NAMESPACE
-
#endif // Q_OS_WIN && !Q_OS_WINRT
#ifndef Q_OS_WINRT
diff --git a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp
index 15c63d4acd..a74ea3a89e 100644
--- a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp
+++ b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp
@@ -212,7 +212,7 @@ private slots:
qunsetenv("QT_LOGGING_RULES");
qputenv("QT_LOGGING_CONF", QFINDTESTDATA("qtlogging.ini").toLocal8Bit());
- registry.initalizeRules();
+ registry.initializeRules();
QCOMPARE(registry.ruleSets[QLoggingRegistry::ApiRules].size(), 0);
QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 0);
@@ -220,7 +220,7 @@ private slots:
// check that QT_LOGGING_RULES take precedence
qputenv("QT_LOGGING_RULES", "Digia.*=true");
- registry.initalizeRules();
+ registry.initializeRules();
QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].size(), 2);
QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].at(1).enabled, true);
}
@@ -246,7 +246,7 @@ private slots:
file.close();
QLoggingRegistry registry;
- registry.initalizeRules();
+ registry.initializeRules();
QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 1);
// remove file again
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index 5ecdd92228..1f98f64340 100644
--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
@@ -151,6 +151,7 @@ private slots:
void deleteLaterInAboutToBlockHandler();
void mutableFunctor();
void checkArgumentsForNarrowing();
+ void nullReceiver();
};
struct QObjectCreatedOnShutdown
@@ -7422,6 +7423,16 @@ void tst_QObject::checkArgumentsForNarrowing()
#undef FITS
}
+void tst_QObject::nullReceiver()
+{
+ QObject o;
+ QObject *nullObj = nullptr; // Passing nullptr directly doesn't compile with gcc 4.8
+ QVERIFY(!connect(&o, &QObject::destroyed, nullObj, &QObject::deleteLater));
+ QVERIFY(!connect(&o, &QObject::destroyed, nullObj, [] {}));
+ QVERIFY(!connect(&o, &QObject::destroyed, nullObj, Functor_noexcept()));
+ QVERIFY(!connect(&o, SIGNAL(destroyed()), nullObj, SLOT(deleteLater())));
+}
+
// Test for QtPrivate::HasQ_OBJECT_Macro
Q_STATIC_ASSERT(QtPrivate::HasQ_OBJECT_Macro<tst_QObject>::Value);
Q_STATIC_ASSERT(!QtPrivate::HasQ_OBJECT_Macro<SiblingDeleter>::Value);
diff --git a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp
index 8f0d83ce32..7ea467b6ef 100644
--- a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp
+++ b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp
@@ -101,6 +101,7 @@ Q_OBJECT
public:
SignalEmitter(QObject *parent = 0)
: QObject(parent) {}
+public Q_SLOTS:
void emitSignalWithNoArg()
{ emit signalWithNoArg(); }
void emitSignalWithIntArg(int arg)
@@ -251,6 +252,7 @@ private slots:
void qtbug_46059();
void qtbug_46703();
void postEventFromBeginSelectTransitions();
+ void dontProcessSlotsWhenMachineIsNotRunning();
};
class TestState : public QState
@@ -6658,5 +6660,35 @@ void tst_QStateMachine::postEventFromBeginSelectTransitions()
QVERIFY(machine.isRunning());
}
+void tst_QStateMachine::dontProcessSlotsWhenMachineIsNotRunning()
+{
+ QStateMachine machine;
+ QState initialState;
+ QFinalState finalState;
+
+ struct Emitter : SignalEmitter
+ {
+ QThread thread;
+ Emitter(QObject *parent = nullptr) : SignalEmitter(parent)
+ {
+ moveToThread(&thread);
+ thread.start();
+ }
+ } emitter;
+
+ initialState.addTransition(&emitter, &Emitter::signalWithNoArg, &finalState);
+ QTimer::singleShot(0, [&]() {
+ metaObject()->invokeMethod(&emitter, "emitSignalWithNoArg");
+ metaObject()->invokeMethod(&emitter, "emitSignalWithNoArg");
+ });
+ machine.addState(&initialState);
+ machine.addState(&finalState);
+ machine.setInitialState(&initialState);
+ machine.start();
+ connect(&machine, &QStateMachine::finished, &emitter.thread, &QThread::quit);
+ QSignalSpy signalSpy(&machine, &QStateMachine::finished);
+ QTRY_COMPARE_WITH_TIMEOUT(signalSpy.count(), 1, 100);
+}
+
QTEST_MAIN(tst_QStateMachine)
#include "tst_qstatemachine.moc"
diff --git a/tests/auto/corelib/tools/qdatetime/BLACKLIST b/tests/auto/corelib/tools/qdatetime/BLACKLIST
new file mode 100644
index 0000000000..e78f5cfd87
--- /dev/null
+++ b/tests/auto/corelib/tools/qdatetime/BLACKLIST
@@ -0,0 +1,3 @@
+[operator_eqeq]
+ubuntu-16.04
+b2qt
diff --git a/tests/auto/network/socket/qudpsocket/BLACKLIST b/tests/auto/network/socket/qudpsocket/BLACKLIST
index 5b8d4f1e34..d58a850a1f 100644
--- a/tests/auto/network/socket/qudpsocket/BLACKLIST
+++ b/tests/auto/network/socket/qudpsocket/BLACKLIST
@@ -18,7 +18,12 @@ osx
osx
[broadcasting]
osx
+ubuntu-16.04
[zeroLengthDatagram]
osx
[linkLocalIPv6]
redhatenterpriselinuxworkstation-6.6
+[pendingDatagramSize]
+ubuntu-16.04
+[readyReadForEmptyDatagram]
+ubuntu-16.04
diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp
index 4e800dfd63..bbac03b708 100644
--- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp
+++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp
@@ -55,6 +55,13 @@
#include <errno.h>
#endif
+#ifdef Q_OS_UNIX
+# include <sys/socket.h>
+#endif
+#if defined(Q_OS_LINUX) || defined(Q_OS_WIN) || defined(SO_NREAD)
+# define RELIABLE_BYTES_AVAILABLE
+#endif
+
Q_DECLARE_METATYPE(QHostAddress)
QT_FORWARD_DECLARE_CLASS(QUdpSocket)
@@ -1678,7 +1685,7 @@ void tst_QUdpSocket::linkLocalIPv4()
foreach (QNetworkAddressEntry addr, iface.addressEntries()) {
if (addr.ip().isInSubnet(localMask, 16)) {
addresses << addr.ip();
- qDebug() << addr.ip();
+ qDebug() << "Found IPv4 link local address" << addr.ip();
}
}
}
@@ -1703,7 +1710,6 @@ void tst_QUdpSocket::linkLocalIPv4()
QVERIFY(s->writeDatagram(testData, s->localAddress(), neutral.localPort()));
QVERIFY2(neutral.waitForReadyRead(10000), QtNetworkSettings::msgSocketError(neutral).constData());
- QVERIFY2(s->waitForReadyRead(10000), QtNetworkSettings::msgSocketError(*s).constData());
QNetworkDatagram dgram = neutral.receiveDatagram(testData.length() * 2);
QVERIFY(dgram.isValid());
QCOMPARE(dgram.senderAddress(), s->localAddress());
@@ -1726,7 +1732,7 @@ void tst_QUdpSocket::linkLocalIPv4()
}
QVERIFY(neutral.writeDatagram(dgram.makeReply(testData)));
-
+ QVERIFY2(s->waitForReadyRead(10000), QtNetworkSettings::msgSocketError(*s).constData());
dgram = s->receiveDatagram(testData.length() * 2);
QVERIFY(dgram.isValid());
QCOMPARE(dgram.data(), testData);
@@ -1764,7 +1770,9 @@ void tst_QUdpSocket::readyRead()
// make sure only one signal was emitted
QCOMPARE(spy.count(), 1);
QVERIFY(receiver.hasPendingDatagrams());
+#ifdef RELIABLE_BYTES_AVAILABLE
QCOMPARE(receiver.bytesAvailable(), qint64(2));
+#endif
QCOMPARE(receiver.pendingDatagramSize(), qint64(2));
// write another datagram
@@ -1786,7 +1794,9 @@ void tst_QUdpSocket::readyRead()
QTest::qWait(100);
QCOMPARE(spy.count(), 2);
QVERIFY(receiver.hasPendingDatagrams());
+#ifdef RELIABLE_BYTES_AVAILABLE
QCOMPARE(receiver.bytesAvailable(), qint64(3));
+#endif
QCOMPARE(receiver.pendingDatagramSize(), qint64(3));
}
@@ -1814,7 +1824,9 @@ void tst_QUdpSocket::readyReadForEmptyDatagram()
char buf[1];
QVERIFY(receiver.hasPendingDatagrams());
QCOMPARE(receiver.pendingDatagramSize(), qint64(0));
+#ifdef RELIABLE_BYTES_AVAILABLE
QCOMPARE(receiver.bytesAvailable(), qint64(0));
+#endif
QCOMPARE(receiver.readDatagram(buf, sizeof buf), qint64(0));
}
@@ -1823,7 +1835,9 @@ void tst_QUdpSocket::async_readDatagramSlot()
char buf[1];
QVERIFY(m_asyncReceiver->hasPendingDatagrams());
QCOMPARE(m_asyncReceiver->pendingDatagramSize(), qint64(1));
+#ifdef RELIABLE_BYTES_AVAILABLE
QCOMPARE(m_asyncReceiver->bytesAvailable(), qint64(1));
+#endif
QCOMPARE(m_asyncReceiver->readDatagram(buf, sizeof(buf)), qint64(1));
if (buf[0] == '2') {
diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
index 31df66e312..979d5c632e 100644
--- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
+++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
@@ -239,13 +239,18 @@ void tst_QFileSystemModel::readOnly()
QCOMPARE(model->isReadOnly(), true);
QTemporaryFile file(flatDirTestPath + QStringLiteral("/XXXXXX.dat"));
QVERIFY2(file.open(), qPrintable(file.errorString()));
+ const QString fileName = file.fileName();
+ file.close();
+
+ const QFileInfo fileInfo(fileName);
+ QTRY_VERIFY(QDir(flatDirTestPath).entryInfoList().contains(fileInfo));
QModelIndex root = model->setRootPath(flatDirTestPath);
QTRY_VERIFY(model->rowCount(root) > 0);
- QVERIFY(!(model->flags(model->index(file.fileName())) & Qt::ItemIsEditable));
+ QVERIFY(!(model->flags(model->index(fileName)) & Qt::ItemIsEditable));
model->setReadOnly(false);
QCOMPARE(model->isReadOnly(), false);
- QVERIFY(model->flags(model->index(file.fileName())) & Qt::ItemIsEditable);
+ QVERIFY(model->flags(model->index(fileName)) & Qt::ItemIsEditable);
}
class CustomFileIconProvider : public QFileIconProvider
@@ -729,6 +734,9 @@ void tst_QFileSystemModel::sortPersistentIndex()
{
QTemporaryFile file(flatDirTestPath + QStringLiteral("/XXXXXX.dat"));
QVERIFY2(file.open(), qPrintable(file.errorString()));
+ const QFileInfo fileInfo(file.fileName());
+ file.close();
+ QTRY_VERIFY(QDir(flatDirTestPath).entryInfoList().contains(fileInfo));
QModelIndex root = model->setRootPath(flatDirTestPath);
QTRY_VERIFY(model->rowCount(root) > 0);
diff --git a/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp
index a1cb729849..dfe5baba71 100644
--- a/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp
+++ b/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp
@@ -52,6 +52,7 @@ private slots:
void boundingRect2();
void draw();
void opacity();
+ void nestedOpaqueOpacity();
void grayscale();
void colorize();
void drawPixmapItem();
@@ -407,6 +408,26 @@ void tst_QGraphicsEffect::opacity()
QCOMPARE(effect->m_opacity, qreal(0.5));
}
+void tst_QGraphicsEffect::nestedOpaqueOpacity()
+{
+ // QTBUG-60231: Nesting widgets with a QGraphicsEffect on a toplevel with
+ // QGraphicsOpacityEffect caused crashes due to constructing several
+ // QPainter instances on a device in the fast path for
+ // QGraphicsOpacityEffect::opacity=1
+ QWidget topLevel;
+ topLevel.setWindowTitle(QTest::currentTestFunction());
+ topLevel.resize(320, 200);
+ QGraphicsOpacityEffect *opacityEffect = new QGraphicsOpacityEffect;
+ opacityEffect->setOpacity(1);
+ topLevel.setGraphicsEffect(opacityEffect);
+ QWidget *child = new QWidget(&topLevel);
+ child->resize(topLevel.size() / 2);
+ QGraphicsDropShadowEffect *childEffect = new QGraphicsDropShadowEffect;
+ child->setGraphicsEffect(childEffect);
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+}
+
void tst_QGraphicsEffect::grayscale()
{
if (qApp->desktop()->depth() < 24)
diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
index b2e1a2d9b5..4c6dd341b3 100644
--- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
+++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
@@ -332,6 +332,17 @@ public:
endRemoveColumns();
}
+ void removeAddLastColumnLayoutChanged() // for taskQTBUG_41124
+ {
+ // make sure QHeaderView::_q_layoutChanged() is called
+ emit layoutAboutToBeChanged();
+ --cols;
+ emit layoutChanged();
+ emit layoutAboutToBeChanged();
+ ++cols;
+ emit layoutChanged();
+ }
+
void removeAllColumns()
{
beginRemoveColumns(QModelIndex(), 0, cols - 1);
@@ -1326,6 +1337,19 @@ void tst_QTreeView::columnHidden()
for (int c = 0; c < model.columnCount(); ++c)
QCOMPARE(view.isColumnHidden(c), true);
view.update();
+
+ // QTBUG_41124:
+ // QHeaderViewPrivate::_q_layoutChanged was not called because it was
+ // disconnected in QTreeView::setModel(). _q_layoutChanged restores
+ // the hidden sections which is tested here
+ view.setColumnHidden(model.cols - 1, true);
+ model.removeAddLastColumnLayoutChanged();
+ // we removed the last column and added a new one
+ // (with layoutToBeChanged/layoutChanged() for both) so column
+ // 1 is a new column and therefore must not be hidden when
+ // _q_layoutChanged() is called and is doing the right stuff
+ QCOMPARE(view.isColumnHidden(model.cols - 1), false);
+
}
void tst_QTreeView::rowHidden()
diff --git a/tests/auto/widgets/widgets/qsplitter/BLACKLIST b/tests/auto/widgets/widgets/qsplitter/BLACKLIST
new file mode 100644
index 0000000000..1352805cd7
--- /dev/null
+++ b/tests/auto/widgets/widgets/qsplitter/BLACKLIST
@@ -0,0 +1,2 @@
+[replaceWidget:visible, not collapsed]
+xcb
diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp
index c995a40343..fe6d4fbca1 100644
--- a/util/unicode/main.cpp
+++ b/util/unicode/main.cpp
@@ -1293,6 +1293,18 @@ static void readArabicShaping()
{
qDebug("Reading ArabicShaping.txt");
+ // Initialize defaults:
+ // Code points that are not explicitly listed in ArabicShaping.txt are either of joining type T or U:
+ // - Those that not explicitly listed that are of General Category Mn, Me, or Cf have joining type T.
+ // - All others not explicitly listed have joining type U.
+ for (int codepoint = 0; codepoint <= QChar::LastValidCodePoint; ++codepoint) {
+ UnicodeData &d = UnicodeData::valueRef(codepoint);
+ if (d.p.joining == QChar::Joining_None) {
+ if (d.p.category == QChar::Mark_NonSpacing || d.p.category == QChar::Mark_Enclosing || d.p.category == QChar::Other_Format)
+ d.p.joining = QChar::Joining_Transparent;
+ }
+ }
+
QFile f("data/ArabicShaping.txt");
if (!f.exists())
qFatal("Couldn't find ArabicShaping.txt");
@@ -1338,17 +1350,6 @@ static void readArabicShaping()
break;
}
}
-
- // Code points that are not explicitly listed in ArabicShaping.txt are either of joining type T or U:
- // - Those that not explicitly listed that are of General Category Mn, Me, or Cf have joining type T.
- // - All others not explicitly listed have joining type U.
- for (int codepoint = 0; codepoint <= QChar::LastValidCodePoint; ++codepoint) {
- UnicodeData &d = UnicodeData::valueRef(codepoint);
- if (d.p.joining == QChar::Joining_None) {
- if (d.p.category == QChar::Mark_NonSpacing || d.p.category == QChar::Mark_Enclosing || d.p.category == QChar::Other_Format)
- d.p.joining = QChar::Joining_Transparent;
- }
- }
}
static void readDerivedAge()
@@ -2525,7 +2526,7 @@ static QByteArray createSpecialCaseMap()
out.chop(1);
out += "\n};\n\n";
- qDebug(" memory usage: %d bytes", specialCaseMap.size()*sizeof(unsigned short));
+ qDebug(" memory usage: %ld bytes", specialCaseMap.size()*sizeof(unsigned short));
return out;
}
@@ -3021,7 +3022,7 @@ int main(int, char **)
"****************************************************************************/\n\n";
QByteArray note =
- "/* This file is autogenerated from the Unicode "DATA_VERSION_S" database. Do not edit */\n\n";
+ "/* This file is autogenerated from the Unicode " DATA_VERSION_S " database. Do not edit */\n\n";
QByteArray warning =
"//\n"
@@ -3062,9 +3063,10 @@ int main(int, char **)
f.write(warning);
f.write("#ifndef QUNICODETABLES_P_H\n"
"#define QUNICODETABLES_P_H\n\n"
+ "#include <QtCore/private/qglobal_p.h>\n\n"
"#include <QtCore/qchar.h>\n\n"
"QT_BEGIN_NAMESPACE\n\n");
- f.write("#define UNICODE_DATA_VERSION "DATA_VERSION_STR"\n\n");
+ f.write("#define UNICODE_DATA_VERSION " DATA_VERSION_STR "\n\n");
f.write("namespace QUnicodeTables {\n\n");
f.write(property_string);
f.write(grapheme_break_class_string);