Merge remote-tracking branch 'origin/5.13' into dev
Conflicts: src/gui/util/qshaderformat.cpp src/gui/util/qshaderformat_p.h src/widgets/graphicsview/qgraphicsitem_p.h Change-Id: Idafd88eb9a0a15b4af29f6143d009c1ec8ceecca
This commit is contained in:
commit
dc37318684
@ -1111,7 +1111,7 @@ foreach my $lib (@modules_to_sync) {
|
||||
elsif (!$shadow) {
|
||||
$pri_install_pfiles.= "$pri_install_iheader ";;
|
||||
}
|
||||
$pri_injections .= fixPaths($iheader, $out_basedir)
|
||||
$pri_injections .= fixPaths($iheader, $build_basedir)
|
||||
.":".($no_stamp ? "^" : "").fixPaths($oheader, "$out_basedir/include/$lib")
|
||||
.$injection." " if ($shadow);
|
||||
}
|
||||
|
@ -139,8 +139,8 @@ Build options:
|
||||
-coverage {trace-pc-guard}
|
||||
Add code coverage instrumentation (Clang only)
|
||||
|
||||
-c++std <edition> .... Select C++ standard <edition> [c++1z/c++14/c++11]
|
||||
(Not supported with MSVC)
|
||||
-c++std <edition> .... Select C++ standard <edition> [c++2a/c++17/c++14/c++11]
|
||||
(Not supported with MSVC 2015)
|
||||
|
||||
-sse2 ................ Use SSE2 instructions [auto]
|
||||
-sse3/-ssse3/-sse4.1/-sse4.2/-avx/-avx2/-avx512
|
||||
|
@ -319,7 +319,7 @@
|
||||
}
|
||||
},
|
||||
"c++1z": {
|
||||
"label": "C++1z support",
|
||||
"label": "C++17 support",
|
||||
"type": "compile",
|
||||
"test": {
|
||||
"head": [
|
||||
@ -339,6 +339,20 @@
|
||||
"qmake": "CONFIG += c++11 c++14 c++1z"
|
||||
}
|
||||
},
|
||||
"c++2a": {
|
||||
"label": "C++2a support",
|
||||
"type": "compile",
|
||||
"test": {
|
||||
"head": [
|
||||
"#if __cplusplus > 201703L",
|
||||
"// Compiler claims to support experimental C++2a, trust it",
|
||||
"#else",
|
||||
"# error __cplusplus must be > 201703L (the value for C++17)",
|
||||
"#endif"
|
||||
],
|
||||
"qmake": "CONFIG += c++11 c++14 c++1z c++2a"
|
||||
}
|
||||
},
|
||||
"precompile_header": {
|
||||
"label": "precompiled header support",
|
||||
"type": "compile",
|
||||
@ -907,10 +921,16 @@
|
||||
"output": [ "publicFeature", "publicQtConfig" ]
|
||||
},
|
||||
"c++1z": {
|
||||
"label": "C++1z",
|
||||
"label": "C++17",
|
||||
"condition": "features.c++14 && tests.c++1z",
|
||||
"output": [ "publicFeature", "publicQtConfig" ]
|
||||
},
|
||||
"c++2a": {
|
||||
"label": "C++2a",
|
||||
"autoDetect": false,
|
||||
"condition": "features.c++1z && tests.c++2a",
|
||||
"output": [ "publicFeature", "publicQtConfig" ]
|
||||
},
|
||||
"c89": {
|
||||
"label": "C89"
|
||||
},
|
||||
@ -1413,7 +1433,7 @@ Configure with '-qreal float' to create a build that is binary-compatible with 5
|
||||
{
|
||||
"message": "Using C++ standard",
|
||||
"type": "firstAvailableFeature",
|
||||
"args": "c++1z c++14 c++11"
|
||||
"args": "c++2a c++1z c++14 c++11"
|
||||
},
|
||||
{
|
||||
"type": "feature",
|
||||
|
@ -14,21 +14,26 @@ defineTest(qtConfCommandline_qmakeArgs) {
|
||||
}
|
||||
|
||||
defineTest(qtConfCommandline_cxxstd) {
|
||||
msvc: \
|
||||
qtConfAddError("Command line option -c++std is not supported with MSVC compilers.")
|
||||
|
||||
arg = $${1}
|
||||
val = $${2}
|
||||
isEmpty(val): val = $$qtConfGetNextCommandlineArg()
|
||||
!contains(val, "^-.*"):!isEmpty(val) {
|
||||
contains(val, "(c\+\+)?11") {
|
||||
qtConfCommandlineSetInput("c++14", "no")
|
||||
qtConfCommandlineSetInput("c++1z", "no")
|
||||
qtConfCommandlineSetInput("c++2a", "no")
|
||||
} else: contains(val, "(c\+\+)?(14|1y)") {
|
||||
qtConfCommandlineSetInput("c++14", "yes")
|
||||
qtConfCommandlineSetInput("c++1z", "no")
|
||||
} else: contains(val, "(c\+\+)?(1z)") {
|
||||
qtConfCommandlineSetInput("c++2a", "no")
|
||||
} else: contains(val, "(c\+\+)?(17|1z)") {
|
||||
qtConfCommandlineSetInput("c++14", "yes")
|
||||
qtConfCommandlineSetInput("c++1z", "yes")
|
||||
qtConfCommandlineSetInput("c++2a", "no")
|
||||
} else: contains(val, "(c\+\+)?(2a)") {
|
||||
qtConfCommandlineSetInput("c++14", "yes")
|
||||
qtConfCommandlineSetInput("c++1z", "yes")
|
||||
qtConfCommandlineSetInput("c++2a", "yes")
|
||||
} else {
|
||||
qtConfAddError("Invalid argument $$val to command line parameter $$arg")
|
||||
}
|
||||
|
82
dist/changes-5.12.3
vendored
Normal file
82
dist/changes-5.12.3
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
Qt 5.12.3 is a bug-fix release. It maintains both forward and backward
|
||||
compatibility (source and binary) with Qt 5.12.0 through 5.12.2.
|
||||
|
||||
For more details, refer to the online documentation included in this
|
||||
distribution. The documentation is also available online:
|
||||
|
||||
https://doc.qt.io/qt-5/index.html
|
||||
|
||||
The Qt version 5.12 series is binary compatible with the 5.11.x series.
|
||||
Applications compiled for 5.11 will continue to run with 5.12.
|
||||
|
||||
Some of the changes listed in this file include issue tracking numbers
|
||||
corresponding to tasks in the Qt Bug Tracker:
|
||||
|
||||
https://bugreports.qt.io/
|
||||
|
||||
Each of these identifiers can be entered in the bug tracker to obtain more
|
||||
information about a particular change.
|
||||
|
||||
****************************************************************************
|
||||
* Third-Party Code *
|
||||
****************************************************************************
|
||||
|
||||
- Changed classification of the wintab license from Public Domain to
|
||||
Custom.
|
||||
|
||||
****************************************************************************
|
||||
* QtCore *
|
||||
****************************************************************************
|
||||
|
||||
- Event system:
|
||||
* [QTBUG-72438] Fixed a possible race condition on Windows that would
|
||||
cause an interrupted event loop to be stuck until more events were
|
||||
posted.
|
||||
|
||||
- Logging system:
|
||||
* [QTBUG-74359] Fixed the compilation of qCDebug("", ...) when debug
|
||||
output was disabled.
|
||||
|
||||
- QCollator:
|
||||
* [QTBUG-74209] Fixed a bug that caused QCompare to incorrect return a
|
||||
sorting order on Windows if the Win32 API failed.
|
||||
|
||||
- QDateTime / QTimeZone:
|
||||
* [QTBUG-74614] Fixed handling of timezones that contain no DST
|
||||
transitions.
|
||||
|
||||
- QProcess:
|
||||
* [QTBUG-73778] Fixed a crash when calling closeWriteChannel() on Windows.
|
||||
|
||||
****************************************************************************
|
||||
* QtSql *
|
||||
****************************************************************************
|
||||
|
||||
- When cross-compiling pg_config, mysql_config are not looked up in PATH
|
||||
anymore. Pass -psql_config path/to/pg_config or -mysql_config
|
||||
path/to/mysql_config to explicitly enable PSQL or MySQL in this setup.
|
||||
|
||||
****************************************************************************
|
||||
* Platform Specific Changes *
|
||||
****************************************************************************
|
||||
|
||||
- Android:
|
||||
* Text fields with ImhNoPredictiveText set are no longer working around
|
||||
keyboards that disregard this setting. To enforce the workaround, the
|
||||
environment variable
|
||||
QT_ANDROID_ENABLE_WORKAROUND_TO_DISABLE_PREDICTIVE_TEXT should be set.
|
||||
|
||||
* [QTBUG-74029] Added entries in the AndroidManifest.xml for specific
|
||||
portrait and landscape splash screens. If one is present for the current
|
||||
orientation, it will be preferred over the generic one.
|
||||
|
||||
- Linux:
|
||||
* [QTBUG-74526] Changed the way we use the statx() system call to use a
|
||||
fallback mechanism provided by the GNU C library. This should allow Qt
|
||||
applications that are compiled with glibc >= 2.28 to run even on kernels
|
||||
older than 4.11.
|
||||
|
||||
- Windows:
|
||||
* [QTBUG-74062] Fixed QToolTip pop-ups and QComboBox animation pop-ups
|
||||
being off by a few pixels on Windows 10.
|
||||
|
@ -35,9 +35,11 @@ QMAKE_CXXFLAGS_DISABLE_LTCG = $$QMAKE_CFLAGS_DISABLE_LTCG
|
||||
QMAKE_CXXFLAGS_CXX11 = -std=c++11
|
||||
QMAKE_CXXFLAGS_CXX14 = -std=c++1y
|
||||
QMAKE_CXXFLAGS_CXX1Z = -std=c++1z
|
||||
QMAKE_CXXFLAGS_CXX2A = -std=c++2a
|
||||
QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++11
|
||||
QMAKE_CXXFLAGS_GNUCXX14 = -std=gnu++1y
|
||||
QMAKE_CXXFLAGS_GNUCXX1Z = -std=gnu++1z
|
||||
QMAKE_CXXFLAGS_GNUCXX2A = -std=gnu++2a
|
||||
|
||||
QMAKE_LFLAGS_CXX11 =
|
||||
QMAKE_LFLAGS_CXX14 =
|
||||
|
@ -32,9 +32,11 @@ QMAKE_CFLAGS_GNUC11 = -std=gnu11
|
||||
QMAKE_CXXFLAGS_CXX11 = -std=c++11
|
||||
QMAKE_CXXFLAGS_CXX14 = -std=c++1y
|
||||
QMAKE_CXXFLAGS_CXX1Z = -std=c++1z
|
||||
QMAKE_CXXFLAGS_CXX2A = -std=c++2a
|
||||
QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++11
|
||||
QMAKE_CXXFLAGS_GNUCXX14 = -std=gnu++1y
|
||||
QMAKE_CXXFLAGS_GNUCXX1Z = -std=gnu++1z
|
||||
QMAKE_CXXFLAGS_GNUCXX2A = -std=gnu++2a
|
||||
QMAKE_LFLAGS_CXX11 =
|
||||
QMAKE_LFLAGS_CXX14 =
|
||||
QMAKE_LFLAGS_CXX1Z =
|
||||
|
@ -116,6 +116,8 @@ greaterThan(QMAKE_MSC_VER, 1910) {
|
||||
greaterThan(QMAKE_MSC_VER, 1919) {
|
||||
# Visual Studio 2019 (16.0) / Visual C++ 19.20 and up
|
||||
MSVC_VER = 16.0
|
||||
QMAKE_CXXFLAGS_CXX2A = -std:c++latest
|
||||
|
||||
}
|
||||
|
||||
!isEmpty(COMPAT_MKSPEC):!$$COMPAT_MKSPEC: CONFIG += $$COMPAT_MKSPEC
|
||||
|
@ -26,20 +26,29 @@ contains(CMAKE_INSTALL_LIBS_DIR, ^(/usr)?/lib(64)?.*): CMAKE_USR_MOVE_WORKAROUND
|
||||
|
||||
CMAKE_OUT_DIR = $$MODULE_BASE_OUTDIR/lib/cmake
|
||||
|
||||
# Core, Network, an external module named Foo
|
||||
CMAKE_MODULE_NAME = $$cmakeModuleName($${MODULE})
|
||||
|
||||
# QtCore, QtNetwork, still Foo
|
||||
CMAKE_INCLUDE_NAME = $$eval(QT.$${MODULE}.name)
|
||||
|
||||
# TARGET here is the one changed at the end of qt_module.prf,
|
||||
# which already contains the Qt5 prefix and QT_LIBINFIX suffix :
|
||||
# Qt5Core_suffix, Qt5Network_suffix, Foo_suffix
|
||||
# (or QtCore_suffix, Foo_suffix on macos with -framework)
|
||||
CMAKE_QT_STEM = $${TARGET}
|
||||
|
||||
!generated_privates {
|
||||
isEmpty(SYNCQT.INJECTED_PRIVATE_HEADER_FILES):isEmpty(SYNCQT.PRIVATE_HEADER_FILES): \
|
||||
CMAKE_NO_PRIVATE_INCLUDES = true
|
||||
}
|
||||
|
||||
split_incpath {
|
||||
CMAKE_ADD_SOURCE_INCLUDE_DIRS = true
|
||||
CMAKE_SOURCE_INCLUDES = \
|
||||
$$cmakeTargetPaths($$QT_MODULE_INCLUDE_BASE $$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME})
|
||||
$$cmakeTargetPaths($$QT_MODULE_INCLUDE_BASE $$QT_MODULE_INCLUDE_BASE/$${CMAKE_INCLUDE_NAME})
|
||||
CMAKE_SOURCE_PRIVATE_INCLUDES = \
|
||||
$$cmakeTargetPaths($$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}/$$eval(QT.$${MODULE}.VERSION) \
|
||||
$$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}/$$eval(QT.$${MODULE}.VERSION)/Qt$${CMAKE_MODULE_NAME})
|
||||
$$cmakeTargetPaths($$QT_MODULE_INCLUDE_BASE/$${CMAKE_INCLUDE_NAME}/$$eval(QT.$${MODULE}.VERSION) \
|
||||
$$QT_MODULE_INCLUDE_BASE/$${CMAKE_INCLUDE_NAME}/$$eval(QT.$${MODULE}.VERSION)/$${CMAKE_INCLUDE_NAME})
|
||||
|
||||
cmake_extra_source_includes.input = $$PWD/data/cmake/ExtraSourceIncludes.cmake.in
|
||||
cmake_extra_source_includes.output = $$CMAKE_OUT_DIR/Qt5$${CMAKE_MODULE_NAME}/ExtraSourceIncludes.cmake
|
||||
@ -200,10 +209,6 @@ CMAKE_QT5_MODULE_DEPS = $$join(lib_deps, ";")
|
||||
CMAKE_INTERFACE_MODULE_DEPS = $$join(aux_mod_deps, ";")
|
||||
CMAKE_INTERFACE_QT5_MODULE_DEPS = $$join(aux_lib_deps, ";")
|
||||
|
||||
# TARGET here is the one changed at the end of qt_module.prf,
|
||||
# which already contains the Qt5 prefix and QT_LIBINFIX suffix
|
||||
CMAKE_QT_STEM = $${TARGET}
|
||||
|
||||
mac {
|
||||
!isEmpty(CMAKE_STATIC_TYPE) {
|
||||
CMAKE_LIB_FILE_LOCATION_DEBUG = lib$${CMAKE_QT_STEM}_debug.a
|
||||
@ -213,8 +218,8 @@ mac {
|
||||
CMAKE_PRL_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.prl
|
||||
} else {
|
||||
qt_framework {
|
||||
CMAKE_LIB_FILE_LOCATION_DEBUG = Qt$${CMAKE_MODULE_NAME}$${QT_LIBINFIX}.framework/Qt$${CMAKE_MODULE_NAME}$${QT_LIBINFIX}
|
||||
CMAKE_LIB_FILE_LOCATION_RELEASE = Qt$${CMAKE_MODULE_NAME}$${QT_LIBINFIX}.framework/Qt$${CMAKE_MODULE_NAME}$${QT_LIBINFIX}
|
||||
CMAKE_LIB_FILE_LOCATION_DEBUG = $${CMAKE_QT_STEM}.framework/$${CMAKE_QT_STEM}
|
||||
CMAKE_LIB_FILE_LOCATION_RELEASE = $${CMAKE_QT_STEM}.framework/$${CMAKE_QT_STEM}
|
||||
CMAKE_BUILD_IS_FRAMEWORK = "true"
|
||||
} else {
|
||||
CMAKE_LIB_FILE_LOCATION_DEBUG = lib$${CMAKE_QT_STEM}_debug.$$eval(QT.$${MODULE}.VERSION).dylib
|
||||
|
@ -157,13 +157,13 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME})
|
||||
!!IF !no_module_headers
|
||||
!!IF !isEmpty(CMAKE_BUILD_IS_FRAMEWORK)
|
||||
set(_Qt5$${CMAKE_MODULE_NAME}_OWN_INCLUDE_DIRS
|
||||
\"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}Qt$${CMAKE_MODULE_NAME}.framework\"
|
||||
\"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}Qt$${CMAKE_MODULE_NAME}.framework/Headers\"
|
||||
\"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_QT_STEM}.framework\"
|
||||
\"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_QT_STEM}.framework/Headers\"
|
||||
)
|
||||
!!IF isEmpty(CMAKE_NO_PRIVATE_INCLUDES)
|
||||
set(Qt5$${CMAKE_MODULE_NAME}_PRIVATE_INCLUDE_DIRS
|
||||
\"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}Qt$${CMAKE_MODULE_NAME}.framework/Versions/$$section(VERSION, ., 0, 0)/Headers/$$VERSION/\"
|
||||
\"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}Qt$${CMAKE_MODULE_NAME}.framework/Versions/$$section(VERSION, ., 0, 0)/Headers/$$VERSION/$${MODULE_INCNAME}\"
|
||||
\"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_QT_STEM}.framework/Versions/$$section(VERSION, ., 0, 0)/Headers/$$VERSION/\"
|
||||
\"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_QT_STEM}.framework/Versions/$$section(VERSION, ., 0, 0)/Headers/$$VERSION/$${MODULE_INCNAME}\"
|
||||
)
|
||||
!!ELSE
|
||||
set(Qt5$${CMAKE_MODULE_NAME}_PRIVATE_INCLUDE_DIRS \"\")
|
||||
@ -180,7 +180,7 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME})
|
||||
set(Qt5$${CMAKE_MODULE_NAME}_PRIVATE_INCLUDE_DIRS \"\")
|
||||
!!ENDIF
|
||||
!!ELSE
|
||||
set(_Qt5$${CMAKE_MODULE_NAME}_OWN_INCLUDE_DIRS \"$$CMAKE_INCLUDE_DIR\" \"$${CMAKE_INCLUDE_DIR}Qt$${CMAKE_MODULE_NAME}\")
|
||||
set(_Qt5$${CMAKE_MODULE_NAME}_OWN_INCLUDE_DIRS \"$$CMAKE_INCLUDE_DIR\" \"$${CMAKE_INCLUDE_DIR}$${CMAKE_INCLUDE_NAME}\")
|
||||
!!IF isEmpty(CMAKE_NO_PRIVATE_INCLUDES)
|
||||
set(Qt5$${CMAKE_MODULE_NAME}_PRIVATE_INCLUDE_DIRS
|
||||
\"$${CMAKE_INCLUDE_DIR}$${MODULE_INCNAME}/$$VERSION\"
|
||||
|
@ -121,15 +121,16 @@ breakpad {
|
||||
|
||||
c++17: CONFIG += c++1z
|
||||
|
||||
!c++11:!c++14:!c++1z {
|
||||
!c++11:!c++14:!c++1z:!c++2a {
|
||||
# Qt requires C++11 since 5.7, check if we need to force a compiler option
|
||||
QT_COMPILER_STDCXX_no_L = $$replace(QT_COMPILER_STDCXX, "L$", "")
|
||||
!greaterThan(QT_COMPILER_STDCXX_no_L, 199711): CONFIG += c++11
|
||||
}
|
||||
c++11|c++14|c++1z {
|
||||
c++11|c++14|c++1z|c++2a {
|
||||
# Disable special compiler flags for host builds
|
||||
!host_build|!cross_compile {
|
||||
c++1z: cxxstd = CXX1Z
|
||||
c++2a: cxxstd = CXX2A
|
||||
else: c++1z: cxxstd = CXX1Z
|
||||
else: c++14: cxxstd = CXX14
|
||||
else: cxxstd = CXX11
|
||||
} else {
|
||||
|
@ -145,12 +145,14 @@ import_plugins:qtConfig(static) {
|
||||
# the plugin path. Unknown plugins must rely on the default link path.
|
||||
plug_type = $$eval(QT_PLUGIN.$${plug}.TYPE)
|
||||
!isEmpty(plug_type) {
|
||||
plug_name = $$QMAKE_PREFIX_STATICLIB$${plug}$$qtPlatformTargetSuffix().$$QMAKE_EXTENSION_STATICLIB
|
||||
plug_path = $$eval(QT_PLUGIN.$${plug}.PATH)
|
||||
isEmpty(plug_path): \
|
||||
plug_path = $$[QT_INSTALL_PLUGINS/get]
|
||||
LIBS += -L$$plug_path/$$plug_type
|
||||
LIBS += $$plug_path/$$plug_type/$$plug_name
|
||||
} else {
|
||||
LIBS += -l$${plug}$$qtPlatformTargetSuffix()
|
||||
}
|
||||
LIBS += -l$${plug}$$qtPlatformTargetSuffix()
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,8 +197,6 @@ for(ever) {
|
||||
qtProcessModuleFlags(DEFINES, QT.$${QTLIB}.DEFINES)
|
||||
|
||||
MODULE_INCLUDES -= $$QMAKE_DEFAULT_INCDIRS
|
||||
MODULE_LIBS_ADD = $$MODULE_LIBS
|
||||
MODULE_LIBS_ADD -= $$QMAKE_DEFAULT_LIBDIRS
|
||||
|
||||
# Frameworks shouldn't need include paths, but much code does not use
|
||||
# module-qualified #includes, so by default we add paths which point
|
||||
@ -209,23 +209,17 @@ for(ever) {
|
||||
!isEmpty(MODULE_MODULE) {
|
||||
contains(MODULE_CONFIG, lib_bundle) {
|
||||
framework = $$MODULE_MODULE
|
||||
# Linking frameworks by absolute path does not work.
|
||||
LIBS$$var_sfx += -framework $$framework
|
||||
} else {
|
||||
!isEmpty(MODULE_LIBS_ADD): \
|
||||
LIBS$$var_sfx += -L$$MODULE_LIBS_ADD
|
||||
|
||||
lib = $$MODULE_MODULE$$qtPlatformTargetSuffix()
|
||||
LIBS$$var_sfx += -l$$lib
|
||||
|
||||
contains(MODULE_CONFIG, staticlib): \
|
||||
PRE_TARGETDEPS *= $$MODULE_LIBS/$${QMAKE_PREFIX_STATICLIB}$${lib}.$${QMAKE_EXTENSION_STATICLIB}
|
||||
|
||||
!isEmpty(QMAKE_LSB) {
|
||||
!isEmpty(MODULE_LIBS_ADD): \
|
||||
QMAKE_LFLAGS *= --lsb-libpath=$$MODULE_LIBS_ADD
|
||||
QMAKE_LFLAGS *= --lsb-shared-libs=$$lib
|
||||
QMAKE_LIBDIR *= /opt/lsb/lib
|
||||
win32|contains(MODULE_CONFIG, staticlib) {
|
||||
lib = $$MODULE_LIBS/$$QMAKE_PREFIX_STATICLIB$${lib}.$$QMAKE_EXTENSION_STATICLIB
|
||||
PRE_TARGETDEPS += $$lib
|
||||
} else {
|
||||
lib = $$MODULE_LIBS/$$QMAKE_PREFIX_SHLIB$${lib}.$$QMAKE_EXTENSION_SHLIB
|
||||
}
|
||||
LIBS$$var_sfx += $$lib
|
||||
}
|
||||
}
|
||||
QMAKE_USE$$var_sfx += $$MODULE_USES
|
||||
@ -295,7 +289,8 @@ contains(all_qt_module_deps, qml): \
|
||||
for (key, IMPORTS._KEYS_) {
|
||||
PATH = $$eval(IMPORTS.$${key}.path)
|
||||
PLUGIN = $$eval(IMPORTS.$${key}.plugin)
|
||||
!isEmpty(PATH):!isEmpty(PLUGIN): LIBS *= -L$$PATH -l$${PLUGIN}$$qtPlatformTargetSuffix()
|
||||
!isEmpty(PATH):!isEmpty(PLUGIN): \
|
||||
LIBS += $$PATH/$$QMAKE_PREFIX_STATICLIB$${PLUGIN}$$qtPlatformTargetSuffix().$$QMAKE_EXTENSION_STATICLIB
|
||||
}
|
||||
|
||||
# create qml_plugin_import.cpp
|
||||
|
@ -17,6 +17,7 @@ DEFINES *= QT_NO_NARROWING_CONVERSIONS_IN_CONNECT
|
||||
qtConfig(c++11): CONFIG += c++11 strict_c++
|
||||
qtConfig(c++14): CONFIG += c++14
|
||||
qtConfig(c++1z): CONFIG += c++1z
|
||||
qtConfig(c++2a): CONFIG += c++2a
|
||||
qtConfig(c99): CONFIG += c99
|
||||
qtConfig(c11): CONFIG += c11
|
||||
qtConfig(stack-protector-strong): CONFIG += stack_protector_strong
|
||||
|
@ -526,6 +526,17 @@ defineTest(qtConfSetupLibraries) {
|
||||
}
|
||||
}
|
||||
|
||||
defineReplace(qtGccSysrootifiedPath) {
|
||||
return($$replace(1, ^=, $$[QT_SYSROOT]))
|
||||
}
|
||||
|
||||
defineReplace(qtGccSysrootifiedPaths) {
|
||||
sysrootified =
|
||||
for (path, 1): \
|
||||
sysrootified += $$qtGccSysrootifiedPath($$path)
|
||||
return($$sysrootified)
|
||||
}
|
||||
|
||||
# libs-var, libs, in-paths, out-paths-var
|
||||
defineTest(qtConfResolveLibs) {
|
||||
ret = true
|
||||
@ -542,6 +553,7 @@ defineTest(qtConfResolveLibs) {
|
||||
out += $$l
|
||||
} else: contains(l, "^-L.*") {
|
||||
lp = $$replace(l, "^-L", )
|
||||
gcc: lp = $$qtGccSysrootifiedPath($$lp)
|
||||
!exists($$lp/.) {
|
||||
qtLog("Library path $$val_escape(lp) is invalid.")
|
||||
ret = false
|
||||
@ -615,6 +627,7 @@ defineTest(qtConfResolveAllLibs) {
|
||||
# libs-var, in-paths, libs
|
||||
defineTest(qtConfResolvePathLibs) {
|
||||
ret = true
|
||||
gcc: 2 = $$qtGccSysrootifiedPaths($$2)
|
||||
for (libdir, 2) {
|
||||
!exists($$libdir/.) {
|
||||
qtLog("Library path $$val_escape(libdir) is invalid.")
|
||||
@ -665,6 +678,7 @@ defineReplace(qtConfGetTestIncludes) {
|
||||
# includes-var, in-paths, test-object-var
|
||||
defineTest(qtConfResolvePathIncs) {
|
||||
ret = true
|
||||
gcc: 2 = $$qtGccSysrootifiedPaths($$2)
|
||||
for (incdir, 2) {
|
||||
!exists($$incdir/.) {
|
||||
qtLog("Include path $$val_escape(incdir) is invalid.")
|
||||
|
@ -23,7 +23,7 @@ load(qt_build_paths)
|
||||
QMAKE_SYNCQT += -module $$mod
|
||||
QMAKE_SYNCQT += \
|
||||
-version $$VERSION -outdir $$system_quote($$MODULE_BASE_OUTDIR) \
|
||||
-builddir $$system_quote($$shadowed($$MODULE_BASE_INDIR)) $$MODULE_SYNCQT_DIR
|
||||
-builddir $$system_quote($$REAL_MODULE_BASE_OUTDIR) $$MODULE_SYNCQT_DIR
|
||||
!silent: message($$QMAKE_SYNCQT)
|
||||
system($$QMAKE_SYNCQT)|error("Failed to run: $$QMAKE_SYNCQT")
|
||||
|
||||
|
@ -1,13 +1,21 @@
|
||||
QT_FOR_CONFIG += gui
|
||||
|
||||
defineTest(prependOpenGlLib) {
|
||||
path = $$QT.core.libs/$$QMAKE_PREFIX_STATICLIB$$1
|
||||
ext = .$$QMAKE_EXTENSION_STATICLIB
|
||||
QMAKE_LIBS_OPENGL_ES2 = $${path}$${ext} $$QMAKE_LIBS_OPENGL_ES2
|
||||
QMAKE_LIBS_OPENGL_ES2_DEBUG = $${path}d$${ext} $$QMAKE_LIBS_OPENGL_ES2_DEBUG
|
||||
export(QMAKE_LIBS_OPENGL_ES2)
|
||||
export(QMAKE_LIBS_OPENGL_ES2_DEBUG)
|
||||
}
|
||||
|
||||
qtConfig(opengles2) {
|
||||
# Depending on the configuration we use libQtANGLE or libEGL and libGLESv2
|
||||
qtConfig(combined-angle-lib) {
|
||||
QMAKE_LIBS_OPENGL_ES2 = -l$${LIBQTANGLE_NAME} $$QMAKE_LIBS_OPENGL_ES2
|
||||
QMAKE_LIBS_OPENGL_ES2_DEBUG = -l$${LIBQTANGLE_NAME}d $$QMAKE_LIBS_OPENGL_ES2_DEBUG
|
||||
prependOpenGlLib($$LIBQTANGLE_NAME)
|
||||
} else {
|
||||
QMAKE_LIBS_OPENGL_ES2 = -l$${LIBEGL_NAME} -l$${LIBGLESV2_NAME} $$QMAKE_LIBS_OPENGL_ES2
|
||||
QMAKE_LIBS_OPENGL_ES2_DEBUG = -l$${LIBEGL_NAME}d -l$${LIBGLESV2_NAME}d $$QMAKE_LIBS_OPENGL_ES2_DEBUG
|
||||
prependOpenGlLib($$LIBGLESV2_NAME)
|
||||
prependOpenGlLib($$LIBEGL_NAME)
|
||||
}
|
||||
# For Desktop, use the ANGLE library location passed on from configure.
|
||||
INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES2
|
||||
|
@ -6,10 +6,9 @@ contains(TEMPLATE, ".*app") {
|
||||
|
||||
qt:for(entryLib, $$list($$unique(QMAKE_LIBS_QT_ENTRY))) {
|
||||
isEqual(entryLib, -lqtmain) {
|
||||
!contains(QMAKE_DEFAULT_LIBDIRS, $$QT.core.libs): \
|
||||
QMAKE_LIBS += -L$$QT.core.libs
|
||||
CONFIG(debug, debug|release): QMAKE_LIBS += $${entryLib}$${QT_LIBINFIX}d
|
||||
else: QMAKE_LIBS += $${entryLib}$${QT_LIBINFIX}
|
||||
lib = $$QT.core.libs/$${QMAKE_PREFIX_STATICLIB}qtmain$$QT_LIBINFIX$$qtPlatformTargetSuffix().$$QMAKE_EXTENSION_STATICLIB
|
||||
PRE_TARGETDEPS += $$lib
|
||||
QMAKE_LIBS += $$lib
|
||||
} else {
|
||||
QMAKE_LIBS += $${entryLib}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ load(qt_config)
|
||||
|
||||
QMAKE_LIBS_THREAD += -lrt
|
||||
|
||||
QMAKE_LSB = 1
|
||||
QMAKE_CC = lsbcc
|
||||
QMAKE_CXX = lsbc++
|
||||
|
||||
|
@ -1271,6 +1271,41 @@
|
||||
|
||||
\snippet code/doc_src_qmake-manual.pro 36
|
||||
|
||||
\c INSTALLS has a \c{.CONFIG} member that can take several values:
|
||||
|
||||
\table
|
||||
\header
|
||||
\li Value
|
||||
\li Description
|
||||
\row
|
||||
\li no_check_exists
|
||||
\li If not set, qmake looks to see if the files to install actually
|
||||
exist. If these files don't exist, qmake doesn’t create the
|
||||
install rule. Use this config value if you need to install
|
||||
files that are generated as part of your build process, like
|
||||
HTML files created by qdoc.
|
||||
\row
|
||||
\li nostrip
|
||||
\li If set, the typical Unix strip functionality is turned off and
|
||||
the debug information will remain in the binary.
|
||||
\row
|
||||
\li executable
|
||||
\li On Unix, this sets the executable flag.
|
||||
\row
|
||||
\li no_build
|
||||
\li When you do a \c{make install}, and you don't have a build of
|
||||
the project yet, the project is first built, and then installed.
|
||||
If you don't want this behavior, set this config value to ensure
|
||||
that the build target is not added as a dependency to the install
|
||||
target.
|
||||
\row
|
||||
\li no_default_install
|
||||
\li A project has a top-level project target where, when you do a
|
||||
\c{make install}, everything is installed. But, if you have an
|
||||
install target with this config value set, it's not installed by
|
||||
default. You then have to explicitly say \c{make install_<file>}.
|
||||
\endtable
|
||||
|
||||
For more information, see \l{Installing Files}.
|
||||
|
||||
This variable is also used to specify which additional files will be
|
||||
@ -1580,6 +1615,14 @@
|
||||
The value of this variable is typically handled by qmake or \l{#QMAKESPEC}{qmake.conf}
|
||||
and rarely needs to be modified.
|
||||
|
||||
\target QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
|
||||
\section1 QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
|
||||
|
||||
Specifies the C compiler flags for release builds where
|
||||
\c{force_debug_info} is set in \c{CONFIG}.
|
||||
The value of this variable is typically handled by
|
||||
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
|
||||
|
||||
\target QMAKE_CFLAGS_SHLIB
|
||||
\section1 QMAKE_CFLAGS_SHLIB
|
||||
|
||||
@ -1648,6 +1691,14 @@
|
||||
The value of this variable is typically handled by
|
||||
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
|
||||
|
||||
\target QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO
|
||||
\section1 QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO
|
||||
|
||||
Specifies the C++ compiler flags for release builds where
|
||||
\c{force_debug_info} is set in \c{CONFIG}.
|
||||
The value of this variable is typically handled by
|
||||
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
|
||||
|
||||
\target QMAKE_CXXFLAGS_SHLIB
|
||||
\section1 QMAKE_CXXFLAGS_SHLIB
|
||||
|
||||
@ -2028,6 +2079,12 @@
|
||||
The value of this variable is typically handled by
|
||||
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
|
||||
|
||||
\section1 QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO
|
||||
|
||||
Specifies the linker flags for release builds where \c{force_debug_info} is
|
||||
set in \c{CONFIG}. The value of this variable is typically handled by
|
||||
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
|
||||
|
||||
\section1 QMAKE_LFLAGS_APP
|
||||
|
||||
Specifies the linker flags for building applications.
|
||||
@ -4813,6 +4870,7 @@
|
||||
\li Unix
|
||||
\list
|
||||
\li GCC 3.4 and above
|
||||
\li clang
|
||||
\endlist
|
||||
\endlist
|
||||
|
||||
|
@ -143,6 +143,7 @@ const char _InterfaceIdentifierFileName[] = "InterfaceIdentifierFileName";
|
||||
const char _IntermediateDirectory[] = "IntermediateDirectory";
|
||||
const char _KeyContainer[] = "KeyContainer";
|
||||
const char _KeyFile[] = "KeyFile";
|
||||
const char _LanguageStandard[] = "LanguageStandard";
|
||||
const char _LargeAddressAware[] = "LargeAddressAware";
|
||||
const char _LinkDLL[] = "LinkDLL";
|
||||
const char _LinkErrorReporting[] = "LinkErrorReporting";
|
||||
@ -1478,6 +1479,7 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCCLCompilerTool &tool)
|
||||
<< attrTagT(_IntrinsicFunctions, tool.EnableIntrinsicFunctions)
|
||||
<< attrTagT(_MinimalRebuild, tool.MinimalRebuild)
|
||||
<< attrTagT(_MultiProcessorCompilation, tool.MultiProcessorCompilation)
|
||||
<< attrTagS(_LanguageStandard, tool.LanguageStandard)
|
||||
<< attrTagS(_ObjectFileName, tool.ObjectFile)
|
||||
<< attrTagT(_OmitDefaultLibName, tool.OmitDefaultLibName)
|
||||
<< attrTagT(_OmitFramePointers, tool.OmitFramePointers)
|
||||
|
@ -1147,6 +1147,14 @@ bool VCCLCompilerTool::parseOption(const char* option)
|
||||
ShowIncludes = _True;
|
||||
break;
|
||||
}
|
||||
if (strlen(option) > 8 && second == 't' && third == 'd') {
|
||||
const QString version = option + 8;
|
||||
static const QStringList knownVersions = { "14", "17", "latest" };
|
||||
if (knownVersions.contains(version)) {
|
||||
LanguageStandard = "stdcpp" + version;
|
||||
break;
|
||||
}
|
||||
}
|
||||
found = false; break;
|
||||
case 'u':
|
||||
if (!second)
|
||||
|
@ -526,6 +526,7 @@ public:
|
||||
triState ImproveFloatingPointConsistency;
|
||||
inlineExpansionOption InlineFunctionExpansion;
|
||||
triState KeepComments;
|
||||
QString LanguageStandard;
|
||||
triState MinimalRebuild;
|
||||
QString ObjectFile;
|
||||
triState OmitDefaultLibName;
|
||||
|
17
src/3rdparty/angle/src/libANGLE/Display.cpp
vendored
17
src/3rdparty/angle/src/libANGLE/Display.cpp
vendored
@ -364,6 +364,23 @@ Display *Display::GetDisplayFromDevice(Device *device, const AttributeMap &attri
|
||||
return display;
|
||||
}
|
||||
|
||||
//static
|
||||
void Display::CleanupDisplays()
|
||||
{
|
||||
// ~Display takes care of removing the entry from the according map
|
||||
{
|
||||
ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
|
||||
while (!displays->empty())
|
||||
delete displays->begin()->second;
|
||||
}
|
||||
|
||||
{
|
||||
DevicePlatformDisplayMap *displays = GetDevicePlatformDisplayMap();
|
||||
while (!displays->empty())
|
||||
delete displays->begin()->second;
|
||||
}
|
||||
}
|
||||
|
||||
Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice)
|
||||
: mImplementation(nullptr),
|
||||
mDisplayId(displayId),
|
||||
|
1
src/3rdparty/angle/src/libANGLE/Display.h
vendored
1
src/3rdparty/angle/src/libANGLE/Display.h
vendored
@ -65,6 +65,7 @@ class Display final : angle::NonCopyable
|
||||
static Display *GetDisplayFromDevice(Device *device, const AttributeMap &attribMap);
|
||||
static Display *GetDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay,
|
||||
const AttributeMap &attribMap);
|
||||
static void CleanupDisplays();
|
||||
|
||||
static const ClientExtensions &GetClientExtensions();
|
||||
static const std::string &GetClientExtensionString();
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "common/tls.h"
|
||||
|
||||
#include "libANGLE/Thread.h"
|
||||
#include "libANGLE/Display.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
@ -140,6 +141,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID)
|
||||
return static_cast<BOOL>(egl::DeallocateCurrentThread());
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
egl::Display::CleanupDisplays();
|
||||
return static_cast<BOOL>(egl::TerminateProcess());
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,78 @@
|
||||
From d8ca4f6d0d8fffd8319f340685e03751049678ae Mon Sep 17 00:00:00 2001
|
||||
From: Oliver Wolff <oliver.wolff@qt.io>
|
||||
Date: Tue, 16 Apr 2019 10:19:27 +0200
|
||||
Subject: [PATCH] ANGLE: clean up displays on dll unload
|
||||
|
||||
If the displays are not cleaned up on dll unloading, profilers might
|
||||
report memory leaks.
|
||||
|
||||
Change-Id: I04cbc3c2448bfb450f7d840e216827f86856e963
|
||||
---
|
||||
src/3rdparty/angle/src/libANGLE/Display.cpp | 17 +++++++++++++++++
|
||||
src/3rdparty/angle/src/libANGLE/Display.h | 1 +
|
||||
.../angle/src/libGLESv2/global_state.cpp | 2 ++
|
||||
3 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/src/3rdparty/angle/src/libANGLE/Display.cpp b/src/3rdparty/angle/src/libANGLE/Display.cpp
|
||||
index 735b472787..0bb0bb05b1 100644
|
||||
--- a/src/3rdparty/angle/src/libANGLE/Display.cpp
|
||||
+++ b/src/3rdparty/angle/src/libANGLE/Display.cpp
|
||||
@@ -364,6 +364,23 @@ Display *Display::GetDisplayFromDevice(Device *device, const AttributeMap &attri
|
||||
return display;
|
||||
}
|
||||
|
||||
+//static
|
||||
+void Display::CleanupDisplays()
|
||||
+{
|
||||
+ // ~Display takes care of removing the entry from the according map
|
||||
+ {
|
||||
+ ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
|
||||
+ while (!displays->empty())
|
||||
+ delete displays->begin()->second;
|
||||
+ }
|
||||
+
|
||||
+ {
|
||||
+ DevicePlatformDisplayMap *displays = GetDevicePlatformDisplayMap();
|
||||
+ while (!displays->empty())
|
||||
+ delete displays->begin()->second;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice)
|
||||
: mImplementation(nullptr),
|
||||
mDisplayId(displayId),
|
||||
diff --git a/src/3rdparty/angle/src/libANGLE/Display.h b/src/3rdparty/angle/src/libANGLE/Display.h
|
||||
index aa1d1c3b37..2a1c386d75 100644
|
||||
--- a/src/3rdparty/angle/src/libANGLE/Display.h
|
||||
+++ b/src/3rdparty/angle/src/libANGLE/Display.h
|
||||
@@ -65,6 +65,7 @@ class Display final : angle::NonCopyable
|
||||
static Display *GetDisplayFromDevice(Device *device, const AttributeMap &attribMap);
|
||||
static Display *GetDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay,
|
||||
const AttributeMap &attribMap);
|
||||
+ static void CleanupDisplays();
|
||||
|
||||
static const ClientExtensions &GetClientExtensions();
|
||||
static const std::string &GetClientExtensionString();
|
||||
diff --git a/src/3rdparty/angle/src/libGLESv2/global_state.cpp b/src/3rdparty/angle/src/libGLESv2/global_state.cpp
|
||||
index c5f3dfe4e1..26045bf5b2 100644
|
||||
--- a/src/3rdparty/angle/src/libGLESv2/global_state.cpp
|
||||
+++ b/src/3rdparty/angle/src/libGLESv2/global_state.cpp
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "common/tls.h"
|
||||
|
||||
#include "libANGLE/Thread.h"
|
||||
+#include "libANGLE/Display.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
@@ -140,6 +141,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID)
|
||||
return static_cast<BOOL>(egl::DeallocateCurrentThread());
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
+ egl::Display::CleanupDisplays();
|
||||
return static_cast<BOOL>(egl::TerminateProcess());
|
||||
}
|
||||
|
||||
--
|
||||
2.20.1.windows.1
|
||||
|
@ -61,6 +61,9 @@
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#ifdef Q_CC_MINGW
|
||||
# include <unistd.h> // Define _POSIX_THREAD_SAFE_FUNCTIONS to obtain localtime_r()
|
||||
#endif
|
||||
#include <time.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
@ -310,9 +310,18 @@ static QString readSymLink(const QFileSystemEntry &link)
|
||||
const wchar_t* PathBuffer = &rdb->SymbolicLinkReparseBuffer.PathBuffer[offset];
|
||||
result = QString::fromWCharArray(PathBuffer, length);
|
||||
}
|
||||
// cut-off "//?/" and "/??/"
|
||||
if (result.size() > 4 && result.at(0) == QLatin1Char('\\') && result.at(2) == QLatin1Char('?') && result.at(3) == QLatin1Char('\\'))
|
||||
// cut-off "\\?\" and "\??\"
|
||||
if (result.size() > 4
|
||||
&& result.at(0) == QLatin1Char('\\')
|
||||
&& result.at(2) == QLatin1Char('?')
|
||||
&& result.at(3) == QLatin1Char('\\')) {
|
||||
result = result.mid(4);
|
||||
// cut off UNC in addition when the link points at a UNC share
|
||||
// in which case we need to prepend another backslash to get \\server\share
|
||||
if (result.leftRef(3) == QLatin1String("UNC")) {
|
||||
result.replace(0, 3, QLatin1Char('\\'));
|
||||
}
|
||||
}
|
||||
}
|
||||
free(rdb);
|
||||
CloseHandle(handle);
|
||||
|
@ -3619,7 +3619,7 @@ QModelIndex QAbstractTableModel::sibling(int row, int column, const QModelIndex
|
||||
|
||||
bool QAbstractTableModel::hasChildren(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.model() == this || !parent.isValid())
|
||||
if (!parent.isValid())
|
||||
return rowCount(parent) > 0 && columnCount(parent) > 0;
|
||||
return false;
|
||||
}
|
||||
|
@ -515,7 +515,7 @@ struct Q_CORE_EXPORT QMetaObject
|
||||
Qt::ConnectionType type = Qt::AutoConnection, decltype(function()) *ret = nullptr)
|
||||
{
|
||||
return invokeMethodImpl(context,
|
||||
new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(function),
|
||||
new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)),
|
||||
type,
|
||||
ret);
|
||||
}
|
||||
@ -527,7 +527,7 @@ struct Q_CORE_EXPORT QMetaObject
|
||||
invokeMethod(QObject *context, Func function, typename std::result_of<Func()>::type *ret)
|
||||
{
|
||||
return invokeMethodImpl(context,
|
||||
new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(function),
|
||||
new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)),
|
||||
Qt::AutoConnection,
|
||||
ret);
|
||||
}
|
||||
|
@ -58,6 +58,9 @@
|
||||
#endif
|
||||
|
||||
#include <cmath>
|
||||
#ifdef Q_CC_MINGW
|
||||
# include <unistd.h> // Define _POSIX_THREAD_SAFE_FUNCTIONS to obtain localtime_r()
|
||||
#endif
|
||||
#include <time.h>
|
||||
#ifdef Q_OS_WIN
|
||||
# include <qt_windows.h>
|
||||
|
@ -335,7 +335,7 @@ public:
|
||||
inline bool operator>(const QDateTime &other) const { return other < *this; }
|
||||
inline bool operator>=(const QDateTime &other) const { return !(*this < other); }
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 2)
|
||||
#if QT_DEPRECATED_SINCE(5, 2) // ### Qt 6: remove
|
||||
QT_DEPRECATED void setUtcOffset(int seconds);
|
||||
QT_DEPRECATED int utcOffset() const;
|
||||
#endif // QT_DEPRECATED_SINCE
|
||||
|
@ -2482,6 +2482,17 @@ QString QLocale::toString(double i, char f, int prec) const
|
||||
|
||||
Returns a QLocale object initialized to the "C" locale.
|
||||
|
||||
This locale is based on en_US but with various quirks of its own, such as
|
||||
simplified number formatting and its own date formatting. It implements the
|
||||
POSIX standards that describe the behavior of standard library functions of
|
||||
the "C" programming language.
|
||||
|
||||
Among other things, this means its collation order is based on the ASCII
|
||||
values of letters, so that (for case-sensitive sorting) all upper-case
|
||||
letters sort before any lower-case one (rather than each letter's upper- and
|
||||
lower-case forms sorting adjacent to one another, before the next letter's
|
||||
two forms).
|
||||
|
||||
\sa system()
|
||||
*/
|
||||
|
||||
|
@ -104,7 +104,7 @@
|
||||
This enumerated type is used to specify a language.
|
||||
|
||||
\value AnyLanguage
|
||||
\value C The "C" locale is identical in behavior to English/UnitedStates.
|
||||
\value C A simplified English locale; see QLocale::c()
|
||||
|
||||
\value Abkhazian
|
||||
\value Afan Obsolete, please use Oromo
|
||||
|
@ -46,6 +46,8 @@
|
||||
#include "qwindow.h"
|
||||
#include "qplatformwindow.h"
|
||||
|
||||
#include <private/qwindow_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*!
|
||||
@ -199,12 +201,18 @@ void QOffscreenSurface::create()
|
||||
if (QThread::currentThread() != qGuiApp->thread())
|
||||
qWarning("Attempting to create QWindow-based QOffscreenSurface outside the gui thread. Expect failures.");
|
||||
d->offscreenWindow = new QWindow(d->screen);
|
||||
// Make the window frameless to prevent Windows from enlarging it, should it
|
||||
// violate the minimum title bar width on the platform.
|
||||
d->offscreenWindow->setFlags(d->offscreenWindow->flags()
|
||||
| Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
|
||||
d->offscreenWindow->setObjectName(QLatin1String("QOffscreenSurface"));
|
||||
// Remove this window from the global list since we do not want it to be destroyed when closing the app.
|
||||
// The QOffscreenSurface has to be usable even after exiting the event loop.
|
||||
QGuiApplicationPrivate::window_list.removeOne(d->offscreenWindow);
|
||||
d->offscreenWindow->setSurfaceType(QWindow::OpenGLSurface);
|
||||
d->offscreenWindow->setFormat(d->requestedFormat);
|
||||
// Prevent QPlatformWindow::initialGeometry() and platforms from setting a default geometry.
|
||||
qt_window_private(d->offscreenWindow)->setAutomaticPositionAndResizeEnabled(false);
|
||||
d->offscreenWindow->setGeometry(0, 0, d->size.width(), d->size.height());
|
||||
d->offscreenWindow->create();
|
||||
}
|
||||
|
@ -366,40 +366,35 @@ void qt_mac_scale_region(QRegion *region, qreal scaleFactor)
|
||||
|
||||
// ---------------------- QMacCGContext ----------------------
|
||||
|
||||
QMacCGContext::QMacCGContext(QPaintDevice *paintDevice) : context(0)
|
||||
QMacCGContext::QMacCGContext(QPaintDevice *paintDevice)
|
||||
{
|
||||
// In Qt 5, QWidget and QPixmap (and QImage) paint devices are all QImages under the hood.
|
||||
QImage *image = 0;
|
||||
if (paintDevice->devType() == QInternal::Image) {
|
||||
image = static_cast<QImage *>(paintDevice);
|
||||
} else if (paintDevice->devType() == QInternal::Pixmap) {
|
||||
|
||||
const QPixmap *pm = static_cast<const QPixmap*>(paintDevice);
|
||||
QPlatformPixmap *data = const_cast<QPixmap *>(pm)->data_ptr().data();
|
||||
if (data && data->classId() == QPlatformPixmap::RasterClass) {
|
||||
image = data->buffer();
|
||||
} else {
|
||||
qDebug("QMacCGContext: Unsupported pixmap class");
|
||||
}
|
||||
} else if (paintDevice->devType() == QInternal::Widget) {
|
||||
// TODO test: image = static_cast<QImage *>(static_cast<const QWidget *>(paintDevice)->backingStore()->paintDevice());
|
||||
qDebug("QMacCGContext: not implemented: Widget class");
|
||||
}
|
||||
|
||||
if (!image)
|
||||
return; // Context type not supported.
|
||||
|
||||
QCFType<CGColorSpaceRef> colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
|
||||
context = CGBitmapContextCreate(image->bits(), image->width(), image->height(), 8,
|
||||
image->bytesPerLine(), colorSpace, qt_mac_bitmapInfoForImage(*image));
|
||||
|
||||
CGContextTranslateCTM(context, 0, image->height());
|
||||
const qreal devicePixelRatio = paintDevice->devicePixelRatioF();
|
||||
CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
|
||||
CGContextScaleCTM(context, 1, -1);
|
||||
initialize(paintDevice);
|
||||
}
|
||||
|
||||
QMacCGContext::QMacCGContext(QPainter *painter) : context(0)
|
||||
void QMacCGContext::initialize(QPaintDevice *paintDevice)
|
||||
{
|
||||
// Find the underlying QImage of the paint device
|
||||
switch (int deviceType = paintDevice->devType()) {
|
||||
case QInternal::Pixmap: {
|
||||
auto *platformPixmap = static_cast<QPixmap*>(paintDevice)->handle();
|
||||
if (platformPixmap && platformPixmap->classId() == QPlatformPixmap::RasterClass)
|
||||
initialize(platformPixmap->buffer());
|
||||
else
|
||||
qWarning() << "QMacCGContext: Unsupported pixmap class" << platformPixmap->classId();
|
||||
break;
|
||||
}
|
||||
case QInternal::Image:
|
||||
initialize(static_cast<const QImage *>(paintDevice));
|
||||
break;
|
||||
case QInternal::Widget:
|
||||
qWarning() << "QMacCGContext: not implemented: Widget class";
|
||||
break;
|
||||
default:
|
||||
qWarning() << "QMacCGContext:: Unsupported paint device type" << deviceType;
|
||||
}
|
||||
}
|
||||
|
||||
QMacCGContext::QMacCGContext(QPainter *painter)
|
||||
{
|
||||
QPaintEngine *paintEngine = painter->paintEngine();
|
||||
|
||||
@ -414,51 +409,68 @@ QMacCGContext::QMacCGContext(QPainter *painter) : context(0)
|
||||
return;
|
||||
}
|
||||
|
||||
int devType = painter->device()->devType();
|
||||
if (paintEngine->type() == QPaintEngine::Raster
|
||||
&& (devType == QInternal::Widget ||
|
||||
devType == QInternal::Pixmap ||
|
||||
devType == QInternal::Image)) {
|
||||
|
||||
const QImage *image = static_cast<const QImage *>(paintEngine->paintDevice());
|
||||
QCFType<CGColorSpaceRef> colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
|
||||
context = CGBitmapContextCreate((void *)image->bits(), image->width(), image->height(), 8,
|
||||
image->bytesPerLine(), colorSpace, qt_mac_bitmapInfoForImage(*image));
|
||||
|
||||
// Invert y axis
|
||||
CGContextTranslateCTM(context, 0, image->height());
|
||||
CGContextScaleCTM(context, 1, -1);
|
||||
|
||||
const qreal devicePixelRatio = image->devicePixelRatio();
|
||||
|
||||
if (devType == QInternal::Widget) {
|
||||
// Set the clip rect which is an intersection of the system clip
|
||||
// and the painter clip. To make matters more interesting these
|
||||
// are in device pixels and device-independent pixels, respectively.
|
||||
QRegion clip = painter->paintEngine()->systemClip(); // get system clip in device pixels
|
||||
QTransform native = painter->deviceTransform(); // get device transform. dx/dy is in device pixels
|
||||
|
||||
if (painter->hasClipping()) {
|
||||
QRegion r = painter->clipRegion(); // get painter clip, which is in device-independent pixels
|
||||
qt_mac_scale_region(&r, devicePixelRatio); // scale painter clip to device pixels
|
||||
r.translate(native.dx(), native.dy());
|
||||
if (clip.isEmpty())
|
||||
clip = r;
|
||||
else
|
||||
clip &= r;
|
||||
}
|
||||
qt_mac_clip_cg(context, clip, 0); // clip in device pixels
|
||||
|
||||
// Scale the context so that painting happens in device-independent pixels
|
||||
CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
|
||||
CGContextTranslateCTM(context, native.dx() / devicePixelRatio, native.dy() / devicePixelRatio);
|
||||
} else {
|
||||
// Scale to paint in device-independent pixels
|
||||
CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
|
||||
}
|
||||
} else {
|
||||
qDebug() << "QMacCGContext:: Unsupported painter devtype type" << devType;
|
||||
if (paintEngine->type() != QPaintEngine::Raster) {
|
||||
qWarning() << "QMacCGContext:: Unsupported paint engine type" << paintEngine->type();
|
||||
return;
|
||||
}
|
||||
|
||||
// The raster paint engine always operates on a QImage
|
||||
Q_ASSERT(paintEngine->paintDevice()->devType() == QInternal::Image);
|
||||
|
||||
// On behalf of one of these supported painter devices
|
||||
switch (int painterDeviceType = painter->device()->devType()) {
|
||||
case QInternal::Pixmap:
|
||||
case QInternal::Image:
|
||||
case QInternal::Widget:
|
||||
break;
|
||||
default:
|
||||
qWarning() << "QMacCGContext:: Unsupported paint device type" << painterDeviceType;
|
||||
return;
|
||||
}
|
||||
|
||||
// Applying the clip is so entangled with the rest of the context setup
|
||||
// that for simplicity we just pass in the painter.
|
||||
initialize(static_cast<const QImage *>(paintEngine->paintDevice()), painter);
|
||||
}
|
||||
|
||||
void QMacCGContext::initialize(const QImage *image, QPainter *painter)
|
||||
{
|
||||
QCFType<CGColorSpaceRef> colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
|
||||
context = CGBitmapContextCreate((void *)image->bits(), image->width(), image->height(), 8,
|
||||
image->bytesPerLine(), colorSpace, qt_mac_bitmapInfoForImage(*image));
|
||||
|
||||
// Invert y axis
|
||||
CGContextTranslateCTM(context, 0, image->height());
|
||||
CGContextScaleCTM(context, 1, -1);
|
||||
|
||||
const qreal devicePixelRatio = image->devicePixelRatio();
|
||||
|
||||
if (painter && painter->device()->devType() == QInternal::Widget) {
|
||||
// Set the clip rect which is an intersection of the system clip and the painter clip
|
||||
QRegion clip = painter->paintEngine()->systemClip();
|
||||
QTransform deviceTransform = painter->deviceTransform();
|
||||
|
||||
if (painter->hasClipping()) {
|
||||
// To make matters more interesting the painter clip is in device-independent pixels,
|
||||
// so we need to scale it to match the device-pixels of the system clip.
|
||||
QRegion painterClip = painter->clipRegion();
|
||||
qt_mac_scale_region(&painterClip, devicePixelRatio);
|
||||
|
||||
painterClip.translate(deviceTransform.dx(), deviceTransform.dy());
|
||||
|
||||
if (clip.isEmpty())
|
||||
clip = painterClip;
|
||||
else
|
||||
clip &= painterClip;
|
||||
}
|
||||
|
||||
qt_mac_clip_cg(context, clip, 0);
|
||||
|
||||
CGContextTranslateCTM(context, deviceTransform.dx(), deviceTransform.dy());
|
||||
}
|
||||
|
||||
// Scale the context so that painting happens in device-independent pixels
|
||||
CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -51,6 +51,8 @@
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtCore/private/qcore_mac_p.h>
|
||||
|
||||
#include <QtGui/private/qtguiglobal_p.h>
|
||||
#include <QtGui/qregion.h>
|
||||
#include <QtGui/qpalette.h>
|
||||
@ -89,38 +91,16 @@ Q_GUI_EXPORT QBrush qt_mac_toQBrush(CGColorRef color);
|
||||
class Q_GUI_EXPORT QMacCGContext
|
||||
{
|
||||
public:
|
||||
inline QMacCGContext() { context = 0; }
|
||||
QMacCGContext() = default;
|
||||
QMacCGContext(QPaintDevice *pdev);
|
||||
QMacCGContext(QPainter *p);
|
||||
inline QMacCGContext(CGContextRef cg, bool takeOwnership = false) {
|
||||
context = cg;
|
||||
if (!takeOwnership)
|
||||
CGContextRetain(context);
|
||||
}
|
||||
inline QMacCGContext(const QMacCGContext ©) : context(0) { *this = copy; }
|
||||
inline ~QMacCGContext() {
|
||||
if (context)
|
||||
CGContextRelease(context);
|
||||
}
|
||||
inline bool isNull() const { return context; }
|
||||
inline operator CGContextRef() { return context; }
|
||||
inline QMacCGContext &operator=(const QMacCGContext ©) {
|
||||
if (context)
|
||||
CGContextRelease(context);
|
||||
context = copy.context;
|
||||
CGContextRetain(context);
|
||||
return *this;
|
||||
}
|
||||
inline QMacCGContext &operator=(CGContextRef cg) {
|
||||
if (context)
|
||||
CGContextRelease(context);
|
||||
context = cg;
|
||||
CGContextRetain(context); //we do not take ownership
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator CGContextRef() { return context; }
|
||||
|
||||
private:
|
||||
CGContextRef context;
|
||||
void initialize(QPaintDevice *paintDevice);
|
||||
void initialize(const QImage *, QPainter *painter = nullptr);
|
||||
QCFType<CGContextRef> context;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
QShaderFormat::QShaderFormat() noexcept
|
||||
: m_api(NoApi)
|
||||
, m_shaderType(Fragment)
|
||||
{
|
||||
}
|
||||
|
||||
@ -106,6 +107,9 @@ bool QShaderFormat::supports(const QShaderFormat &other) const noexcept
|
||||
if (m_version < other.m_version)
|
||||
return false;
|
||||
|
||||
if (m_shaderType != other.m_shaderType)
|
||||
return false;
|
||||
|
||||
const auto containsAllExtensionsFromOther = std::includes(m_extensions.constBegin(),
|
||||
m_extensions.constEnd(),
|
||||
other.m_extensions.constBegin(),
|
||||
@ -119,12 +123,23 @@ bool QShaderFormat::supports(const QShaderFormat &other) const noexcept
|
||||
return true;
|
||||
}
|
||||
|
||||
QShaderFormat::ShaderType QShaderFormat::shaderType() const Q_DECL_NOTHROW
|
||||
{
|
||||
return m_shaderType;
|
||||
}
|
||||
|
||||
void QShaderFormat::setShaderType(QShaderFormat::ShaderType shaderType) Q_DECL_NOTHROW
|
||||
{
|
||||
m_shaderType = shaderType;
|
||||
}
|
||||
|
||||
bool operator==(const QShaderFormat &lhs, const QShaderFormat &rhs) noexcept
|
||||
{
|
||||
return lhs.api() == rhs.api()
|
||||
&& lhs.version() == rhs.version()
|
||||
&& lhs.extensions() == rhs.extensions()
|
||||
&& lhs.vendor() == rhs.vendor();
|
||||
&& lhs.vendor() == rhs.vendor()
|
||||
&& lhs.shaderType() == rhs.shaderType();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -69,6 +69,15 @@ public:
|
||||
OpenGLES
|
||||
};
|
||||
|
||||
enum ShaderType : int {
|
||||
Vertex = 0,
|
||||
TessellationControl,
|
||||
TessellationEvaluation,
|
||||
Geometry,
|
||||
Fragment,
|
||||
Compute
|
||||
};
|
||||
|
||||
Q_GUI_EXPORT QShaderFormat() noexcept;
|
||||
|
||||
Q_GUI_EXPORT Api api() const noexcept;
|
||||
@ -86,11 +95,15 @@ public:
|
||||
Q_GUI_EXPORT bool isValid() const noexcept;
|
||||
Q_GUI_EXPORT bool supports(const QShaderFormat &other) const noexcept;
|
||||
|
||||
Q_GUI_EXPORT ShaderType shaderType() const Q_DECL_NOTHROW;
|
||||
Q_GUI_EXPORT void setShaderType(ShaderType shaderType) Q_DECL_NOTHROW;
|
||||
|
||||
private:
|
||||
Api m_api;
|
||||
QVersionNumber m_version;
|
||||
QStringList m_extensions;
|
||||
QString m_vendor;
|
||||
ShaderType m_shaderType;
|
||||
};
|
||||
|
||||
Q_GUI_EXPORT bool operator==(const QShaderFormat &lhs, const QShaderFormat &rhs) noexcept;
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "qshadergenerator_p.h"
|
||||
|
||||
#include "qshaderlanguage_p.h"
|
||||
#include <QRegularExpression>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -56,7 +57,10 @@ namespace
|
||||
case QShaderLanguage::Const:
|
||||
return "const";
|
||||
case QShaderLanguage::Input:
|
||||
return "varying";
|
||||
if (format.shaderType() == QShaderFormat::Vertex)
|
||||
return "attribute";
|
||||
else
|
||||
return "varying";
|
||||
case QShaderLanguage::Output:
|
||||
return ""; // Although fragment shaders for <=2 only have fixed outputs
|
||||
case QShaderLanguage::Uniform:
|
||||
@ -314,12 +318,22 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
||||
[enabledLayers] (const QString &s) { return enabledLayers.contains(s); });
|
||||
};
|
||||
|
||||
QVector<QString> globalInputVariables;
|
||||
const QRegularExpression globalInputExtractRegExp(QStringLiteral("^.*\\s+(\\w+).*;$"));
|
||||
|
||||
const QVector<QShaderNode> nodes = graph.nodes();
|
||||
for (const QShaderNode &node : nodes) {
|
||||
if (intersectsEnabledLayers(node.layers())) {
|
||||
const QByteArrayList headerSnippets = node.rule(format).headerSnippets;
|
||||
for (const QByteArray &snippet : headerSnippets) {
|
||||
code << replaceParameters(snippet, node, format);
|
||||
|
||||
// If node is an input, record the variable name into the globalInputVariables vector
|
||||
if (node.type() == QShaderNode::Input) {
|
||||
const QRegularExpressionMatch match = globalInputExtractRegExp.match(QString::fromUtf8(code.last()));
|
||||
if (match.hasMatch())
|
||||
globalInputVariables.push_back(match.captured(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -328,6 +342,14 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
||||
code << QByteArrayLiteral("void main()");
|
||||
code << QByteArrayLiteral("{");
|
||||
|
||||
// Table to store temporary variables that should be replaced by global
|
||||
// variables. This avoids having vec3 v56 = vertexPosition; when we could
|
||||
// just use vertexPosition directly.
|
||||
// The added benefit is when having arrays, we don't try to create
|
||||
// mat4 v38 = skinningPalelette[100] which would be invalid
|
||||
QHash<QString, QString> localReferencesToGlobalInputs;
|
||||
const QRegularExpression localToGlobalRegExp(QStringLiteral("^.*\\s+(\\w+)\\s*=\\s*(\\w+).*;$"));
|
||||
|
||||
for (const QShaderGraph::Statement &statement : graph.createStatements(enabledLayers)) {
|
||||
const QShaderNode node = statement.node;
|
||||
QByteArray line = node.rule(format).substitution;
|
||||
@ -338,6 +360,9 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
||||
const bool isInput = port.direction == QShaderNodePort::Input;
|
||||
|
||||
const int portIndex = statement.portIndex(portDirection, portName);
|
||||
|
||||
Q_ASSERT(portIndex >= 0);
|
||||
|
||||
const int variableIndex = isInput ? statement.inputs.at(portIndex)
|
||||
: statement.outputs.at(portIndex);
|
||||
if (variableIndex < 0)
|
||||
@ -345,15 +370,51 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
||||
|
||||
const auto placeholder = QByteArray(QByteArrayLiteral("$") + portName.toUtf8());
|
||||
const auto variable = QByteArray(QByteArrayLiteral("v") + QByteArray::number(variableIndex));
|
||||
|
||||
line.replace(placeholder, variable);
|
||||
}
|
||||
|
||||
code << QByteArrayLiteral(" ") + replaceParameters(line, node, format);
|
||||
const QByteArray substitutionedLine = replaceParameters(line, node, format);
|
||||
|
||||
// Record name of temporary variable that possibly references a global input
|
||||
// We will replace the temporary variables by the matching global variables later
|
||||
bool isAGlobalInputVariable = false;
|
||||
if (node.type() == QShaderNode::Input) {
|
||||
const QRegularExpressionMatch match = localToGlobalRegExp.match(QString::fromUtf8(substitutionedLine));
|
||||
if (match.hasMatch()) {
|
||||
const QString globalVariable = match.captured(2);
|
||||
if (globalInputVariables.contains(globalVariable)) {
|
||||
const QString localVariable = match.captured(1);
|
||||
// TO DO: Clean globalVariable (remove brackets ...)
|
||||
localReferencesToGlobalInputs.insert(localVariable, globalVariable);
|
||||
isAGlobalInputVariable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only insert content for lines aren't inputs or have not matching
|
||||
// globalVariables for now
|
||||
if (!isAGlobalInputVariable)
|
||||
code << QByteArrayLiteral(" ") + substitutionedLine;
|
||||
}
|
||||
|
||||
code << QByteArrayLiteral("}");
|
||||
code << QByteArray();
|
||||
return code.join('\n');
|
||||
|
||||
// Replace occurrences of local variables which reference a global variable
|
||||
// by the global variables directly
|
||||
auto it = localReferencesToGlobalInputs.cbegin();
|
||||
const auto end = localReferencesToGlobalInputs.cend();
|
||||
QString codeString = QString::fromUtf8(code.join('\n'));
|
||||
|
||||
while (it != end) {
|
||||
const QRegularExpression r(QStringLiteral("\\b(%1)([\\b|\\.|;|\\)|\\[|\\s|\\*|\\+|\\/|\\-|,])").arg(it.key()),
|
||||
QRegularExpression::MultilineOption);
|
||||
codeString.replace(r, QStringLiteral("%1\\2").arg(it.value()));
|
||||
++it;
|
||||
}
|
||||
|
||||
return codeString.toUtf8();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -251,6 +251,17 @@ void QShaderNodesLoader::load(const QJsonObject &prototypesObject)
|
||||
break;
|
||||
}
|
||||
|
||||
// We default out to a Fragment ShaderType if nothing is specified
|
||||
// as that was the initial behavior we introduced
|
||||
const QString shaderType = formatObject.value(QStringLiteral("shaderType")).toString();
|
||||
format.setShaderType(shaderType == QStringLiteral("Fragment") ? QShaderFormat::Fragment
|
||||
: shaderType == QStringLiteral("Vertex") ? QShaderFormat::Vertex
|
||||
: shaderType == QStringLiteral("TessellationControl") ? QShaderFormat::TessellationControl
|
||||
: shaderType == QStringLiteral("TessellationEvaluation") ? QShaderFormat::TessellationEvaluation
|
||||
: shaderType == QStringLiteral("Geometry") ? QShaderFormat::Geometry
|
||||
: shaderType == QStringLiteral("Compute") ? QShaderFormat::Compute
|
||||
: QShaderFormat::Fragment);
|
||||
|
||||
const QByteArray substitution = substitutionValue.toString().toUtf8();
|
||||
|
||||
const QJsonValue snippetsValue = ruleObject.value(QStringLiteral("headerSnippets"));
|
||||
|
@ -385,8 +385,8 @@ QHostAddress QNetmask::address(QAbstractSocket::NetworkLayerProtocol protocol) c
|
||||
\value LocalHost The IPv4 localhost address. Equivalent to QHostAddress("127.0.0.1").
|
||||
\value LocalHostIPv6 The IPv6 localhost address. Equivalent to QHostAddress("::1").
|
||||
\value Broadcast The IPv4 broadcast address. Equivalent to QHostAddress("255.255.255.255").
|
||||
\value AnyIPv4 The IPv4 any-address. Equivalent to QHostAddress("0.0.0.0"). A socket bound with this address will listen only on IPv4 interaces.
|
||||
\value AnyIPv6 The IPv6 any-address. Equivalent to QHostAddress("::"). A socket bound with this address will listen only on IPv6 interaces.
|
||||
\value AnyIPv4 The IPv4 any-address. Equivalent to QHostAddress("0.0.0.0"). A socket bound with this address will listen only on IPv4 interfaces.
|
||||
\value AnyIPv6 The IPv6 any-address. Equivalent to QHostAddress("::"). A socket bound with this address will listen only on IPv6 interfaces.
|
||||
\value Any The dual stack any-address. A socket bound with this address will listen on both IPv4 and IPv6 interfaces.
|
||||
*/
|
||||
|
||||
|
@ -268,7 +268,7 @@ EGLConfig QEglConfigChooser::chooseConfig()
|
||||
configureAttributes.append(EGL_OPENGL_ES_BIT);
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
Q_FALLTHROUGH();
|
||||
default:
|
||||
needsES2Plus = true;
|
||||
break;
|
||||
|
@ -134,7 +134,7 @@ QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatform
|
||||
|
||||
void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLContext *share)
|
||||
{
|
||||
m_format = q_glFormatFromConfig(m_eglDisplay, m_eglConfig);
|
||||
m_format = q_glFormatFromConfig(m_eglDisplay, m_eglConfig, format);
|
||||
// m_format now has the renderableType() resolved (it cannot be Default anymore)
|
||||
// but does not yet contain version, profile, options.
|
||||
m_shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : 0;
|
||||
@ -248,6 +248,12 @@ void QEGLPlatformContext::adopt(const QVariant &nativeHandle, QPlatformOpenGLCon
|
||||
value = 0;
|
||||
eglQueryContext(m_eglDisplay, context, EGL_CONTEXT_CLIENT_TYPE, &value);
|
||||
if (value == EGL_OPENGL_API || value == EGL_OPENGL_ES_API) {
|
||||
// if EGL config supports both OpenGL and OpenGL ES render type,
|
||||
// q_glFormatFromConfig() with the default "referenceFormat" parameter
|
||||
// will always figure it out as OpenGL render type.
|
||||
// We can override it to match user's real render type.
|
||||
if (value == EGL_OPENGL_ES_API)
|
||||
m_format.setRenderableType(QSurfaceFormat::OpenGLES);
|
||||
m_api = value;
|
||||
eglBindAPI(m_api);
|
||||
} else {
|
||||
|
@ -6,7 +6,7 @@ CONFIG += static internal_module
|
||||
|
||||
DEFINES += QT_NO_CAST_FROM_ASCII
|
||||
|
||||
QMAKE_USE_PRIVATE += xlib
|
||||
QMAKE_USE += xlib
|
||||
|
||||
HEADERS += qglxconvenience_p.h
|
||||
SOURCES += qglxconvenience.cpp
|
||||
|
@ -96,8 +96,8 @@ void QTsLibMouseHandler::readMouseData()
|
||||
int x = sample.x;
|
||||
int y = sample.y;
|
||||
|
||||
// work around missing coordinates on mouse release
|
||||
if (sample.pressure == 0 && sample.x == 0 && sample.y == 0) {
|
||||
// coordinates on release events can contain arbitrary values, just ignore them
|
||||
if (sample.pressure == 0) {
|
||||
x = m_x;
|
||||
y = m_y;
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ enum OutputConfiguration {
|
||||
OutputConfigOff,
|
||||
OutputConfigPreferred,
|
||||
OutputConfigCurrent,
|
||||
OutputConfigSkip,
|
||||
OutputConfigMode,
|
||||
OutputConfigModeline
|
||||
};
|
||||
@ -191,6 +192,8 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
|
||||
configuration = OutputConfigPreferred;
|
||||
} else if (mode == "current") {
|
||||
configuration = OutputConfigCurrent;
|
||||
} else if (mode == "skip") {
|
||||
configuration = OutputConfigSkip;
|
||||
} else if (sscanf(mode.constData(), "%dx%d@%d", &configurationSize.rwidth(), &configurationSize.rheight(),
|
||||
&configurationRefresh) == 3)
|
||||
{
|
||||
@ -229,6 +232,11 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (configuration == OutputConfigSkip) {
|
||||
qCDebug(qLcKmsDebug) << "Skipping output" << connectorName;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Get the current mode on the current crtc
|
||||
drmModeModeInfo crtc_mode;
|
||||
memset(&crtc_mode, 0, sizeof crtc_mode);
|
||||
|
@ -188,14 +188,15 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
|
||||
topLeftRect.width(), topLeftRect.height());
|
||||
}
|
||||
|
||||
static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &targetWindowRect,
|
||||
static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &sourceWindowRect,
|
||||
const QRect &targetWindowRect,
|
||||
QOpenGLTextureBlitter *blitter, QMatrix4x4 *rotationMatrix)
|
||||
{
|
||||
const QRect clipRect = textures->clipRect(idx);
|
||||
if (clipRect.isEmpty())
|
||||
return;
|
||||
|
||||
const QRect rectInWindow = textures->geometry(idx);
|
||||
const QRect rectInWindow = textures->geometry(idx).translated(sourceWindowRect.topLeft());
|
||||
const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft());
|
||||
const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height());
|
||||
|
||||
@ -218,7 +219,7 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window)
|
||||
const QRect targetWindowRect(QPoint(0, 0), m_targetWindow->geometry().size());
|
||||
float currentOpacity = 1.0f;
|
||||
BlendStateBinder blend;
|
||||
|
||||
const QRect sourceWindowRect = window->sourceWindow()->geometry();
|
||||
for (int i = 0; i < textures->count(); ++i) {
|
||||
uint textureId = textures->textureId(i);
|
||||
const float opacity = window->sourceWindow()->opacity();
|
||||
@ -243,16 +244,16 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window)
|
||||
target = m_rotationMatrix * target;
|
||||
m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
|
||||
} else if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) {
|
||||
// Texture from an FBO belonging to a QOpenGLWidget
|
||||
// Texture from an FBO belonging to a QOpenGLWidget or QQuickWidget
|
||||
blend.set(false);
|
||||
clippedBlit(textures, i, targetWindowRect, &m_blitter, m_rotation ? &m_rotationMatrix : nullptr);
|
||||
clippedBlit(textures, i, sourceWindowRect, targetWindowRect, &m_blitter, m_rotation ? &m_rotationMatrix : nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < textures->count(); ++i) {
|
||||
if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) {
|
||||
blend.set(true);
|
||||
clippedBlit(textures, i, targetWindowRect, &m_blitter, m_rotation ? &m_rotationMatrix : nullptr);
|
||||
clippedBlit(textures, i, sourceWindowRect, targetWindowRect, &m_blitter, m_rotation ? &m_rotationMatrix : nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,7 +300,7 @@ void QGenericEngine::doRequestUpdate()
|
||||
if (interface.flags() & QNetworkInterface::IsLoopBack)
|
||||
continue;
|
||||
|
||||
#ifndef Q_OS_WINRT
|
||||
#ifndef Q_OS_WIN
|
||||
// ignore WLAN interface handled in separate engine
|
||||
if (qGetInterfaceType(interface.name()) == QNetworkConfiguration::BearerWLAN)
|
||||
continue;
|
||||
|
@ -93,6 +93,7 @@ private:
|
||||
|
||||
QRegion dirtyRegion; // In unscaled coordinates
|
||||
QImage *asImage();
|
||||
qreal devicePixelRatio() const { return m_devicePixelRatio; }
|
||||
|
||||
private:
|
||||
qreal m_devicePixelRatio;
|
||||
|
@ -460,12 +460,29 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion,
|
||||
NSView *backingStoreView = static_cast<QCocoaWindow *>(window()->handle())->view();
|
||||
NSView *flushedView = static_cast<QCocoaWindow *>(flushedWindow->handle())->view();
|
||||
|
||||
// If the backingstore is just flushed, without being painted to first, then we may
|
||||
// end in a situation where the backingstore is flushed to a layer with a different
|
||||
// scale factor than the one it was created for in beginPaint. This is the client's
|
||||
// fault in not picking up the change in scale factor of the window and re-painting
|
||||
// the backingstore accordingly. To smoothing things out, we warn about this situation,
|
||||
// and change the layer's contentsScale to match the scale of the back buffer, so that
|
||||
// we at least cover the whole layer. This is necessary since we set the view's
|
||||
// contents placement policy to NSViewLayerContentsPlacementTopLeft, which means
|
||||
// AppKit will not do any scaling on our behalf.
|
||||
if (m_buffers.back()->devicePixelRatio() != flushedView.layer.contentsScale) {
|
||||
qCWarning(lcQpaBackingStore) << "Back buffer dpr of" << m_buffers.back()->devicePixelRatio()
|
||||
<< "doesn't match" << flushedView.layer << "contents scale of" << flushedView.layer.contentsScale
|
||||
<< "- updating layer to match.";
|
||||
flushedView.layer.contentsScale = m_buffers.back()->devicePixelRatio();
|
||||
}
|
||||
|
||||
id backBufferSurface = (__bridge id)m_buffers.back()->surface();
|
||||
if (flushedView.layer.contents == backBufferSurface) {
|
||||
// We've managed to paint to the back buffer again before Core Animation had time
|
||||
// to flush the transaction and persist the layer changes to the window server.
|
||||
// The layer already knows about the back buffer, and we don't need to re-apply
|
||||
// it to pick up the surface changes, so bail out early.
|
||||
// to flush the transaction and persist the layer changes to the window server, or
|
||||
// we've been asked to flush without painting anything. The layer already knows about
|
||||
// the back buffer, and we don't need to re-apply it to pick up any possible surface
|
||||
// changes, so bail out early.
|
||||
qCInfo(lcQpaBackingStore).nospace() << "Skipping flush of " << flushedView
|
||||
<< ", layer already reflects back buffer";
|
||||
return;
|
||||
|
@ -154,6 +154,7 @@
|
||||
<< "due to being" << ([self layerExplicitlyRequested] ? "explicitly requested"
|
||||
: [self shouldUseMetalLayer] ? "needed by surface type" : "enabled by macOS");
|
||||
[super setLayer:layer];
|
||||
layer.delegate = self;
|
||||
}
|
||||
|
||||
- (NSViewLayerContentsRedrawPolicy)layerContentsRedrawPolicy
|
||||
|
@ -199,6 +199,10 @@ QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
|
||||
QEglFSWindow *w = qt_egl_device_integration()->createWindow(window);
|
||||
w->create();
|
||||
|
||||
const auto showWithoutActivating = window->property("_q_showWithoutActivating");
|
||||
if (showWithoutActivating.isValid() && showWithoutActivating.toBool())
|
||||
return w;
|
||||
|
||||
// Activate only the window for the primary screen to make input work
|
||||
if (window->type() != Qt::ToolTip && window->screen() == QGuiApplication::primaryScreen())
|
||||
w->requestActivateWindow();
|
||||
|
@ -167,6 +167,9 @@ void QEglFSWindow::create()
|
||||
|
||||
void QEglFSWindow::destroy()
|
||||
{
|
||||
if (!m_flags.testFlag(Created))
|
||||
return; // already destroyed
|
||||
|
||||
#ifndef QT_NO_OPENGL
|
||||
QOpenGLCompositor::instance()->removeWindow(this);
|
||||
#endif
|
||||
|
@ -55,6 +55,9 @@ public:
|
||||
: QEglFSWindow(w),
|
||||
m_integration(integration)
|
||||
{ }
|
||||
|
||||
~QEglFSKmsGbmWindow() { destroy(); }
|
||||
|
||||
void resetSurface() override;
|
||||
void invalidateSurface() override;
|
||||
|
||||
|
@ -117,6 +117,8 @@ public:
|
||||
, m_framePending(false)
|
||||
{ }
|
||||
|
||||
~QEglFSKmsEglDeviceWindow() { destroy(); }
|
||||
|
||||
void invalidateSurface() override;
|
||||
void resetSurface() override;
|
||||
void flip();
|
||||
|
@ -205,6 +205,9 @@ public:
|
||||
: QEglFSWindow(w)
|
||||
, m_integration(integration)
|
||||
{}
|
||||
|
||||
~QEglFSKmsVsp2Window() { destroy(); }
|
||||
|
||||
void resetSurface() override;
|
||||
void invalidateSurface() override;
|
||||
const QEglFSKmsVsp2Integration *m_integration;
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#include <QtCore/qurl.h>
|
||||
#include <QtCore/qmimedata.h>
|
||||
#include "qwindowsmime.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -48,8 +49,9 @@ QT_BEGIN_NAMESPACE
|
||||
\class QWindowsDropDataObject
|
||||
\brief QWindowsOleDataObject subclass specialized for handling Drag&Drop.
|
||||
|
||||
Only allows "text/uri-list" data to be exported as CF_HDROP, to allow dropped
|
||||
files to be attached to Office applications (instead of adding an URL link).
|
||||
Prevents "text/uri-list" data for local files from being exported as text
|
||||
or URLs, to allow dropped files to be attached to Office applications
|
||||
(instead of creating local hyperlinks).
|
||||
|
||||
\internal
|
||||
\ingroup qt-lighthouse-win
|
||||
@ -80,14 +82,22 @@ QWindowsDropDataObject::QueryGetData(LPFORMATETC pformatetc)
|
||||
return QWindowsOleDataObject::QueryGetData(pformatetc);
|
||||
}
|
||||
|
||||
// If the data is text/uri-list for local files, tell we can only export it as CF_HDROP.
|
||||
// If the data is "text/uri-list" only, and all URIs are for local files,
|
||||
// we prevent it from being exported as text or URLs, to make target applications
|
||||
// like MS Office attach or open the files instead of creating local hyperlinks.
|
||||
bool QWindowsDropDataObject::shouldIgnore(LPFORMATETC pformatetc) const
|
||||
{
|
||||
QMimeData *dropData = mimeData();
|
||||
|
||||
if (dropData && dropData->hasFormat(QStringLiteral("text/uri-list")) && (pformatetc->cfFormat != CF_HDROP)) {
|
||||
QList<QUrl> urls = dropData->urls();
|
||||
return std::any_of(urls.cbegin(), urls.cend(), [] (const QUrl &u) { return u.isLocalFile(); });
|
||||
if (dropData && dropData->formats().size() == 1 && dropData->hasUrls()) {
|
||||
QString formatName = QWindowsMimeConverter::clipboardFormatName(pformatetc->cfFormat);
|
||||
if (pformatetc->cfFormat == CF_UNICODETEXT
|
||||
|| pformatetc->cfFormat == CF_TEXT
|
||||
|| formatName == QStringLiteral("UniformResourceLocator")
|
||||
|| formatName == QStringLiteral("UniformResourceLocatorW")) {
|
||||
QList<QUrl> urls = dropData->urls();
|
||||
return std::all_of(urls.cbegin(), urls.cend(), [] (const QUrl &u) { return u.isLocalFile(); });
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -879,21 +879,16 @@ bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, con
|
||||
#if defined(WM_APPCOMMAND)
|
||||
const int cmd = GET_APPCOMMAND_LPARAM(msg.lParam);
|
||||
// QTBUG-57198, do not send mouse-synthesized commands as key events in addition
|
||||
bool skipPressRelease = false;
|
||||
switch (GET_DEVICE_LPARAM(msg.lParam)) {
|
||||
case FAPPCOMMAND_MOUSE:
|
||||
return false;
|
||||
case FAPPCOMMAND_KEY:
|
||||
// QTBUG-62838, swallow WM_KEYDOWN, WM_KEYUP for commands that are
|
||||
// reflected in VK(s) like VK_MEDIA_NEXT_TRACK. Don't do that for
|
||||
// APPCOMMAND_BROWSER_HOME as that one does not trigger two events
|
||||
if (cmd != APPCOMMAND_BROWSER_HOME) {
|
||||
MSG peekedMsg;
|
||||
if (PeekMessage(&peekedMsg, msg.hwnd, 0, 0, PM_NOREMOVE)
|
||||
&& peekedMsg.message == WM_KEYDOWN) {
|
||||
PeekMessage(&peekedMsg, msg.hwnd, 0, 0, PM_REMOVE);
|
||||
PeekMessage(&peekedMsg, msg.hwnd, 0, 0, PM_REMOVE);
|
||||
}
|
||||
}
|
||||
// QTBUG-62838, use WM_KEYDOWN/WM_KEYUP for commands that are reflected
|
||||
// in VK(s) like VK_MEDIA_NEXT_TRACK, to get correct codes and autorepeat.
|
||||
// Don't do that for APPCOMMAND_BROWSER_HOME as that one does not trigger two events.
|
||||
if (cmd != APPCOMMAND_BROWSER_HOME)
|
||||
skipPressRelease = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -908,7 +903,8 @@ bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, con
|
||||
return false;
|
||||
|
||||
const int qtKey = int(CmdTbl[cmd]);
|
||||
sendExtendedPressRelease(receiver, qtKey, Qt::KeyboardModifier(state), 0, 0, 0);
|
||||
if (!skipPressRelease)
|
||||
sendExtendedPressRelease(receiver, qtKey, Qt::KeyboardModifier(state), 0, 0, 0);
|
||||
// QTBUG-43343: Make sure to return false if Qt does not handle the key, otherwise,
|
||||
// the keys are not passed to the active media player.
|
||||
# if QT_CONFIG(shortcut)
|
||||
|
@ -1087,7 +1087,10 @@ bool QWindowsMimeImage::canConvertFromMime(const FORMATETC &formatetc, const QMi
|
||||
const QImage image = qvariant_cast<QImage>(mimeData->imageData());
|
||||
if (image.isNull())
|
||||
return false;
|
||||
return cf == CF_DIBV5 || (cf == CF_DIB) || cf == int(CF_PNG);
|
||||
// QTBUG-64322: Use PNG only for transparent images as otherwise MS PowerPoint
|
||||
// cannot handle it.
|
||||
return cf == CF_DIBV5 || cf == CF_DIB
|
||||
|| (cf == int(CF_PNG) && image.hasAlphaChannel());
|
||||
}
|
||||
|
||||
bool QWindowsMimeImage::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
|
||||
|
@ -250,6 +250,23 @@ static Qt::MouseButtons mouseButtonsFromKeyState(WPARAM keyState)
|
||||
return result;
|
||||
}
|
||||
|
||||
static Qt::MouseButtons queryMouseButtons()
|
||||
{
|
||||
Qt::MouseButtons result = Qt::NoButton;
|
||||
const bool mouseSwapped = GetSystemMetrics(SM_SWAPBUTTON);
|
||||
if (GetAsyncKeyState(VK_LBUTTON) < 0)
|
||||
result |= mouseSwapped ? Qt::RightButton: Qt::LeftButton;
|
||||
if (GetAsyncKeyState(VK_RBUTTON) < 0)
|
||||
result |= mouseSwapped ? Qt::LeftButton : Qt::RightButton;
|
||||
if (GetAsyncKeyState(VK_MBUTTON) < 0)
|
||||
result |= Qt::MidButton;
|
||||
if (GetAsyncKeyState(VK_XBUTTON1) < 0)
|
||||
result |= Qt::XButton1;
|
||||
if (GetAsyncKeyState(VK_XBUTTON2) < 0)
|
||||
result |= Qt::XButton2;
|
||||
return result;
|
||||
}
|
||||
|
||||
static QWindow *getWindowUnderPointer(QWindow *window, QPoint globalPos)
|
||||
{
|
||||
QWindow *currentWindowUnderPointer = QWindowsScreen::windowAt(globalPos, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT);
|
||||
@ -531,7 +548,7 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
|
||||
if (!QWindowsContext::user32dll.getPointerDeviceRects(penInfo->pointerInfo.sourceDevice, &pRect, &dRect))
|
||||
return false;
|
||||
|
||||
const quint32 pointerId = penInfo->pointerInfo.pointerId;
|
||||
const qint64 sourceDevice = (qint64)penInfo->pointerInfo.sourceDevice;
|
||||
const QPoint globalPos = QPoint(penInfo->pointerInfo.ptPixelLocation.x, penInfo->pointerInfo.ptPixelLocation.y);
|
||||
const QPoint localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPos);
|
||||
const QPointF hiResGlobalPos = QPointF(dRect.left + qreal(penInfo->pointerInfo.ptHimetricLocation.x - pRect.left)
|
||||
@ -547,7 +564,7 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
|
||||
|
||||
if (QWindowsContext::verbose > 1)
|
||||
qCDebug(lcQpaEvents).noquote().nospace() << showbase
|
||||
<< __FUNCTION__ << " pointerId=" << pointerId
|
||||
<< __FUNCTION__ << " sourceDevice=" << sourceDevice
|
||||
<< " globalPos=" << globalPos << " localPos=" << localPos << " hiResGlobalPos=" << hiResGlobalPos
|
||||
<< " message=" << hex << msg.message
|
||||
<< " flags=" << hex << penInfo->pointerInfo.pointerFlags;
|
||||
@ -570,7 +587,7 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
|
||||
|
||||
switch (msg.message) {
|
||||
case WM_POINTERENTER: {
|
||||
QWindowSystemInterface::handleTabletEnterProximityEvent(device, type, pointerId);
|
||||
QWindowSystemInterface::handleTabletEnterProximityEvent(device, type, sourceDevice);
|
||||
m_windowUnderPointer = window;
|
||||
// The local coordinates may fall outside the window.
|
||||
// Wait until the next update to send the enter event.
|
||||
@ -583,12 +600,12 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
|
||||
m_windowUnderPointer = nullptr;
|
||||
m_currentWindow = nullptr;
|
||||
}
|
||||
QWindowSystemInterface::handleTabletLeaveProximityEvent(device, type, pointerId);
|
||||
QWindowSystemInterface::handleTabletLeaveProximityEvent(device, type, sourceDevice);
|
||||
break;
|
||||
case WM_POINTERDOWN:
|
||||
case WM_POINTERUP:
|
||||
case WM_POINTERUPDATE: {
|
||||
QWindow *target = QGuiApplicationPrivate::tabletDevicePoint(pointerId).target; // Pass to window that grabbed it.
|
||||
QWindow *target = QGuiApplicationPrivate::tabletDevicePoint(sourceDevice).target; // Pass to window that grabbed it.
|
||||
if (!target && m_windowUnderPointer)
|
||||
target = m_windowUnderPointer;
|
||||
if (!target)
|
||||
@ -607,7 +624,7 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
|
||||
|
||||
QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons,
|
||||
pressure, xTilt, yTilt, tangentialPressure, rotation, z,
|
||||
pointerId, keyModifiers);
|
||||
sourceDevice, keyModifiers);
|
||||
return false; // Allow mouse messages to be generated.
|
||||
}
|
||||
}
|
||||
@ -681,7 +698,6 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
|
||||
}
|
||||
|
||||
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
|
||||
const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam);
|
||||
QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
|
||||
|
||||
if (et == QtWindows::MouseWheelEvent)
|
||||
@ -709,7 +725,8 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
|
||||
const MouseEvent mouseEvent = eventFromMsg(msg);
|
||||
|
||||
if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) {
|
||||
QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons,
|
||||
const Qt::MouseButtons nonclientButtons = queryMouseButtons();
|
||||
QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, nonclientButtons,
|
||||
mouseEvent.button, mouseEvent.type, keyModifiers, source);
|
||||
return false; // Allow further event processing
|
||||
}
|
||||
@ -725,6 +742,8 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
|
||||
return true;
|
||||
}
|
||||
|
||||
const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam);
|
||||
|
||||
handleCaptureRelease(window, currentWindowUnderPointer, hwnd, mouseEvent.type, mouseButtons);
|
||||
handleEnterLeave(window, currentWindowUnderPointer, globalPos);
|
||||
|
||||
|
@ -113,6 +113,9 @@ void QWindowsUiaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event
|
||||
case QAccessible::ValueChanged:
|
||||
QWindowsUiaMainProvider::notifyValueChange(static_cast<QAccessibleValueChangeEvent *>(event));
|
||||
break;
|
||||
case QAccessible::SelectionAdd:
|
||||
QWindowsUiaMainProvider::notifySelectionChange(event);
|
||||
break;
|
||||
case QAccessible::TextAttributeChanged:
|
||||
case QAccessible::TextColumnChanged:
|
||||
case QAccessible::TextInserted:
|
||||
|
@ -146,9 +146,33 @@ void QWindowsUiaMainProvider::notifyStateChange(QAccessibleStateChangeEvent *eve
|
||||
void QWindowsUiaMainProvider::notifyValueChange(QAccessibleValueChangeEvent *event)
|
||||
{
|
||||
if (QAccessibleInterface *accessible = event->accessibleInterface()) {
|
||||
if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) {
|
||||
// Notifies changes in values of controls supporting the value interface.
|
||||
if (accessible->role() == QAccessible::ComboBox && accessible->childCount() > 0) {
|
||||
QAccessibleInterface *listacc = accessible->child(0);
|
||||
if (listacc && listacc->role() == QAccessible::List) {
|
||||
int count = listacc->childCount();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
QAccessibleInterface *item = listacc->child(i);
|
||||
if (item && item->text(QAccessible::Name) == event->value()) {
|
||||
if (!item->state().selected) {
|
||||
if (QAccessibleActionInterface *actionInterface = item->actionInterface())
|
||||
actionInterface->doAction(QAccessibleActionInterface::toggleAction());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (event->value().type() == QVariant::String) {
|
||||
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
|
||||
// Notifies changes in string values.
|
||||
VARIANT oldVal, newVal;
|
||||
clearVariant(&oldVal);
|
||||
setVariantString(event->value().toString(), &newVal);
|
||||
QWindowsUiaWrapper::instance()->raiseAutomationPropertyChangedEvent(provider, UIA_ValueValuePropertyId, oldVal, newVal);
|
||||
}
|
||||
} else if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) {
|
||||
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
|
||||
// Notifies changes in values of controls supporting the value interface.
|
||||
VARIANT oldVal, newVal;
|
||||
clearVariant(&oldVal);
|
||||
setVariantDouble(valueInterface->currentValue().toDouble(), &newVal);
|
||||
@ -158,6 +182,15 @@ void QWindowsUiaMainProvider::notifyValueChange(QAccessibleValueChangeEvent *eve
|
||||
}
|
||||
}
|
||||
|
||||
void QWindowsUiaMainProvider::notifySelectionChange(QAccessibleEvent *event)
|
||||
{
|
||||
if (QAccessibleInterface *accessible = event->accessibleInterface()) {
|
||||
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
|
||||
QWindowsUiaWrapper::instance()->raiseAutomationEvent(provider, UIA_SelectionItem_ElementSelectedEventId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Notifies changes in text content and selection state of text controls.
|
||||
void QWindowsUiaMainProvider::notifyTextChange(QAccessibleEvent *event)
|
||||
{
|
||||
|
@ -68,6 +68,7 @@ public:
|
||||
static void notifyFocusChange(QAccessibleEvent *event);
|
||||
static void notifyStateChange(QAccessibleStateChangeEvent *event);
|
||||
static void notifyValueChange(QAccessibleValueChangeEvent *event);
|
||||
static void notifySelectionChange(QAccessibleEvent *event);
|
||||
static void notifyTextChange(QAccessibleEvent *event);
|
||||
|
||||
// IUnknown
|
||||
|
@ -270,7 +270,9 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
|
||||
// ES does not support any format option
|
||||
m_format.setOptions(QSurfaceFormat::FormatOptions());
|
||||
}
|
||||
|
||||
// Robustness must match that of the shared context.
|
||||
if (share && share->format().testOption(QSurfaceFormat::ResetNotification))
|
||||
m_format.setOption(QSurfaceFormat::ResetNotification);
|
||||
Q_ASSERT(glVersions.count() > 0);
|
||||
|
||||
for (int i = 0; !m_context && i < glVersions.count(); i++) {
|
||||
|
@ -1156,66 +1156,6 @@ static QStyleHelper::WidgetSizePolicy qt_aqua_guess_size(const QWidget *widg, QS
|
||||
}
|
||||
#endif
|
||||
|
||||
static NSColor *qt_convertColorForContext(CGContextRef context, NSColor *color)
|
||||
{
|
||||
Q_ASSERT(color);
|
||||
Q_ASSERT(context);
|
||||
|
||||
CGColorSpaceRef targetCGColorSpace = CGBitmapContextGetColorSpace(context);
|
||||
NSColorSpace *targetNSColorSpace = [[NSColorSpace alloc] initWithCGColorSpace:targetCGColorSpace];
|
||||
NSColor *adjusted = [color colorUsingColorSpace:targetNSColorSpace];
|
||||
[targetNSColorSpace release];
|
||||
|
||||
return adjusted;
|
||||
}
|
||||
|
||||
static NSColor *qt_colorForContext(CGContextRef context, const CGFloat (&rgba)[4])
|
||||
{
|
||||
Q_ASSERT(context);
|
||||
|
||||
auto colorSpace = CGBitmapContextGetColorSpace(context);
|
||||
if (!colorSpace)
|
||||
return nil;
|
||||
|
||||
return qt_convertColorForContext(context, [NSColor colorWithSRGBRed:rgba[0] green:rgba[1] blue:rgba[2] alpha:rgba[3]]);
|
||||
}
|
||||
|
||||
static void qt_drawDisclosureButton(CGContextRef context, NSInteger state, bool selected, CGRect rect)
|
||||
{
|
||||
Q_ASSERT(context);
|
||||
|
||||
static const CGFloat gray[] = {0.55, 0.55, 0.55, 0.97};
|
||||
static const CGFloat white[] = {1.0, 1.0, 1.0, 0.9};
|
||||
|
||||
NSColor *fillColor = qt_colorForContext(context, selected ? white : gray);
|
||||
[fillColor setFill];
|
||||
|
||||
if (state == NSOffState) {
|
||||
static NSBezierPath *triangle = [[NSBezierPath alloc] init];
|
||||
[triangle removeAllPoints];
|
||||
// In off state, a disclosure button is an equilateral triangle
|
||||
// ('pointing' to the right) with a bound rect that can be described
|
||||
// as NSMakeRect(0, 0, 8, 9). Inside the 'rect' it's translated by
|
||||
// (2, 4).
|
||||
[triangle moveToPoint:NSMakePoint(rect.origin.x + 2, rect.origin.y + 4)];
|
||||
[triangle lineToPoint:NSMakePoint(rect.origin.x + 2, rect.origin.y + 4 + 9)];
|
||||
[triangle lineToPoint:NSMakePoint(rect.origin.x + 2 + 8, rect.origin.y + 4 + 4.5)];
|
||||
[triangle closePath];
|
||||
[triangle fill];
|
||||
} else {
|
||||
static NSBezierPath *openTriangle = [[NSBezierPath alloc] init];
|
||||
[openTriangle removeAllPoints];
|
||||
// In 'on' state, the button is an equilateral triangle (looking down)
|
||||
// with the bounding rect NSMakeRect(0, 0, 9, 8). Inside the 'rect'
|
||||
// it's translated by (1, 4).
|
||||
[openTriangle moveToPoint:NSMakePoint(rect.origin.x + 1, rect.origin.y + 4 + 8)];
|
||||
[openTriangle lineToPoint:NSMakePoint(rect.origin.x + 1 + 9, rect.origin.y + 4 + 8)];
|
||||
[openTriangle lineToPoint:NSMakePoint(rect.origin.x + 1 + 4.5, rect.origin.y + 4)];
|
||||
[openTriangle closePath];
|
||||
[openTriangle fill];
|
||||
}
|
||||
}
|
||||
|
||||
void QMacStylePrivate::drawFocusRing(QPainter *p, const QRectF &targetRect, int hMargin, int vMargin, const CocoaControl &cw) const
|
||||
{
|
||||
QPainterPath focusRingPath;
|
||||
@ -3301,15 +3241,8 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
|
||||
CGContextScaleCTM(cg, 1, -1);
|
||||
CGContextTranslateCTM(cg, -rect.origin.x, -rect.origin.y);
|
||||
|
||||
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave && !qt_mac_applicationIsInDarkMode()) {
|
||||
// When the real system theme is one of the 'Dark' themes, and an application forces the 'Aqua' theme,
|
||||
// under some conditions (see QTBUG-74515 for more details) NSButtonCell seems to select the 'Dark'
|
||||
// code path and is becoming transparent, thus 'invisible' on the white background. To workaround this,
|
||||
// we draw the disclose triangle manually:
|
||||
qt_drawDisclosureButton(cg, triangleCell.state, (opt->state & State_Selected) && viewHasFocus, rect);
|
||||
} else {
|
||||
[triangleCell drawBezelWithFrame:NSRectFromCGRect(rect) inView:[triangleCell controlView]];
|
||||
}
|
||||
[triangleCell drawBezelWithFrame:NSRectFromCGRect(rect) inView:[triangleCell controlView]];
|
||||
|
||||
d->restoreNSGraphicsContext(cg);
|
||||
break; }
|
||||
|
||||
|
@ -11343,7 +11343,7 @@ void QGraphicsItemEffectSourcePrivate::draw(QPainter *painter)
|
||||
}
|
||||
|
||||
// sourceRect must be in the given coordinate system
|
||||
QRect QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const
|
||||
QRectF QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const
|
||||
{
|
||||
QRectF effectRectF;
|
||||
|
||||
@ -11371,7 +11371,7 @@ QRect QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem sy
|
||||
*unpadded = true;
|
||||
}
|
||||
|
||||
return effectRectF.toAlignedRect();
|
||||
return effectRectF;
|
||||
}
|
||||
|
||||
QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
|
||||
@ -11389,7 +11389,8 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP
|
||||
|
||||
bool unpadded;
|
||||
const QRectF sourceRect = boundingRect(system);
|
||||
QRect effectRect = paddedEffectRect(system, mode, sourceRect, &unpadded);
|
||||
QRectF effectRectF = paddedEffectRect(system, mode, sourceRect, &unpadded);
|
||||
QRect effectRect = effectRectF.toAlignedRect();
|
||||
|
||||
if (offset)
|
||||
*offset = effectRect.topLeft();
|
||||
@ -11405,7 +11406,9 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP
|
||||
if (effectRect.isEmpty())
|
||||
return QPixmap();
|
||||
|
||||
QPixmap pixmap(effectRect.size());
|
||||
const auto dpr = info ? info->painter->device()->devicePixelRatioF() : 1.0;
|
||||
QPixmap pixmap(QRectF(effectRectF.topLeft(), effectRectF.size() * dpr).toAlignedRect().size());
|
||||
pixmap.setDevicePixelRatio(dpr);
|
||||
pixmap.fill(Qt::transparent);
|
||||
QPainter pixmapPainter(&pixmap);
|
||||
pixmapPainter.setRenderHints(info ? info->painter->renderHints() : QPainter::TextAntialiasing);
|
||||
|
@ -644,7 +644,7 @@ public:
|
||||
QPixmap pixmap(Qt::CoordinateSystem system,
|
||||
QPoint *offset,
|
||||
QGraphicsEffect::PixmapPadMode mode) const override;
|
||||
QRect paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded = nullptr) const;
|
||||
QRectF paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded = nullptr) const;
|
||||
|
||||
QGraphicsItem *item;
|
||||
QGraphicsItemPaintInfo *info;
|
||||
|
@ -4852,7 +4852,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
|
||||
&& painter->worldTransform().type() <= QTransform::TxTranslate)
|
||||
{
|
||||
QRectF sourceRect = sourced->boundingRect(Qt::DeviceCoordinates);
|
||||
QRect effectRect = sourced->paddedEffectRect(Qt::DeviceCoordinates, sourced->currentCachedMode(), sourceRect);
|
||||
QRect effectRect = sourced->paddedEffectRect(Qt::DeviceCoordinates, sourced->currentCachedMode(), sourceRect).toAlignedRect();
|
||||
|
||||
sourced->setCachedOffset(effectRect.topLeft());
|
||||
} else {
|
||||
|
@ -2283,13 +2283,15 @@ void QHeaderViewPrivate::_q_sectionsChanged(const QList<QPersistentModelIndex> &
|
||||
: index.row());
|
||||
// the new visualIndices are already adjusted / reset by initializeSections()
|
||||
const int newVisualIndex = visualIndex(newLogicalIndex);
|
||||
auto &newSection = sectionItems[newVisualIndex];
|
||||
newSection = item.section;
|
||||
if (newVisualIndex < sectionItems.count()) {
|
||||
auto &newSection = sectionItems[newVisualIndex];
|
||||
newSection = item.section;
|
||||
|
||||
if (newSection.isHidden) {
|
||||
// otherwise setSectionHidden will return without doing anything
|
||||
newSection.isHidden = false;
|
||||
q->setSectionHidden(newLogicalIndex, true);
|
||||
if (newSection.isHidden) {
|
||||
// otherwise setSectionHidden will return without doing anything
|
||||
newSection.isHidden = false;
|
||||
q->setSectionHidden(newLogicalIndex, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -650,11 +650,13 @@ QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *listview, int
|
||||
|Qt::ItemIsEnabled
|
||||
|Qt::ItemIsDragEnabled)
|
||||
{
|
||||
QListModel *model = listModel();
|
||||
{
|
||||
QSignalBlocker b(view);
|
||||
QSignalBlocker bm(model);
|
||||
setData(Qt::DisplayRole, text);
|
||||
}
|
||||
if (QListModel *model = listModel())
|
||||
if (model)
|
||||
model->insert(model->rowCount(), this);
|
||||
}
|
||||
|
||||
@ -683,12 +685,14 @@ QListWidgetItem::QListWidgetItem(const QIcon &icon,const QString &text,
|
||||
|Qt::ItemIsEnabled
|
||||
|Qt::ItemIsDragEnabled)
|
||||
{
|
||||
QListModel *model = listModel();
|
||||
{
|
||||
QSignalBlocker b(view);
|
||||
QSignalBlocker bm(model);
|
||||
setData(Qt::DisplayRole, text);
|
||||
setData(Qt::DecorationRole, icon);
|
||||
}
|
||||
if (QListModel *model = listModel())
|
||||
if (model)
|
||||
model->insert(model->rowCount(), this);
|
||||
}
|
||||
|
||||
|
@ -1448,7 +1448,8 @@ bool QOpenGLWidget::event(QEvent *e)
|
||||
{
|
||||
// Special case: did grabFramebuffer() for a hidden widget that then became visible.
|
||||
// Recreate all resources since the context now needs to share with the TLW's.
|
||||
d->reset();
|
||||
if (!qGuiApp->testAttribute(Qt::AA_ShareOpenGLContexts))
|
||||
d->reset();
|
||||
}
|
||||
if (!d->initialized && !size().isEmpty() && window()->windowHandle()) {
|
||||
d->initialize();
|
||||
|
@ -2908,7 +2908,10 @@ void QStyleSheetStyle::polish(QPalette &pal)
|
||||
|
||||
void QStyleSheetStyle::repolish(QWidget *w)
|
||||
{
|
||||
QList<const QObject *> children = w->findChildren<const QObject *>(QString());
|
||||
QList<const QObject *> children;
|
||||
children.reserve(w->children().size() + 1);
|
||||
for (auto child: qAsConst(w->children()))
|
||||
children.append(child);
|
||||
children.append(w);
|
||||
styleSheetCaches->styleSheetCache.remove(w);
|
||||
updateObjects(children);
|
||||
|
@ -69,6 +69,7 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSystemTrayIconSys;
|
||||
class QSystemTrayWatcher;
|
||||
class QPlatformSystemTrayIcon;
|
||||
class QToolButton;
|
||||
class QLabel;
|
||||
@ -90,6 +91,8 @@ public:
|
||||
void showMessage_sys(const QString &title, const QString &msg, const QIcon &icon,
|
||||
QSystemTrayIcon::MessageIcon msgIcon, int msecs);
|
||||
|
||||
void destroyIcon();
|
||||
|
||||
static bool isSystemTrayAvailable_sys();
|
||||
static bool supportsMessages_sys();
|
||||
|
||||
@ -101,6 +104,7 @@ public:
|
||||
QSystemTrayIconSys *sys;
|
||||
QPlatformSystemTrayIcon *qpa_sys;
|
||||
bool visible;
|
||||
QSystemTrayWatcher *trayWatcher;
|
||||
|
||||
private:
|
||||
void install_sys_qpa();
|
||||
|
@ -92,9 +92,6 @@ protected:
|
||||
virtual void resizeEvent(QResizeEvent *) override;
|
||||
virtual void moveEvent(QMoveEvent *) override;
|
||||
|
||||
private slots:
|
||||
void systemTrayWindowChanged(QScreen *screen);
|
||||
|
||||
private:
|
||||
QSystemTrayIcon *q;
|
||||
};
|
||||
@ -116,15 +113,6 @@ QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn)
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
void QSystemTrayIconSys::systemTrayWindowChanged(QScreen *)
|
||||
{
|
||||
if (!locateSystemTray()) {
|
||||
QBalloonTip::hideBalloon();
|
||||
hide(); // still no luck
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
QRect QSystemTrayIconSys::globalGeometry() const
|
||||
{
|
||||
return QRect(mapToGlobal(QPoint(0, 0)), size());
|
||||
@ -199,10 +187,41 @@ void QSystemTrayIconSys::resizeEvent(QResizeEvent *event)
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class QSystemTrayWatcher: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QSystemTrayWatcher(QSystemTrayIcon *trayIcon)
|
||||
: QObject(trayIcon)
|
||||
, mTrayIcon(trayIcon)
|
||||
{
|
||||
// This code uses string-based syntax because we want to connect to a signal
|
||||
// which is defined in XCB plugin - QXcbNativeInterface::systemTrayWindowChanged().
|
||||
connect(qGuiApp->platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)),
|
||||
this, SLOT(systemTrayWindowChanged(QScreen*)));
|
||||
}
|
||||
|
||||
private slots:
|
||||
void systemTrayWindowChanged(QScreen *)
|
||||
{
|
||||
auto icon = static_cast<QSystemTrayIconPrivate *>(QObjectPrivate::get(mTrayIcon));
|
||||
icon->destroyIcon();
|
||||
if (icon->visible && locateSystemTray()) {
|
||||
icon->sys = new QSystemTrayIconSys(mTrayIcon);
|
||||
icon->sys->show();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QSystemTrayIcon *mTrayIcon = nullptr;
|
||||
};
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
QSystemTrayIconPrivate::QSystemTrayIconPrivate()
|
||||
: sys(0),
|
||||
qpa_sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon()),
|
||||
visible(false)
|
||||
visible(false),
|
||||
trayWatcher(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@ -213,16 +232,21 @@ QSystemTrayIconPrivate::~QSystemTrayIconPrivate()
|
||||
|
||||
void QSystemTrayIconPrivate::install_sys()
|
||||
{
|
||||
Q_Q(QSystemTrayIcon);
|
||||
|
||||
if (qpa_sys) {
|
||||
install_sys_qpa();
|
||||
return;
|
||||
}
|
||||
Q_Q(QSystemTrayIcon);
|
||||
if (!sys && locateSystemTray()) {
|
||||
sys = new QSystemTrayIconSys(q);
|
||||
QObject::connect(QGuiApplication::platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)),
|
||||
sys, SLOT(systemTrayWindowChanged(QScreen*)));
|
||||
sys->show();
|
||||
|
||||
if (!sys) {
|
||||
if (!trayWatcher)
|
||||
trayWatcher = new QSystemTrayWatcher(q);
|
||||
|
||||
if (locateSystemTray()) {
|
||||
sys = new QSystemTrayIconSys(q);
|
||||
sys->show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,14 +265,21 @@ void QSystemTrayIconPrivate::remove_sys()
|
||||
remove_sys_qpa();
|
||||
return;
|
||||
}
|
||||
|
||||
destroyIcon();
|
||||
}
|
||||
|
||||
void QSystemTrayIconPrivate::destroyIcon()
|
||||
{
|
||||
if (!sys)
|
||||
return;
|
||||
QBalloonTip::hideBalloon();
|
||||
sys->hide(); // this should do the trick, but...
|
||||
delete sys; // wm may resize system tray only for DestroyEvents
|
||||
sys = 0;
|
||||
sys->hide();
|
||||
delete sys;
|
||||
sys = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void QSystemTrayIconPrivate::updateIcon_sys()
|
||||
{
|
||||
if (qpa_sys) {
|
||||
|
@ -1239,6 +1239,8 @@ void QPlainTextEditPrivate::ensureViewportLayouted()
|
||||
|
||||
This property gets and sets the plain text editor's contents. The previous
|
||||
contents are removed and undo/redo history is reset when this property is set.
|
||||
currentCharFormat() is also reset, unless textCursor() is already at the
|
||||
beginning of the document.
|
||||
|
||||
By default, for an editor with no contents, this property contains an empty string.
|
||||
*/
|
||||
@ -1518,7 +1520,12 @@ void QPlainTextEdit::paste()
|
||||
/*!
|
||||
Deletes all the text in the text edit.
|
||||
|
||||
Note that the undo/redo history is cleared by this function.
|
||||
Notes:
|
||||
\list
|
||||
\li The undo/redo history is also cleared.
|
||||
\li currentCharFormat() is reset, unless textCursor()
|
||||
is already at the beginning of the document.
|
||||
\endlist
|
||||
|
||||
\sa cut(), setPlainText()
|
||||
*/
|
||||
@ -1651,7 +1658,12 @@ void QPlainTextEdit::timerEvent(QTimerEvent *e)
|
||||
|
||||
\a text is interpreted as plain text.
|
||||
|
||||
Note that the undo/redo history is cleared by this function.
|
||||
Notes:
|
||||
\list
|
||||
\li The undo/redo history is also cleared.
|
||||
\li currentCharFormat() is reset, unless textCursor()
|
||||
is already at the beginning of the document.
|
||||
\endlist
|
||||
|
||||
\sa toPlainText()
|
||||
*/
|
||||
|
@ -556,7 +556,8 @@ void QTextEditPrivate::_q_ensureVisible(const QRectF &_rect)
|
||||
|
||||
This property gets and sets the text editor's contents as plain
|
||||
text. Previous contents are removed and undo/redo history is reset
|
||||
when the property is set.
|
||||
when the property is set. currentCharFormat() is also reset, unless
|
||||
textCursor() is already at the beginning of the document.
|
||||
|
||||
If the text edit has another content type, it will not be replaced
|
||||
by plain text if you call toPlainText(). The only exception to this
|
||||
@ -1034,7 +1035,12 @@ void QTextEdit::paste()
|
||||
/*!
|
||||
Deletes all the text in the text edit.
|
||||
|
||||
Note that the undo/redo history is cleared by this function.
|
||||
Notes:
|
||||
\list
|
||||
\li The undo/redo history is also cleared.
|
||||
\li currentCharFormat() is reset, unless textCursor()
|
||||
is already at the beginning of the document.
|
||||
\endlist
|
||||
|
||||
\sa cut(), setPlainText(), setHtml()
|
||||
*/
|
||||
@ -1139,9 +1145,13 @@ void QTextEdit::timerEvent(QTimerEvent *e)
|
||||
Changes the text of the text edit to the string \a text.
|
||||
Any previous text is removed.
|
||||
|
||||
\a text is interpreted as plain text.
|
||||
|
||||
Note that the undo/redo history is cleared by this function.
|
||||
Notes:
|
||||
\list
|
||||
\li \a text is interpreted as plain text.
|
||||
\li The undo/redo history is also cleared.
|
||||
\li currentCharFormat() is reset, unless textCursor()
|
||||
is already at the beginning of the document.
|
||||
\endlist
|
||||
|
||||
\sa toPlainText()
|
||||
*/
|
||||
@ -1175,7 +1185,8 @@ QString QTextEdit::toPlainText() const
|
||||
|
||||
setHtml() changes the text of the text edit. Any previous text is
|
||||
removed and the undo/redo history is cleared. The input text is
|
||||
interpreted as rich text in html format.
|
||||
interpreted as rich text in html format. currentCharFormat() is also
|
||||
reset, unless textCursor() is already at the beginning of the document.
|
||||
|
||||
\note It is the responsibility of the caller to make sure that the
|
||||
text is correctly decoded when a QString containing HTML is created
|
||||
|
@ -1559,6 +1559,16 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
|
||||
<< NtfsTestResource(NtfsTestResource::SymLink, relToRelSymlink, relToRelTarget)
|
||||
<< relToRelSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
|
||||
}
|
||||
{
|
||||
// Symlink to UNC share
|
||||
pwd.mkdir("unc");
|
||||
QString errorMessage;
|
||||
QString uncTarget = QStringLiteral("//") + QtNetworkSettings::winServerName() + "/testshare";
|
||||
QString uncSymlink = QDir::toNativeSeparators(pwd.absolutePath().append("\\unc\\link_to_unc"));
|
||||
QTest::newRow("UNC symlink")
|
||||
<< NtfsTestResource(NtfsTestResource::SymLink, uncSymlink, uncTarget)
|
||||
<< QDir::fromNativeSeparators(uncSymlink) << true << QDir::fromNativeSeparators(uncTarget) << uncTarget;
|
||||
}
|
||||
|
||||
//Junctions
|
||||
QString target = "target";
|
||||
@ -1630,7 +1640,7 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks()
|
||||
// Ensure that junctions, mountpoints are removed. If this fails, do not remove
|
||||
// temporary directory to prevent it from trashing the system.
|
||||
if (fi.isDir()) {
|
||||
if (!QDir().rmdir(fi.fileName())) {
|
||||
if (!QDir().rmdir(fi.filePath())) {
|
||||
qWarning("Unable to remove NTFS junction '%s'', keeping '%s'.",
|
||||
qPrintable(fi.fileName()), qPrintable(QDir::toNativeSeparators(m_dir.path())));
|
||||
m_dir.setAutoRemove(false);
|
||||
|
@ -1,4 +1,5 @@
|
||||
CONFIG += testcase
|
||||
qtConfig(c++14): CONFIG += c++14
|
||||
TARGET = tst_qmetaobject
|
||||
QT = core-private testlib
|
||||
SOURCES = tst_qmetaobject.cpp
|
||||
|
@ -816,6 +816,15 @@ void tst_QMetaObject::invokePointer()
|
||||
QCOMPARE(obj.slotResult, QString("sl1:bubu"));
|
||||
}
|
||||
QCOMPARE(countedStructObjectsCount, 0);
|
||||
#ifdef __cpp_init_captures
|
||||
{
|
||||
CountedStruct str;
|
||||
std::unique_ptr<int> ptr( new int );
|
||||
QVERIFY(QMetaObject::invokeMethod(&obj, [str, &t1, &obj, p = std::move(ptr)]() { obj.sl1(t1); }));
|
||||
QCOMPARE(obj.slotResult, QString("sl1:1"));
|
||||
}
|
||||
QCOMPARE(countedStructObjectsCount, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QMetaObject::invokeQueuedMetaMember()
|
||||
@ -1121,6 +1130,15 @@ void tst_QMetaObject::invokeBlockingQueuedPointer()
|
||||
QCOMPARE(exp, QString("yessir"));
|
||||
QCOMPARE(obj.slotResult, QString("sl1:bubu"));
|
||||
}
|
||||
#ifdef __cpp_init_captures
|
||||
{
|
||||
std::unique_ptr<int> ptr(new int);
|
||||
QVERIFY(QMetaObject::invokeMethod(&obj,
|
||||
[&obj, p = std::move(ptr)]() { return obj.sl1("hehe"); },
|
||||
Qt::BlockingQueuedConnection));
|
||||
QCOMPARE(obj.slotResult, QString("sl1:hehe"));
|
||||
}
|
||||
#endif
|
||||
QVERIFY(QMetaObject::invokeMethod(&obj, [&](){obj.moveToThread(QThread::currentThread());}, Qt::BlockingQueuedConnection));
|
||||
t.quit();
|
||||
QVERIFY(t.wait());
|
||||
|
@ -78,9 +78,11 @@ private slots:
|
||||
void toString_isoDate_data();
|
||||
void toString_isoDate();
|
||||
void toString_isoDate_extra();
|
||||
#if QT_CONFIG(datestring)
|
||||
void toString_textDate_data();
|
||||
void toString_textDate();
|
||||
void toString_textDate_extra();
|
||||
#endif
|
||||
void toString_rfcDate_data();
|
||||
void toString_rfcDate();
|
||||
void toString_enumformat();
|
||||
@ -800,11 +802,11 @@ void tst_QDateTime::toString_isoDate_data()
|
||||
QTest::newRow("positive OffsetFromUTC")
|
||||
<< dt << Qt::ISODate
|
||||
<< QString("1978-11-09T13:28:34+05:30");
|
||||
dt.setUtcOffset(-7200);
|
||||
dt.setOffsetFromUtc(-7200);
|
||||
QTest::newRow("negative OffsetFromUTC")
|
||||
<< dt << Qt::ISODate
|
||||
<< QString("1978-11-09T13:28:34-02:00");
|
||||
dt.setUtcOffset(-900);
|
||||
dt.setOffsetFromUtc(-900);
|
||||
QTest::newRow("negative non-integral OffsetFromUTC")
|
||||
<< dt << Qt::ISODate
|
||||
<< QString("1978-11-09T13:28:34-00:15");
|
||||
@ -840,7 +842,7 @@ void tst_QDateTime::toString_isoDate()
|
||||
QCOMPARE(resultDatetime.date(), datetime.date());
|
||||
QCOMPARE(resultDatetime.time(), datetime.time());
|
||||
QCOMPARE(resultDatetime.timeSpec(), datetime.timeSpec());
|
||||
QCOMPARE(resultDatetime.utcOffset(), datetime.utcOffset());
|
||||
QCOMPARE(resultDatetime.offsetFromUtc(), datetime.offsetFromUtc());
|
||||
} else {
|
||||
QCOMPARE(resultDatetime, QDateTime());
|
||||
}
|
||||
@ -870,12 +872,14 @@ void tst_QDateTime::toString_isoDate_extra()
|
||||
#endif // timezone
|
||||
}
|
||||
|
||||
#if QT_CONFIG(datestring)
|
||||
void tst_QDateTime::toString_textDate_data()
|
||||
{
|
||||
QTest::addColumn<QDateTime>("datetime");
|
||||
QTest::addColumn<QString>("expected");
|
||||
|
||||
QString wednesdayJanuary = QDate::shortDayName(3) + ' ' + QDate::shortMonthName(1);
|
||||
QString wednesdayJanuary = QLocale::system().dayName(3, QLocale::ShortFormat)
|
||||
+ ' ' + QLocale::system().monthName(1, QLocale::ShortFormat);
|
||||
|
||||
QTest::newRow("localtime") << QDateTime(QDate(2013, 1, 2), QTime(1, 2, 3), Qt::LocalTime)
|
||||
<< wednesdayJanuary + QString(" 2 01:02:03 2013");
|
||||
@ -904,7 +908,7 @@ void tst_QDateTime::toString_textDate()
|
||||
QCOMPARE(resultDatetime.date(), datetime.date());
|
||||
QCOMPARE(resultDatetime.time(), datetime.time());
|
||||
QCOMPARE(resultDatetime.timeSpec(), datetime.timeSpec());
|
||||
QCOMPARE(resultDatetime.utcOffset(), datetime.utcOffset());
|
||||
QCOMPARE(resultDatetime.offsetFromUtc(), datetime.offsetFromUtc());
|
||||
}
|
||||
|
||||
void tst_QDateTime::toString_textDate_extra()
|
||||
@ -953,6 +957,7 @@ void tst_QDateTime::toString_textDate_extra()
|
||||
dt = QDateTime::fromMSecsSinceEpoch(0, Qt::UTC);
|
||||
QVERIFY(dt.toString().endsWith(GMT));
|
||||
}
|
||||
#endif // datestring
|
||||
|
||||
void tst_QDateTime::toString_rfcDate_data()
|
||||
{
|
||||
@ -968,11 +973,11 @@ void tst_QDateTime::toString_rfcDate_data()
|
||||
<< QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34), Qt::UTC)
|
||||
<< QString("09 Nov 1978 13:28:34 +0000");
|
||||
QDateTime dt(QDate(1978, 11, 9), QTime(13, 28, 34));
|
||||
dt.setUtcOffset(19800);
|
||||
dt.setOffsetFromUtc(19800);
|
||||
QTest::newRow("positive OffsetFromUTC")
|
||||
<< dt
|
||||
<< QString("09 Nov 1978 13:28:34 +0530");
|
||||
dt.setUtcOffset(-7200);
|
||||
dt.setOffsetFromUtc(-7200);
|
||||
QTest::newRow("negative OffsetFromUTC")
|
||||
<< dt
|
||||
<< QString("09 Nov 1978 13:28:34 -0200");
|
||||
|
@ -35,11 +35,13 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
QShaderFormat createFormat(QShaderFormat::Api api, int majorVersion, int minorVersion)
|
||||
QShaderFormat createFormat(QShaderFormat::Api api, int majorVersion, int minorVersion,
|
||||
QShaderFormat::ShaderType shaderType= QShaderFormat::Fragment)
|
||||
{
|
||||
auto format = QShaderFormat();
|
||||
format.setApi(api);
|
||||
format.setVersion(QVersionNumber(majorVersion, minorVersion));
|
||||
format.setShaderType(shaderType);
|
||||
return format;
|
||||
}
|
||||
|
||||
@ -74,7 +76,7 @@ namespace
|
||||
return edge;
|
||||
}
|
||||
|
||||
QShaderGraph createGraph()
|
||||
QShaderGraph createFragmentShaderGraph()
|
||||
{
|
||||
const auto openGLES2 = createFormat(QShaderFormat::OpenGLES, 2, 0);
|
||||
const auto openGL3 = createFormat(QShaderFormat::OpenGLCoreProfile, 3, 0);
|
||||
@ -194,6 +196,7 @@ private slots:
|
||||
void shouldProcessLanguageQualifierAndTypeEnums_data();
|
||||
void shouldProcessLanguageQualifierAndTypeEnums();
|
||||
void shouldGenerateDifferentCodeDependingOnActiveLayers();
|
||||
void shouldUseGlobalVariableRatherThanTemporaries();
|
||||
};
|
||||
|
||||
void tst_QShaderGenerator::shouldHaveDefaultState()
|
||||
@ -213,7 +216,7 @@ void tst_QShaderGenerator::shouldGenerateShaderCode_data()
|
||||
QTest::addColumn<QShaderFormat>("format");
|
||||
QTest::addColumn<QByteArray>("expectedCode");
|
||||
|
||||
const auto graph = createGraph();
|
||||
const auto graph = createFragmentShaderGraph();
|
||||
|
||||
const auto openGLES2 = createFormat(QShaderFormat::OpenGLES, 2, 0);
|
||||
const auto openGL3 = createFormat(QShaderFormat::OpenGLCoreProfile, 3, 0);
|
||||
@ -234,14 +237,9 @@ void tst_QShaderGenerator::shouldGenerateShaderCode_data()
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< " highp vec2 v2 = texCoord;"
|
||||
<< " sampler2D v1 = texture;"
|
||||
<< " highp float v3 = lightIntensity;"
|
||||
<< " highp vec4 v5 = texture2D(v1, v2);"
|
||||
<< " highp vec3 v0 = worldPosition;"
|
||||
<< " highp float v4 = exposure;"
|
||||
<< " highp vec4 v6 = lightModel(v5, v0, v3);"
|
||||
<< " highp vec4 v7 = v6 * pow(2.0, v4);"
|
||||
<< " highp vec4 v5 = texture2D(texture, texCoord);"
|
||||
<< " highp vec4 v6 = lightModel(v5, worldPosition, lightIntensity);"
|
||||
<< " highp vec4 v7 = v6 * pow(2.0, exposure);"
|
||||
<< " gl_fragColor = v7;"
|
||||
<< "}"
|
||||
<< "";
|
||||
@ -256,14 +254,9 @@ void tst_QShaderGenerator::shouldGenerateShaderCode_data()
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< " vec2 v2 = texCoord;"
|
||||
<< " sampler2D v1 = texture;"
|
||||
<< " float v3 = lightIntensity;"
|
||||
<< " vec4 v5 = texture2D(v1, v2);"
|
||||
<< " vec3 v0 = worldPosition;"
|
||||
<< " float v4 = exposure;"
|
||||
<< " vec4 v6 = lightModel(v5, v0, v3);"
|
||||
<< " vec4 v7 = v6 * pow(2.0, v4);"
|
||||
<< " vec4 v5 = texture2D(texture, texCoord);"
|
||||
<< " vec4 v6 = lightModel(v5, worldPosition, lightIntensity);"
|
||||
<< " vec4 v7 = v6 * pow(2.0, exposure);"
|
||||
<< " fragColor = v7;"
|
||||
<< "}"
|
||||
<< "";
|
||||
@ -580,120 +573,190 @@ void tst_QShaderGenerator::shouldProcessLanguageQualifierAndTypeEnums_data()
|
||||
QTest::addColumn<QShaderFormat>("format");
|
||||
QTest::addColumn<QByteArray>("expectedCode");
|
||||
|
||||
const auto es2 = createFormat(QShaderFormat::OpenGLES, 2, 0);
|
||||
const auto es3 = createFormat(QShaderFormat::OpenGLES, 3, 0);
|
||||
const auto gl2 = createFormat(QShaderFormat::OpenGLNoProfile, 2, 0);
|
||||
const auto gl3 = createFormat(QShaderFormat::OpenGLCoreProfile, 3, 0);
|
||||
const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0);
|
||||
{
|
||||
const auto es2 = createFormat(QShaderFormat::OpenGLES, 2, 0);
|
||||
const auto es3 = createFormat(QShaderFormat::OpenGLES, 3, 0);
|
||||
const auto gl2 = createFormat(QShaderFormat::OpenGLNoProfile, 2, 0);
|
||||
const auto gl3 = createFormat(QShaderFormat::OpenGLCoreProfile, 3, 0);
|
||||
const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0);
|
||||
|
||||
const auto qualifierEnum = QMetaEnum::fromType<QShaderLanguage::StorageQualifier>();
|
||||
const auto typeEnum = QMetaEnum::fromType<QShaderLanguage::VariableType>();
|
||||
const auto qualifierEnum = QMetaEnum::fromType<QShaderLanguage::StorageQualifier>();
|
||||
const auto typeEnum = QMetaEnum::fromType<QShaderLanguage::VariableType>();
|
||||
|
||||
for (int qualifierIndex = 0; qualifierIndex < qualifierEnum.keyCount(); qualifierIndex++) {
|
||||
const auto qualifierName = qualifierEnum.key(qualifierIndex);
|
||||
const auto qualifierValue = static_cast<QShaderLanguage::StorageQualifier>(qualifierEnum.value(qualifierIndex));
|
||||
for (int qualifierIndex = 0; qualifierIndex < qualifierEnum.keyCount(); qualifierIndex++) {
|
||||
const auto qualifierName = qualifierEnum.key(qualifierIndex);
|
||||
const auto qualifierValue = static_cast<QShaderLanguage::StorageQualifier>(qualifierEnum.value(qualifierIndex));
|
||||
|
||||
for (int typeIndex = 0; typeIndex < typeEnum.keyCount(); typeIndex++) {
|
||||
const auto typeName = typeEnum.key(typeIndex);
|
||||
const auto typeValue = static_cast<QShaderLanguage::VariableType>(typeEnum.value(typeIndex));
|
||||
for (int typeIndex = 0; typeIndex < typeEnum.keyCount(); typeIndex++) {
|
||||
const auto typeName = typeEnum.key(typeIndex);
|
||||
const auto typeValue = static_cast<QShaderLanguage::VariableType>(typeEnum.value(typeIndex));
|
||||
|
||||
auto graph = QShaderGraph();
|
||||
|
||||
auto worldPosition = createNode({
|
||||
createPort(QShaderNodePort::Output, "value")
|
||||
});
|
||||
worldPosition.setParameter("name", "worldPosition");
|
||||
worldPosition.setParameter("qualifier", QVariant::fromValue<QShaderLanguage::StorageQualifier>(qualifierValue));
|
||||
worldPosition.setParameter("type", QVariant::fromValue<QShaderLanguage::VariableType>(typeValue));
|
||||
worldPosition.addRule(es2, QShaderNode::Rule("highp $type $value = $name;",
|
||||
QByteArrayList() << "$qualifier highp $type $name;"));
|
||||
worldPosition.addRule(gl2, QShaderNode::Rule("$type $value = $name;",
|
||||
QByteArrayList() << "$qualifier $type $name;"));
|
||||
worldPosition.addRule(gl3, QShaderNode::Rule("$type $value = $name;",
|
||||
QByteArrayList() << "$qualifier $type $name;"));
|
||||
|
||||
auto fragColor = createNode({
|
||||
createPort(QShaderNodePort::Input, "fragColor")
|
||||
});
|
||||
fragColor.addRule(es2, QShaderNode::Rule("gl_fragColor = $fragColor;"));
|
||||
fragColor.addRule(gl2, QShaderNode::Rule("gl_fragColor = $fragColor;"));
|
||||
fragColor.addRule(gl3, QShaderNode::Rule("fragColor = $fragColor;",
|
||||
QByteArrayList() << "out vec4 fragColor;"));
|
||||
|
||||
graph.addNode(worldPosition);
|
||||
graph.addNode(fragColor);
|
||||
|
||||
graph.addEdge(createEdge(worldPosition.uuid(), "value", fragColor.uuid(), "fragColor"));
|
||||
|
||||
const auto gl2Code = (QByteArrayList() << "#version 110"
|
||||
<< ""
|
||||
<< QStringLiteral("%1 %2 worldPosition;").arg(toGlsl(qualifierValue, gl2))
|
||||
.arg(toGlsl(typeValue))
|
||||
.toUtf8()
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< " gl_fragColor = worldPosition;"
|
||||
<< "}"
|
||||
<< "").join("\n");
|
||||
const auto gl3Code = (QByteArrayList() << "#version 130"
|
||||
<< ""
|
||||
<< QStringLiteral("%1 %2 worldPosition;").arg(toGlsl(qualifierValue, gl3))
|
||||
.arg(toGlsl(typeValue))
|
||||
.toUtf8()
|
||||
<< "out vec4 fragColor;"
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< " fragColor = worldPosition;"
|
||||
<< "}"
|
||||
<< "").join("\n");
|
||||
const auto gl4Code = (QByteArrayList() << "#version 400 core"
|
||||
<< ""
|
||||
<< QStringLiteral("%1 %2 worldPosition;").arg(toGlsl(qualifierValue, gl4))
|
||||
.arg(toGlsl(typeValue))
|
||||
.toUtf8()
|
||||
<< "out vec4 fragColor;"
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< " fragColor = worldPosition;"
|
||||
<< "}"
|
||||
<< "").join("\n");
|
||||
const auto es2Code = (QByteArrayList() << "#version 100"
|
||||
<< ""
|
||||
<< QStringLiteral("%1 highp %2 worldPosition;").arg(toGlsl(qualifierValue, es2))
|
||||
.arg(toGlsl(typeValue))
|
||||
.toUtf8()
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< " gl_fragColor = worldPosition;"
|
||||
<< "}"
|
||||
<< "").join("\n");
|
||||
const auto es3Code = (QByteArrayList() << "#version 300 es"
|
||||
<< ""
|
||||
<< QStringLiteral("%1 highp %2 worldPosition;").arg(toGlsl(qualifierValue, es3))
|
||||
.arg(toGlsl(typeValue))
|
||||
.toUtf8()
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< " gl_fragColor = worldPosition;"
|
||||
<< "}"
|
||||
<< "").join("\n");
|
||||
|
||||
QTest::addRow("%s %s ES2", qualifierName, typeName) << graph << es2 << es2Code;
|
||||
QTest::addRow("%s %s ES3", qualifierName, typeName) << graph << es3 << es3Code;
|
||||
QTest::addRow("%s %s GL2", qualifierName, typeName) << graph << gl2 << gl2Code;
|
||||
QTest::addRow("%s %s GL3", qualifierName, typeName) << graph << gl3 << gl3Code;
|
||||
QTest::addRow("%s %s GL4", qualifierName, typeName) << graph << gl4 << gl4Code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const auto es2 = createFormat(QShaderFormat::OpenGLES, 2, 0, QShaderFormat::Vertex);
|
||||
const auto es3 = createFormat(QShaderFormat::OpenGLES, 3, 0, QShaderFormat::Vertex);
|
||||
const auto gl2 = createFormat(QShaderFormat::OpenGLNoProfile, 2, 0, QShaderFormat::Vertex);
|
||||
const auto gl3 = createFormat(QShaderFormat::OpenGLCoreProfile, 3, 0, QShaderFormat::Vertex);
|
||||
const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0, QShaderFormat::Vertex);
|
||||
|
||||
auto graph = QShaderGraph();
|
||||
|
||||
auto worldPosition = createNode({
|
||||
auto vertexPosition = createNode({
|
||||
createPort(QShaderNodePort::Output, "value")
|
||||
});
|
||||
worldPosition.setParameter("name", "worldPosition");
|
||||
worldPosition.setParameter("qualifier", QVariant::fromValue<QShaderLanguage::StorageQualifier>(qualifierValue));
|
||||
worldPosition.setParameter("type", QVariant::fromValue<QShaderLanguage::VariableType>(typeValue));
|
||||
worldPosition.addRule(es2, QShaderNode::Rule("highp $type $value = $name;",
|
||||
vertexPosition.setParameter("name", "vertexPosition");
|
||||
vertexPosition.setParameter("qualifier", QVariant::fromValue<QShaderLanguage::StorageQualifier>(QShaderLanguage::Input));
|
||||
vertexPosition.setParameter("type", QVariant::fromValue<QShaderLanguage::VariableType>(QShaderLanguage::Vec4));
|
||||
|
||||
vertexPosition.addRule(es2, QShaderNode::Rule("",
|
||||
QByteArrayList() << "$qualifier highp $type $name;"));
|
||||
worldPosition.addRule(gl2, QShaderNode::Rule("$type $value = $name;",
|
||||
vertexPosition.addRule(gl2, QShaderNode::Rule("",
|
||||
QByteArrayList() << "$qualifier $type $name;"));
|
||||
worldPosition.addRule(gl3, QShaderNode::Rule("$type $value = $name;",
|
||||
vertexPosition.addRule(gl3, QShaderNode::Rule("",
|
||||
QByteArrayList() << "$qualifier $type $name;"));
|
||||
|
||||
auto fragColor = createNode({
|
||||
createPort(QShaderNodePort::Input, "fragColor")
|
||||
});
|
||||
fragColor.addRule(es2, QShaderNode::Rule("gl_fragColor = $fragColor;"));
|
||||
fragColor.addRule(gl2, QShaderNode::Rule("gl_fragColor = $fragColor;"));
|
||||
fragColor.addRule(gl3, QShaderNode::Rule("fragColor = $fragColor;",
|
||||
QByteArrayList() << "out vec4 fragColor;"));
|
||||
|
||||
graph.addNode(worldPosition);
|
||||
graph.addNode(fragColor);
|
||||
|
||||
graph.addEdge(createEdge(worldPosition.uuid(), "value", fragColor.uuid(), "fragColor"));
|
||||
graph.addNode(vertexPosition);
|
||||
|
||||
const auto gl2Code = (QByteArrayList() << "#version 110"
|
||||
<< ""
|
||||
<< QStringLiteral("%1 %2 worldPosition;").arg(toGlsl(qualifierValue, gl2))
|
||||
.arg(toGlsl(typeValue))
|
||||
.toUtf8()
|
||||
<< "attribute vec4 vertexPosition;"
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< QStringLiteral(" %1 v0 = worldPosition;").arg(toGlsl(typeValue)).toUtf8()
|
||||
<< " gl_fragColor = v0;"
|
||||
<< "}"
|
||||
<< "").join("\n");
|
||||
const auto gl3Code = (QByteArrayList() << "#version 130"
|
||||
<< ""
|
||||
<< QStringLiteral("%1 %2 worldPosition;").arg(toGlsl(qualifierValue, gl3))
|
||||
.arg(toGlsl(typeValue))
|
||||
.toUtf8()
|
||||
<< "out vec4 fragColor;"
|
||||
<< "in vec4 vertexPosition;"
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< QStringLiteral(" %1 v0 = worldPosition;").arg(toGlsl(typeValue)).toUtf8()
|
||||
<< " fragColor = v0;"
|
||||
<< "}"
|
||||
<< "").join("\n");
|
||||
const auto gl4Code = (QByteArrayList() << "#version 400 core"
|
||||
<< ""
|
||||
<< QStringLiteral("%1 %2 worldPosition;").arg(toGlsl(qualifierValue, gl4))
|
||||
.arg(toGlsl(typeValue))
|
||||
.toUtf8()
|
||||
<< "out vec4 fragColor;"
|
||||
<< "in vec4 vertexPosition;"
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< QStringLiteral(" %1 v0 = worldPosition;").arg(toGlsl(typeValue)).toUtf8()
|
||||
<< " fragColor = v0;"
|
||||
<< "}"
|
||||
<< "").join("\n");
|
||||
const auto es2Code = (QByteArrayList() << "#version 100"
|
||||
<< ""
|
||||
<< QStringLiteral("%1 highp %2 worldPosition;").arg(toGlsl(qualifierValue, es2))
|
||||
.arg(toGlsl(typeValue))
|
||||
.toUtf8()
|
||||
<< "attribute highp vec4 vertexPosition;"
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< QStringLiteral(" highp %1 v0 = worldPosition;").arg(toGlsl(typeValue)).toUtf8()
|
||||
<< " gl_fragColor = v0;"
|
||||
<< "}"
|
||||
<< "").join("\n");
|
||||
const auto es3Code = (QByteArrayList() << "#version 300 es"
|
||||
<< ""
|
||||
<< QStringLiteral("%1 highp %2 worldPosition;").arg(toGlsl(qualifierValue, es3))
|
||||
.arg(toGlsl(typeValue))
|
||||
.toUtf8()
|
||||
<< "in highp vec4 vertexPosition;"
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< QStringLiteral(" highp %1 v0 = worldPosition;").arg(toGlsl(typeValue)).toUtf8()
|
||||
<< " gl_fragColor = v0;"
|
||||
<< "}"
|
||||
<< "").join("\n");
|
||||
|
||||
QTest::addRow("%s %s ES2", qualifierName, typeName) << graph << es2 << es2Code;
|
||||
QTest::addRow("%s %s ES3", qualifierName, typeName) << graph << es3 << es3Code;
|
||||
QTest::addRow("%s %s GL2", qualifierName, typeName) << graph << gl2 << gl2Code;
|
||||
QTest::addRow("%s %s GL3", qualifierName, typeName) << graph << gl3 << gl3Code;
|
||||
QTest::addRow("%s %s GL4", qualifierName, typeName) << graph << gl4 << gl4Code;
|
||||
}
|
||||
QTest::addRow("Attribute header substitution ES2") << graph << es2 << es2Code;
|
||||
QTest::addRow("Attribute header substitution ES3") << graph << es3 << es3Code;
|
||||
QTest::addRow("Attribute header substitution GL2") << graph << gl2 << gl2Code;
|
||||
QTest::addRow("Attribute header substitution GL3") << graph << gl3 << gl3Code;
|
||||
QTest::addRow("Attribute header substitution GL4") << graph << gl4 << gl4Code;
|
||||
}
|
||||
}
|
||||
|
||||
@ -806,9 +869,7 @@ void tst_QShaderGenerator::shouldGenerateDifferentCodeDependingOnActiveLayers()
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< " vec3 v1 = normalUniform;"
|
||||
<< " vec4 v0 = diffuseUniform;"
|
||||
<< " vec4 v2 = lightModel(v0, v1);"
|
||||
<< " vec4 v2 = lightModel(diffuseUniform, normalUniform);"
|
||||
<< " fragColor = v2;"
|
||||
<< "}"
|
||||
<< "";
|
||||
@ -831,10 +892,8 @@ void tst_QShaderGenerator::shouldGenerateDifferentCodeDependingOnActiveLayers()
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< " vec2 v0 = texCoord;"
|
||||
<< " vec3 v2 = texture2D(normalTexture, v0).rgb;"
|
||||
<< " vec4 v1 = diffuseUniform;"
|
||||
<< " vec4 v3 = lightModel(v1, v2);"
|
||||
<< " vec3 v2 = texture2D(normalTexture, texCoord).rgb;"
|
||||
<< " vec4 v3 = lightModel(diffuseUniform, v2);"
|
||||
<< " fragColor = v3;"
|
||||
<< "}"
|
||||
<< "";
|
||||
@ -857,10 +916,8 @@ void tst_QShaderGenerator::shouldGenerateDifferentCodeDependingOnActiveLayers()
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< " vec2 v0 = texCoord;"
|
||||
<< " vec3 v2 = normalUniform;"
|
||||
<< " vec4 v1 = texture2D(diffuseTexture, v0);"
|
||||
<< " vec4 v3 = lightModel(v1, v2);"
|
||||
<< " vec4 v1 = texture2D(diffuseTexture, texCoord);"
|
||||
<< " vec4 v3 = lightModel(v1, normalUniform);"
|
||||
<< " fragColor = v3;"
|
||||
<< "}"
|
||||
<< "";
|
||||
@ -883,9 +940,8 @@ void tst_QShaderGenerator::shouldGenerateDifferentCodeDependingOnActiveLayers()
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< " vec2 v0 = texCoord;"
|
||||
<< " vec3 v2 = texture2D(normalTexture, v0).rgb;"
|
||||
<< " vec4 v1 = texture2D(diffuseTexture, v0);"
|
||||
<< " vec3 v2 = texture2D(normalTexture, texCoord).rgb;"
|
||||
<< " vec4 v1 = texture2D(diffuseTexture, texCoord);"
|
||||
<< " vec4 v3 = lightModel(v1, v2);"
|
||||
<< " fragColor = v3;"
|
||||
<< "}"
|
||||
@ -894,6 +950,133 @@ void tst_QShaderGenerator::shouldGenerateDifferentCodeDependingOnActiveLayers()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QShaderGenerator::shouldUseGlobalVariableRatherThanTemporaries()
|
||||
{
|
||||
// GIVEN
|
||||
const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0);
|
||||
|
||||
{
|
||||
// WHEN
|
||||
auto vertexPosition = createNode({
|
||||
createPort(QShaderNodePort::Output, "vertexPosition")
|
||||
});
|
||||
vertexPosition.addRule(gl4, QShaderNode::Rule("vec4 $vertexPosition = vertexPosition;",
|
||||
QByteArrayList() << "in vec4 vertexPosition;"));
|
||||
|
||||
auto fakeMultiPlyNoSpace = createNode({
|
||||
createPort(QShaderNodePort::Input, "varName"),
|
||||
createPort(QShaderNodePort::Output, "out")
|
||||
});
|
||||
fakeMultiPlyNoSpace.addRule(gl4, QShaderNode::Rule("vec4 $out = $varName*v11;"));
|
||||
|
||||
auto fakeMultiPlySpace = createNode({
|
||||
createPort(QShaderNodePort::Input, "varName"),
|
||||
createPort(QShaderNodePort::Output, "out")
|
||||
});
|
||||
fakeMultiPlySpace.addRule(gl4, QShaderNode::Rule("vec4 $out = $varName * v11;"));
|
||||
|
||||
auto fakeJoinNoSpace = createNode({
|
||||
createPort(QShaderNodePort::Input, "varName"),
|
||||
createPort(QShaderNodePort::Output, "out")
|
||||
});
|
||||
fakeJoinNoSpace.addRule(gl4, QShaderNode::Rule("vec4 $out = vec4($varName.xyz,$varName.w);"));
|
||||
|
||||
auto fakeJoinSpace = createNode({
|
||||
createPort(QShaderNodePort::Input, "varName"),
|
||||
createPort(QShaderNodePort::Output, "out")
|
||||
});
|
||||
fakeJoinSpace.addRule(gl4, QShaderNode::Rule("vec4 $out = vec4($varName.xyz, $varName.w);"));
|
||||
|
||||
auto fakeAdd = createNode({
|
||||
createPort(QShaderNodePort::Input, "varName"),
|
||||
createPort(QShaderNodePort::Output, "out")
|
||||
});
|
||||
fakeAdd.addRule(gl4, QShaderNode::Rule("vec4 $out = $varName.xyzw + $varName;"));
|
||||
|
||||
auto fakeSub = createNode({
|
||||
createPort(QShaderNodePort::Input, "varName"),
|
||||
createPort(QShaderNodePort::Output, "out")
|
||||
});
|
||||
fakeSub.addRule(gl4, QShaderNode::Rule("vec4 $out = $varName.xyzw - $varName;"));
|
||||
|
||||
auto fakeDiv = createNode({
|
||||
createPort(QShaderNodePort::Input, "varName"),
|
||||
createPort(QShaderNodePort::Output, "out")
|
||||
});
|
||||
fakeDiv.addRule(gl4, QShaderNode::Rule("vec4 $out = $varName / v0;"));
|
||||
|
||||
auto fragColor = createNode({
|
||||
createPort(QShaderNodePort::Input, "input1"),
|
||||
createPort(QShaderNodePort::Input, "input2"),
|
||||
createPort(QShaderNodePort::Input, "input3"),
|
||||
createPort(QShaderNodePort::Input, "input4"),
|
||||
createPort(QShaderNodePort::Input, "input5"),
|
||||
createPort(QShaderNodePort::Input, "input6"),
|
||||
createPort(QShaderNodePort::Input, "input7")
|
||||
});
|
||||
fragColor.addRule(gl4, QShaderNode::Rule("fragColor = $input1 + $input2 + $input3 + $input4 + $input5 + $input6 + $input7;",
|
||||
QByteArrayList() << "out vec4 fragColor;"));
|
||||
|
||||
const auto graph = [=] {
|
||||
auto res = QShaderGraph();
|
||||
|
||||
res.addNode(vertexPosition);
|
||||
res.addNode(fakeMultiPlyNoSpace);
|
||||
res.addNode(fakeMultiPlySpace);
|
||||
res.addNode(fakeJoinNoSpace);
|
||||
res.addNode(fakeJoinSpace);
|
||||
res.addNode(fakeAdd);
|
||||
res.addNode(fakeSub);
|
||||
res.addNode(fakeDiv);
|
||||
res.addNode(fragColor);
|
||||
|
||||
res.addEdge(createEdge(vertexPosition.uuid(), "vertexPosition", fakeMultiPlyNoSpace.uuid(), "varName"));
|
||||
res.addEdge(createEdge(vertexPosition.uuid(), "vertexPosition", fakeMultiPlySpace.uuid(), "varName"));
|
||||
res.addEdge(createEdge(vertexPosition.uuid(), "vertexPosition", fakeJoinNoSpace.uuid(), "varName"));
|
||||
res.addEdge(createEdge(vertexPosition.uuid(), "vertexPosition", fakeJoinSpace.uuid(), "varName"));
|
||||
res.addEdge(createEdge(vertexPosition.uuid(), "vertexPosition", fakeAdd.uuid(), "varName"));
|
||||
res.addEdge(createEdge(vertexPosition.uuid(), "vertexPosition", fakeSub.uuid(), "varName"));
|
||||
res.addEdge(createEdge(vertexPosition.uuid(), "vertexPosition", fakeDiv.uuid(), "varName"));
|
||||
res.addEdge(createEdge(fakeMultiPlyNoSpace.uuid(), "out", fragColor.uuid(), "input1"));
|
||||
res.addEdge(createEdge(fakeMultiPlySpace.uuid(), "out", fragColor.uuid(), "input2"));
|
||||
res.addEdge(createEdge(fakeJoinNoSpace.uuid(), "out", fragColor.uuid(), "input3"));
|
||||
res.addEdge(createEdge(fakeJoinSpace.uuid(), "out", fragColor.uuid(), "input4"));
|
||||
res.addEdge(createEdge(fakeAdd.uuid(), "out", fragColor.uuid(), "input5"));
|
||||
res.addEdge(createEdge(fakeSub.uuid(), "out", fragColor.uuid(), "input6"));
|
||||
res.addEdge(createEdge(fakeDiv.uuid(), "out", fragColor.uuid(), "input7"));
|
||||
|
||||
return res;
|
||||
}();
|
||||
|
||||
auto generator = QShaderGenerator();
|
||||
generator.graph = graph;
|
||||
generator.format = gl4;
|
||||
|
||||
const auto code = generator.createShaderCode({"diffuseUniform", "normalUniform"});
|
||||
|
||||
// THEN
|
||||
const auto expected = QByteArrayList()
|
||||
<< "#version 400 core"
|
||||
<< ""
|
||||
<< "in vec4 vertexPosition;"
|
||||
<< "out vec4 fragColor;"
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< " vec4 v7 = vertexPosition / vertexPosition;"
|
||||
<< " vec4 v6 = vertexPosition.xyzw - vertexPosition;"
|
||||
<< " vec4 v5 = vertexPosition.xyzw + vertexPosition;"
|
||||
<< " vec4 v4 = vec4(vertexPosition.xyz, vertexPosition.w);"
|
||||
<< " vec4 v3 = vec4(vertexPosition.xyz,vertexPosition.w);"
|
||||
<< " vec4 v2 = vertexPosition * v11;"
|
||||
<< " vec4 v1 = vertexPosition*v11;"
|
||||
<< " fragColor = v1 + v2 + v3 + v4 + v5 + v6 + v7;"
|
||||
<< "}"
|
||||
<< "";
|
||||
QCOMPARE(code, expected.join("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QShaderGenerator)
|
||||
|
||||
#include "tst_qshadergenerator.moc"
|
||||
|
@ -248,6 +248,7 @@ private slots:
|
||||
void sizeHintCrash();
|
||||
void testResetCachedSizeHint();
|
||||
void statusTips();
|
||||
void testRemovingColumnsViaLayoutChanged();
|
||||
|
||||
protected:
|
||||
void setupTestData(bool use_reset_model = false);
|
||||
@ -353,6 +354,7 @@ public:
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
emit layoutAboutToBeChanged();
|
||||
cols = 3;
|
||||
rows = 3;
|
||||
emit layoutChanged();
|
||||
@ -3489,5 +3491,20 @@ void tst_QHeaderView::statusTips()
|
||||
QCOMPARE(headerView.statusTipText, QLatin1String("[0,1,0] -- Header"));
|
||||
}
|
||||
|
||||
void tst_QHeaderView::testRemovingColumnsViaLayoutChanged()
|
||||
{
|
||||
const int persistentSectionSize = 101;
|
||||
|
||||
QtTestModel model;
|
||||
model.rows = model.cols = 5;
|
||||
view->setModel(&model);
|
||||
for (int i = 0; i < model.cols; ++i)
|
||||
view->resizeSection(i, persistentSectionSize + i);
|
||||
model.cleanup(); // down to 3 via layoutChanged (not columnsRemoved)
|
||||
for (int j = 0; j < model.cols; ++j)
|
||||
QCOMPARE(view->sectionSize(j), persistentSectionSize + j);
|
||||
// The main point of this test is that the section-size restoring code didn't go out of bounds.
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QHeaderView)
|
||||
#include "tst_qheaderview.moc"
|
||||
|
@ -267,6 +267,7 @@ tst_QListWidget::tst_QListWidget(): testWidget(0), rcParent(8), rcFirst(8,0), rc
|
||||
|
||||
void tst_QListWidget::initTestCase()
|
||||
{
|
||||
qRegisterMetaType<QListWidgetItem*>("QListWidgetItem*");
|
||||
testWidget = new QListWidget();
|
||||
testWidget->show();
|
||||
|
||||
@ -663,6 +664,9 @@ void tst_QListWidget::insertItems()
|
||||
QFETCH(int, rowCount);
|
||||
QFETCH(int, insertType);
|
||||
|
||||
QSignalSpy itemChangedSpy(testWidget, &QListWidget::itemChanged);
|
||||
QSignalSpy dataChangedSpy(testWidget->model(), &QAbstractItemModel::dataChanged);
|
||||
|
||||
if (insertType == 3) {
|
||||
QStringList strings;
|
||||
for (int i=0; i<rowCount; ++i)
|
||||
@ -700,6 +704,9 @@ void tst_QListWidget::insertItems()
|
||||
// make sure all items have view set correctly
|
||||
for (int i=0; i<testWidget->count(); ++i)
|
||||
QCOMPARE(testWidget->item(i)->listWidget(), testWidget);
|
||||
|
||||
QCOMPARE(itemChangedSpy.count(), 0);
|
||||
QCOMPARE(dataChangedSpy.count(), 0);
|
||||
}
|
||||
|
||||
void tst_QListWidget::itemAssignment()
|
||||
@ -1257,7 +1264,6 @@ void tst_QListWidget::setData()
|
||||
QFETCH(IntList, roles);
|
||||
QFETCH(QVariantList, values);
|
||||
QFETCH(int, expectedSignalCount);
|
||||
qRegisterMetaType<QListWidgetItem *>("QListWidgetItem*");
|
||||
|
||||
QCOMPARE(roles.count(), values.count());
|
||||
|
||||
@ -1715,7 +1721,6 @@ void tst_QListWidget::task258949_keypressHangup()
|
||||
|
||||
void tst_QListWidget::QTBUG8086_currentItemChangedOnClick()
|
||||
{
|
||||
qRegisterMetaType<QListWidgetItem*>("QListWidgetItem*");
|
||||
QWidget win;
|
||||
QHBoxLayout layout(&win);
|
||||
QListWidget list;
|
||||
@ -1837,7 +1842,6 @@ void tst_QListWidget::mimeData()
|
||||
|
||||
void tst_QListWidget::QTBUG50891_ensureSelectionModelSignalConnectionsAreSet()
|
||||
{
|
||||
qRegisterMetaType<QListWidgetItem*>("QListWidgetItem*");
|
||||
QListWidget list;
|
||||
for (int i = 0 ; i < 4; ++i)
|
||||
new QListWidgetItem(QString::number(i), &list);
|
||||
|
@ -46,3 +46,6 @@ osx
|
||||
osx-10.12 ci
|
||||
[multipleToplevelFocusCheck]
|
||||
linux
|
||||
[windowState]
|
||||
# QTBUG-75270
|
||||
winrt
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
private slots:
|
||||
void init();
|
||||
void repolish();
|
||||
void repolish_without_crashing();
|
||||
void numinstances();
|
||||
void widgetsBeforeAppStyleSheet();
|
||||
void widgetsAfterAppStyleSheet();
|
||||
@ -367,6 +368,26 @@ void tst_QStyleSheetStyle::repolish()
|
||||
QCOMPARE(BACKGROUND(p1), APPBACKGROUND(p1));
|
||||
}
|
||||
|
||||
void tst_QStyleSheetStyle::repolish_without_crashing()
|
||||
{
|
||||
// This used to crash, QTBUG-69204
|
||||
QMainWindow w;
|
||||
QScopedPointer<QSplitter> splitter1(new QSplitter(w.centralWidget()));
|
||||
QScopedPointer<QSplitter> splitter2(new QSplitter);
|
||||
QScopedPointer<QSplitter> splitter3(new QSplitter);
|
||||
splitter2->addWidget(splitter3.data());
|
||||
|
||||
splitter2->setStyleSheet("color: red");
|
||||
QScopedPointer<QLabel> label(new QLabel);
|
||||
label->setTextFormat(Qt::RichText);
|
||||
splitter3->addWidget(label.data());
|
||||
label->setText("hey");
|
||||
|
||||
splitter1->addWidget(splitter2.data());
|
||||
w.show();
|
||||
QCOMPARE(COLOR(*label), QColor(Qt::red));
|
||||
}
|
||||
|
||||
void tst_QStyleSheetStyle::widgetStyle()
|
||||
{
|
||||
qApp->setStyleSheet(QString());
|
||||
|
@ -90,15 +90,15 @@ int main(int argc, char **argv)
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
if (argc < 3) {
|
||||
printf("\nusage: %s inputFile outputFile\n\n", argv[0]);
|
||||
printf("\nUsage: ./%s inputFile outputFile\n\n", argv[0]);
|
||||
printf("'inputFile' should be a list of effective TLDs, one per line,\n");
|
||||
printf("as obtained from http://publicsuffix.org . To create indices and data file\n");
|
||||
printf("as obtained from http://publicsuffix.org/. To create indices and data\n");
|
||||
printf("file, do the following:\n\n");
|
||||
printf(" wget https://publicsuffix.org/list/effective_tld_names.dat -O effective_tld_names.dat\n");
|
||||
printf(" grep '^[^\\/\\/]' effective_tld_names.dat > effective_tld_names.dat.trimmed\n");
|
||||
printf(" %s effective_tld_names.dat.trimmed effective_tld_names.dat.qt\n\n", argv[0]);
|
||||
printf("Now copy the data from effective_tld_names.dat.qt to the file src/corelib/io/qurltlds_p.h in your Qt repo\n\n");
|
||||
exit(1);
|
||||
printf(" wget https://publicsuffix.org/list/public_suffix_list.dat -O public_suffix_list.dat\n");
|
||||
printf(" grep -v '^//' public_suffix_list.dat | grep . > public_suffix_list.dat.trimmed\n");
|
||||
printf(" ./%s public_suffix_list.dat.trimmed public_suffix_list.cpp\n\n", argv[0]);
|
||||
printf("Now replace the code in qtbase/src/corelib/io/qurltlds_p.h with public_suffix_list.cpp's contents\n\n");
|
||||
return 1;
|
||||
}
|
||||
QFile file(argv[1]);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user