diff --git a/.qmake.conf b/.qmake.conf index 7121ac2008522609c3e60b1bd6c416b80e1d3d1b..44af7abb454316c37301881f58c96718761712a0 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,5 +1,4 @@ load(qt_build_config) -CONFIG += qt_example_installs CONFIG += warning_clean QT_SOURCE_TREE = $$PWD diff --git a/config.tests/qpa/eglfs-viv/eglfs-viv.cpp b/config.tests/qpa/eglfs-viv/eglfs-viv.cpp index a41c482b670d52ed56caa72ba0e61d400d76deb5..96935a2aa0b20b37c7757fe61d72e4668b130c77 100644 --- a/config.tests/qpa/eglfs-viv/eglfs-viv.cpp +++ b/config.tests/qpa/eglfs-viv/eglfs-viv.cpp @@ -43,6 +43,8 @@ int main(int, char **) { - fbGetDisplay(); + // Do not rely on fbGetDisplay() since the signature has changed over time. + // Stick to fbGetDisplayByIndex(). + fbGetDisplayByIndex(0); return 0; } diff --git a/config.tests/qpa/kms/kms.pro b/config.tests/qpa/kms/kms.pro index 1fb73677e772717b5e08a448ba86e6ff7585f499..5147bc82da3d937644062bc2dc0a1188d2bd12d3 100644 --- a/config.tests/qpa/kms/kms.pro +++ b/config.tests/qpa/kms/kms.pro @@ -1,4 +1,4 @@ SOURCES = kms.cpp CONFIG += link_pkgconfig -PKGCONFIG += libdrm libudev +PKGCONFIG += libdrm CONFIG -= qt diff --git a/config.tests/unix/compile.test b/config.tests/unix/compile.test index 1228629aeaf1b606e3df64edfbb0436ba9f606b2..f5db1847b81004b6c78065d01fc325a6be7d5bbf 100755 --- a/config.tests/unix/compile.test +++ b/config.tests/unix/compile.test @@ -66,9 +66,6 @@ while [ "$#" -gt 0 ]; do shift done -# debuggery -[ "$VERBOSE" = "yes" ] && echo "$DESCRIPTION auto-detection... ($*)" - test -d "$OUTDIR/$TEST" || mkdir -p "$OUTDIR/$TEST" cd "$OUTDIR/$TEST" @@ -96,6 +93,7 @@ set -- \ "$SRCDIR/$TEST/$EXE.pro" \ -o "$OUTDIR/$TEST/Makefile" if [ "$VERBOSE" = "yes" ]; then + echo OUTDIR=$OUTDIR "$@" && $MAKE && SUCCESS=yes else OUTDIR=$OUTDIR "$@" >/dev/null 2>&1 && $MAKE >/dev/null 2>&1 && SUCCESS=yes @@ -103,9 +101,9 @@ fi # done if [ "$SUCCESS" != "yes" ]; then - [ "$VERBOSE" = "yes" ] && echo "$DESCRIPTION disabled." + [ "$VERBOSE" = "yes" ] && echo "$DESCRIPTION disabled." || echo " no." exit 1 else - [ "$VERBOSE" = "yes" ] && echo "$DESCRIPTION enabled." + [ "$VERBOSE" = "yes" ] && echo "$DESCRIPTION enabled." || echo " yes." exit 0 fi diff --git a/configure b/configure index a58256f08902dac27ce4d3e413aa6397b71dc2ac..3e455c616397e7c22cc2f97f60fa31e21b826230 100755 --- a/configure +++ b/configure @@ -91,6 +91,7 @@ for i in "$@"; do done # initialize global variables +CONFIG_SEPARATORS=`printf ' \t'` QMAKE_SWITCHES= QMAKE_VARS= QMAKE_CONFIG= @@ -348,6 +349,21 @@ getXQMakeConf() getSingleQMakeVariable "$1" "$xspecvals" } +testXConfig() +{ + # Put a space on each end of the CONFIG value so that searching for the + # target with whitespace on either side will work even when it's the + # first/last/only item in the CONFIG value. + case \ `getXQMakeConf CONFIG`\ in + *[${CONFIG_SEPARATORS}]$1[${CONFIG_SEPARATORS}]*) + return 0 + ;; + *) + return 1 + ;; + esac +} + compilerSupportsFlag() { cat >conftest.cpp <<EOF @@ -3926,7 +3942,7 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; setBootstrapVariable QMAKE_LFLAGS setBootstrapVariable QMAKE_LFLAGS_GCSECTIONS - if [ "$CFG_RELEASE_TOOLS" = "yes" ]; then + if [ "$CFG_DEBUG" = "no" ] || [ "$CFG_RELEASE_TOOLS" = "yes" ]; then setBootstrapVariable QMAKE_CFLAGS_RELEASE setBootstrapVariable QMAKE_CXXFLAGS_RELEASE EXTRA_CFLAGS="$EXTRA_CFLAGS \$(QMAKE_CFLAGS_RELEASE)" @@ -3938,12 +3954,6 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS \$(QMAKE_CXXFLAGS_DEBUG)" fi - if [ -n "$RPATH_FLAGS" ] && [ -n "`getQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then - setBootstrapVariable "QMAKE_(LFLAGS_)?RPATH" QMAKE_LFLAGS_RPATH - for rpath in $RPATH_FLAGS; do - EXTRA_LFLAGS="\$(QMAKE_LFLAGS_RPATH)\"$rpath\" $EXTRA_LFLAGS" - done - fi case `basename "$PLATFORM"` in win32-g++*) EXTRA_CFLAGS="$EXTRA_CFLAGS -DUNICODE" @@ -3994,9 +4004,6 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; \"\$(SOURCE_PATH)/src/corelib/kernel/qcore_mac.cpp\" \ \"\$(SOURCE_PATH)/src/corelib/kernel/qcore_mac_objc.mm\"" fi - if [ '!' -z "$D_FLAGS" ]; then - EXTRA_CFLAGS="$EXTRA_CFLAGS $D_FLAGS" - fi echo >>"$mkfile" adjrelpath=`echo "$relpath" | sed 's/ /\\\\\\\\ /g'` @@ -4225,6 +4232,7 @@ compileTest() if [ "$CFG_SHARED" = "no" ]; then test_config="$QMAKE_CONFIG static" fi + echo $ECHO_N "checking for $name... $ECHO_C" "$unixtests/compile.test" "$XQMAKESPEC" "$test_config" $OPT_VERBOSE "$relpath" "$outpath" "$path" "$name" "$CFG_QMAKE_PATH" "$QTCONFFILE" $I_FLAGS $D_FLAGS $L_FLAGS "$@" } @@ -5437,6 +5445,7 @@ if [ "$CFG_OPENGL" = "es2" ]; then fi # auto-detect FontConfig support +ORIG_CFG_FREETYPE="$CFG_FREETYPE" if [ "$CFG_FONTCONFIG" != "no" ]; then if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists fontconfig --exists freetype2 2>/dev/null; then QT_CFLAGS_FONTCONFIG=`$PKG_CONFIG --cflags fontconfig --cflags freetype2 2>/dev/null` @@ -5630,6 +5639,11 @@ if [ "$CFG_XCB" != "no" ]; then if [ "$CFG_XCB" = "qt" ]; then QT_CONFIG="$QT_CONFIG xcb-qt" + + if compileTest qpa/xcb-glx "xcb-glx" $QMAKE_CFLAGS_XCB $QMAKE_LIBS_XCB; then + CFG_XCB_GLX=yes + QT_CONFIG="$QT_CONFIG xcb-glx" + fi else CFG_XCB="system" if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists "xcb >= 1.5" 2>/dev/null; then @@ -6439,7 +6453,11 @@ fi [ "$CFG_STACK_PROTECTOR_STRONG" = "yes" ] && QT_CONFIG="$QT_CONFIG stack-protector-strong" [ "$CFG_REDUCE_RELOCATIONS" = "yes" ] && QT_CONFIG="$QT_CONFIG reduce_relocations" [ "$CFG_STRIP" = "no" ] && QMAKE_CONFIG="$QMAKE_CONFIG nostrip" -[ "$CFG_PRECOMPILE" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG precompile_header" +if testXConfig precompile_header; then + [ "$CFG_PRECOMPILE" = "no" ] && QMakeVar del CONFIG precompile_header +else + [ "$CFG_PRECOMPILE" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG precompile_header" +fi [ "$CFG_USE_GOLD_LINKER" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG use_gold_linker" [ "$CFG_ENABLE_NEW_DTAGS" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG enable_new_dtags" if [ "$CFG_SEPARATE_DEBUG_INFO" = "yes" ]; then @@ -7536,6 +7554,15 @@ if [ "$CFG_SHARED" = "no" ]; then echo "loaded plugins. Make sure to import all needed static plugins," echo "or compile needed modules into the library." fi +if [ "$CFG_FREETYPE" = "system" ]; then + if [ "$ORIG_CFG_FREETYPE" = "qt" ]; then + echo + echo "WARNING: Bundled FreeType can't be used. FontConfig use requires system FreeType." + elif [ "$ORIG_CFG_FREETYPE" = "no" ]; then + echo + echo "WARNING: FreeType can't be disabled. FontConfig use requires system FreeType." + fi +fi if [ "$CFG_OPENSSL" = "linked" ] && [ "$OPENSSL_LIBS" = "" ]; then echo echo "NOTE: When linking against OpenSSL, you can override the default" diff --git a/examples/corelib/mimetypes/mimetypebrowser/mimetypebrowser.pro b/examples/corelib/mimetypes/mimetypebrowser/mimetypebrowser.pro index 3788632c30e76971ffe05d0018f08e287687fd47..806e9cbd14e0781a791e68ad73a952388738c61e 100644 --- a/examples/corelib/mimetypes/mimetypebrowser/mimetypebrowser.pro +++ b/examples/corelib/mimetypes/mimetypebrowser/mimetypebrowser.pro @@ -11,3 +11,6 @@ SOURCES += \ HEADERS += \ mimetypemodel.h \ mainwindow.h + +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/mimetypes/mimetypebrowser +INSTALLS += target diff --git a/examples/widgets/itemviews/dirview/main.cpp b/examples/widgets/itemviews/dirview/main.cpp index cff65e52dfe7a2f2ab04826081cc5870ed5d4262..eefea657f69983703825500c969c0d616714766f 100644 --- a/examples/widgets/itemviews/dirview/main.cpp +++ b/examples/widgets/itemviews/dirview/main.cpp @@ -51,6 +51,7 @@ #include <QApplication> #include <QDesktopWidget> #include <QFileSystemModel> +#include <QFileIconProvider> #include <QTreeView> #include <QCommandLineParser> #include <QCommandLineOption> @@ -64,6 +65,8 @@ int main(int argc, char *argv[]) parser.setApplicationDescription("Qt Dir View Example"); parser.addHelpOption(); parser.addVersionOption(); + QCommandLineOption dontUseCustomDirectoryIconsOption("c", "Set QFileIconProvider::DontUseCustomDirectoryIcons"); + parser.addOption(dontUseCustomDirectoryIconsOption); parser.addPositionalArgument("directory", "The directory to start in."); parser.process(app); const QString rootPath = parser.positionalArguments().isEmpty() @@ -71,6 +74,8 @@ int main(int argc, char *argv[]) QFileSystemModel model; model.setRootPath(""); + if (parser.isSet(dontUseCustomDirectoryIconsOption)) + model.iconProvider()->setOptions(QFileIconProvider::DontUseCustomDirectoryIcons); QTreeView tree; tree.setModel(&model); if (!rootPath.isEmpty()) { diff --git a/mkspecs/devices/linux-imx6-g++/qmake.conf b/mkspecs/devices/linux-imx6-g++/qmake.conf index 71e37845c378a2ac4034537d88a83281463e23dd..46d631796d6037198bd3de411b2ecc71b159cce7 100644 --- a/mkspecs/devices/linux-imx6-g++/qmake.conf +++ b/mkspecs/devices/linux-imx6-g++/qmake.conf @@ -1,6 +1,23 @@ # # qmake configuration for the Freescale iMX6 boards (single, dual and quad) # +# The configuration below is set up for running with EGL on the framebuffer via +# the eglfs platform plugin and its eglfs_viv backend. + +# Wayland is also fully functional out of the box. However, when writing Wayland +# *compositors* with Qt, the eglfs backend will have to be switched to +# eglfs_viv_wl by setting the QT_QPA_EGLFS_INTEGRATION environment variable. +# +# Below is an example configure line that assumes the SDK is in +# $HOME/imx6/toolchain. On device Qt is expected to be placed under +# /usr/local/qt5 whereas on the host 'make install' will copy the host tools and +# the target libraries to $HOME/imx6/qt5. +# +# ./configure -prefix /usr/local/qt5 -extprefix $HOME/imx6/qt5 -device linux-imx6-g++ \ +# -device-option CROSS_COMPILE=$HOME/imx6/toolchain/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi- \ +# -sysroot $HOME/imx6/toolchain/sysroots/cortexa9hf-vfp-neon-poky-linux-gnueabi \ +# -nomake examples -nomake tests -v +# include(../common/linux_device_pre.conf) diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf index 92c288cdb653c4dbfaa49b9ffbf727a2424e8344..c772a3407aa892f07e565ee2de3fb102e6e0d49b 100644 --- a/mkspecs/features/configure.prf +++ b/mkspecs/features/configure.prf @@ -1,9 +1,7 @@ QMAKE_MAKE = $$(MAKE) !isEmpty(QMAKE_MAKE) { # We were called recursively. Use the right make, as MAKEFLAGS may be set as well. -} else:equals(MAKEFILE_GENERATOR, UNIX) { - QMAKE_MAKE = make -} else:equals(MAKEFILE_GENERATOR, MINGW) { +} else:if(equals(MAKEFILE_GENERATOR, UNIX)|equals(MAKEFILE_GENERATOR, MINGW)) { !equals(QMAKE_HOST.os, Windows): \ QMAKE_MAKE = make else: \ diff --git a/mkspecs/features/lex.prf b/mkspecs/features/lex.prf index 1ca9ae8afaef2dbb0b6658926666ea5ca88a65ca..16d3a6aa94ff60a2a097831953eb356faf5e4437 100644 --- a/mkspecs/features/lex.prf +++ b/mkspecs/features/lex.prf @@ -11,9 +11,13 @@ lex.variable_out = GENERATED_SOURCES } + isEmpty(QMAKE_LEXFLAGS_MANGLE):QMAKE_LEXFLAGS_MANGLE = -P${QMAKE_FILE_BASE} + QMAKE_LEXEXTRAFLAGS = $$QMAKE_LEXFLAGS + !yacc_no_name_mangle:QMAKE_LEXEXTRAFLAGS += $$QMAKE_LEXFLAGS_MANGLE + contains(QMAKE_LEX, .*flex) { # GNU flex, we can use -o outfile - lex.commands = $$QMAKE_LEX $$QMAKE_LEXFLAGS --nounistd -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} + lex.commands = $$QMAKE_LEX $$QMAKE_LEXEXTRAFLAGS --nounistd -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} } else { # stupid POSIX lex, it only generates a file called lex.yy.c # or lex.prefix.c if the -P<prefix> option is active diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf index 20b8eb4d53639a8b55679976fc8835bcbb433bcb..158bddf60c0ed03ac6bf201b23a96fff1a0a6408 100644 --- a/mkspecs/features/qml_plugin.prf +++ b/mkspecs/features/qml_plugin.prf @@ -15,8 +15,7 @@ TEMPLATE = lib CONFIG += plugin if(win32|mac):!macx-xcode { - contains(QT_CONFIG, debug_and_release):CONFIG += debug_and_release - contains(QT_CONFIG, build_all):CONFIG += build_all + contains(QT_CONFIG, debug_and_release): CONFIG += debug_and_release build_all } CONFIG += relative_qt_rpath # Qt's QML plugins should be relocatable diff --git a/mkspecs/features/qt_app.prf b/mkspecs/features/qt_app.prf index 823a4c9490df944da7dc7519c42d0eb5470ddb31..46aca50cc2f509b2633c989ee648152eb2e26c71 100644 --- a/mkspecs/features/qt_app.prf +++ b/mkspecs/features/qt_app.prf @@ -28,7 +28,7 @@ host_build:force_bootstrap { } target.path = $$[QT_HOST_BINS] } else { - !build_pass:contains(QT_CONFIG, debug_and_release):contains(QT_CONFIG, build_all): CONFIG += release + !build_pass:contains(QT_CONFIG, debug_and_release): CONFIG += release target.path = $$[QT_INSTALL_BINS] CONFIG += relative_qt_rpath # Qt's tools and apps should be relocatable } diff --git a/mkspecs/features/qt_build_config.prf b/mkspecs/features/qt_build_config.prf index 2d437e7f910d676360387e218703367146c7846e..1e2d5c2423349fb136f04e2cc26ff4210e73ad81 100644 --- a/mkspecs/features/qt_build_config.prf +++ b/mkspecs/features/qt_build_config.prf @@ -71,6 +71,7 @@ CONFIG += \ create_prl link_prl \ prepare_docs qt_docs_targets \ no_private_qt_headers_warning QTDIR_build \ + qt_example_installs \ # Qt modules get compiled without exceptions enabled by default. # However, testcases should be still built with exceptions. exceptions_off testcase_exceptions diff --git a/mkspecs/features/qt_example_installs.prf b/mkspecs/features/qt_example_installs.prf index ebf68a8a2175fbc41c37ce5626b7f8fbf1d79526..4c68cfd72fd5714ac5549f89176ec6011b4dee7c 100644 --- a/mkspecs/features/qt_example_installs.prf +++ b/mkspecs/features/qt_example_installs.prf @@ -100,6 +100,20 @@ probase = $$relative_path($$_PRO_FILE_PWD_, $$dirname(_QMAKE_CONF_)/examples) !isEmpty(allfiles): warning("remaining files in $$_PRO_FILE_PWD_: $$allfiles") } + equals(TEMPLATE, app)|equals(TEMPLATE, lib) { + !contains(INSTALLS, target) { + !install_ok: \ + error("$$_PRO_FILE_ is lacking an install target.") + else: check_examples: \ + warning("$$_PRO_FILE_ is lacking an install target.") + } else: !equals(target.path, $$sources.path) { + !install_ok: \ + error("$$_PRO_FILE_ installs target to unexpected location.") + else: check_examples: \ + warning("$$_PRO_FILE_ installs target to unexpected location.") + } + } + !equals(TEMPLATE, subdirs):!compile_examples { TEMPLATE = aux CONFIG -= have_target qt staticlib dll diff --git a/mkspecs/features/qt_helper_lib.prf b/mkspecs/features/qt_helper_lib.prf index ebc629f57ff9597d874de395e002beab5804d15a..33931544363644adb0010ac02e86fc1995045f6f 100644 --- a/mkspecs/features/qt_helper_lib.prf +++ b/mkspecs/features/qt_helper_lib.prf @@ -13,12 +13,12 @@ load(qt_build_paths) TEMPLATE = lib CONFIG -= qt +QT = # In case qt is re-added. CONFIG -= warning_clean # Don't presume 3rd party code to be clean load(qt_common) -contains(QT_CONFIG, debug_and_release): CONFIG += debug_and_release -contains(QT_CONFIG, build_all): CONFIG += build_all +contains(QT_CONFIG, debug_and_release): CONFIG += debug_and_release build_all DESTDIR = $$MODULE_BASE_OUTDIR/lib DLLDESTDIR = $$MODULE_BASE_OUTDIR/bin diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index aefd3aee1c865e5da7078af168eca6b617129e4b..5bd5101cdc559590a97eb8f2ce83d5b47d56fd35 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -38,7 +38,7 @@ host_build { QT += bootstrap-private } } else { - !build_pass:contains(QT_CONFIG, build_all): CONFIG += release + !build_pass:contains(QT_CONFIG, debug_and_release): CONFIG += release } } @@ -89,8 +89,7 @@ INCLUDEPATH *= $$eval(QT.$${MODULE}.includes) $$eval(QT.$${MODULE}_private.inclu # If Qt was configured with -debug-and-release then build the module the same way # - unless this is a host library !host_build:if(win32|mac):!macx-xcode { - contains(QT_CONFIG, debug_and_release):CONFIG += debug_and_release - contains(QT_CONFIG, build_all):CONFIG += build_all + contains(QT_CONFIG, debug_and_release): CONFIG += debug_and_release build_all } QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF diff --git a/mkspecs/features/qt_module_headers.prf b/mkspecs/features/qt_module_headers.prf index 7acca41d472224e0f3ffccc7c71d04a181fc0633..05d0706a3320146d932580573da85c72adb61f1a 100644 --- a/mkspecs/features/qt_module_headers.prf +++ b/mkspecs/features/qt_module_headers.prf @@ -188,6 +188,16 @@ headersclean:!internal_module { !contains(QT_ARCH, arm):!contains(QT_ARCH, mips): \ hcleanFLAGS += -Wcast-align + + !clang { + # options accepted only by GCC + + c++11 { + # only enabled for actual c++11 builds due to + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52806 + hcleanFLAGS += -Wzero-as-null-pointer-constant + } + } } # Use strict mode C++11 or C++98, with no GNU extensions (see -pedantic-errors above). diff --git a/mkspecs/features/qt_plugin.prf b/mkspecs/features/qt_plugin.prf index 220f11bd7554289bff380318b98c3be026747b8e..176159eff1ac50ccfa09339d00bb1bdc847ede43 100644 --- a/mkspecs/features/qt_plugin.prf +++ b/mkspecs/features/qt_plugin.prf @@ -24,10 +24,9 @@ win32:CONFIG(shared, static|shared) { } tool_plugin { - !build_pass:contains(QT_CONFIG, build_all): CONFIG += release + !build_pass:contains(QT_CONFIG, debug_and_release): CONFIG += release } else:if(win32|mac):!macx-xcode { - contains(QT_CONFIG, debug_and_release):CONFIG += debug_and_release - contains(QT_CONFIG, build_all):CONFIG += build_all + contains(QT_CONFIG, debug_and_release): CONFIG += debug_and_release build_all } CONFIG += relative_qt_rpath # Qt's plugins should be relocatable diff --git a/mkspecs/wince80colibri-armv7-msvc2012/qmake.conf b/mkspecs/wince80colibri-armv7-msvc2012/qmake.conf index 3712c9477854fae0963e657842dd02693cc6032d..7af1ca828efb4bcabe903df8a6989a1f68229805 100644 --- a/mkspecs/wince80colibri-armv7-msvc2012/qmake.conf +++ b/mkspecs/wince80colibri-armv7-msvc2012/qmake.conf @@ -7,6 +7,7 @@ include(../common/wince/qmake.conf) CE_SDK = Toradex_CE800 # replace with actual SDK name CE_ARCH = ARMV7 +CE_PLATFORMNAME = Toradex_CE800 QT_CONFIG -= accessibility DEFINES += QT_NO_CLIPBOARD QT_NO_ACCESSIBILITY QT_NO_NATIVE_GESTURES QT_NOSTANDARDSHELL_UI_MODEL _CRT_SECURE_NO_DEPRECATE _WIN32_WCE=0x800 $$CE_ARCH _AMRV7_ armv7 _ARM_ UNDER_CE WINCE ARM QT_NO_WINCE_SHELLSDK QT_NO_WINCE_NUIOUSER diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 9486cf8b6f36e9366c481d84bd11d6d4636c0754..d55e5bacf2e61da2d32d34bbe48332ec2761f6de 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -700,6 +700,8 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) QString slnConf = _slnSolutionConf; if (!project->isEmpty("VCPROJ_ARCH")) { slnConf.replace(QLatin1String("|Win32"), "|" + project->first("VCPROJ_ARCH")); + } else if (!project->isEmpty("CE_PLATFORMNAME")) { + slnConf.replace(QLatin1String("|Win32"), "|" + project->first("CE_PLATFORMNAME")); } else if (!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH")) { QString slnPlatform = QString("|") + project->values("CE_SDK").join(' ') + " (" + project->first("CE_ARCH") + ")"; slnConf.replace(QLatin1String("|Win32"), slnPlatform); @@ -717,6 +719,8 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) QString xplatform = platform; if (!project->isEmpty("VCPROJ_ARCH")) { xplatform = project->first("VCPROJ_ARCH").toQString(); + } else if (!project->isEmpty("CE_PLATFORMNAME")) { + xplatform = project->first("CE_PLATFORMNAME").toQString(); } else if (!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH")) { xplatform = project->values("CE_SDK").join(' ') + " (" + project->first("CE_ARCH") + ")"; } @@ -976,6 +980,8 @@ void VcprojGenerator::initProject() vcProject.Keyword = project->first("VCPROJ_KEYWORD").toQString(); if (!project->isEmpty("VCPROJ_ARCH")) { vcProject.PlatformName = project->first("VCPROJ_ARCH").toQString(); + } else if (!project->isEmpty("CE_PLATFORMNAME")) { + vcProject.PlatformName = project->first("CE_PLATFORMNAME").toQString(); } else if (project->isHostBuild() || project->isEmpty("CE_SDK") || project->isEmpty("CE_ARCH")) { vcProject.PlatformName = (is64Bit ? "x64" : "Win32"); } else { @@ -1060,6 +1066,8 @@ void VcprojGenerator::initConfiguration() conf.ConfigurationName = conf.Name; if (!project->isEmpty("VCPROJ_ARCH")) { conf.Name += "|" + project->first("VCPROJ_ARCH"); + } else if (!project->isEmpty("CE_PLATFORMNAME")) { + conf.Name += "|" + project->first("CE_PLATFORMNAME"); } else if (project->isHostBuild() || project->isEmpty("CE_SDK") || project->isEmpty("CE_ARCH")) { conf.Name += (is64Bit ? "|x64" : "|Win32"); } else { diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h index 721abb90d036fd26abf154f5b9fb425914a1ec87..dcff970600ab6417acf2485cf50853ca7f571014 100644 --- a/qmake/library/proitems.h +++ b/qmake/library/proitems.h @@ -130,8 +130,9 @@ public: bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(s, 0, cs) >= 0; } bool contains(const char *s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(QLatin1String(s), 0, cs) >= 0; } bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(c, 0, cs) >= 0; } - int toInt(bool *ok = 0, int base = 10) const { return toQString().toInt(ok, base); } // XXX optimize - short toShort(bool *ok = 0, int base = 10) const { return toQString().toShort(ok, base); } // XXX optimize + int toLongLong(bool *ok = 0, int base = 10) const { return toQStringRef().toLongLong(ok, base); } + int toInt(bool *ok = 0, int base = 10) const { return toQStringRef().toInt(ok, base); } + short toShort(bool *ok = 0, int base = 10) const { return toQStringRef().toShort(ok, base); } uint hash() const { return m_hash; } static uint hash(const QChar *p, int n); diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index 78a491b1cbc4b409bb0f55dc38f1d3609254c8ab..80569e503af3e2bdd5c926c2d793dcdf8084690d 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -192,9 +192,8 @@ void QMakeEvaluator::initFunctionStatics() statics.functions.insert(ProKey(testInits[i].name), testInits[i].func); } -static bool isTrue(const ProString &_str, QString &tmp) +static bool isTrue(const ProString &str) { - const QString &str = _str.toQString(tmp); return !str.compare(statics.strtrue, Qt::CaseInsensitive) || str.toInt(); } @@ -478,9 +477,9 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( } else { var = args[0]; sep = args.at(1).toQString(); - beg = args.at(2).toQString(m_tmp2).toInt(); + beg = args.at(2).toInt(); if (args.count() == 4) - end = args.at(3).toQString(m_tmp2).toInt(); + end = args.at(3).toInt(); } } else { if (args.count() != 1) { @@ -562,7 +561,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( break; } bool ok; - qlonglong num = m_tmp3.toLongLong(&ok, ibase); + qlonglong num = args.at(0).toLongLong(&ok, ibase); if (!ok) { evalError(fL1S("format_number(): malformed number %2 for base %1.") .arg(ibase).arg(m_tmp3)); @@ -639,7 +638,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( const ProStringList &var = values(map(args.at(0))); int start = 0, end = 0; if (args.count() >= 2) { - const QString &start_str = args.at(1).toQString(m_tmp1); + const ProString &start_str = args.at(1); start = start_str.toInt(&ok); if (!ok) { if (args.count() == 2) { @@ -652,11 +651,11 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( } if (!ok) evalError(fL1S("member() argument 2 (start) '%2' invalid.") - .arg(start_str)); + .arg(start_str.toQString(m_tmp1))); } else { end = start; if (args.count() == 3) - end = args.at(2).toQString(m_tmp1).toInt(&ok); + end = args.at(2).toInt(&ok); if (!ok) evalError(fL1S("member() argument 3 (end) '%2' invalid.") .arg(args.at(2).toQString(m_tmp1))); @@ -904,7 +903,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( } else { bool recursive = false; if (args.count() == 2) - recursive = isTrue(args.at(1), m_tmp2); + recursive = isTrue(args.at(1)); QStringList dirs; QString r = m_option->expandEnvVars(args.at(0).toQString(m_tmp1)) .replace(QLatin1Char('\\'), QLatin1Char('/')); @@ -1292,7 +1291,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( return ReturnFalse; } int cnt = values(map(args.at(0))).count(); - int val = args.at(1).toQString(m_tmp1).toInt(); + int val = args.at(1).toInt(); if (args.count() == 3) { const ProString &comp = args.at(2); if (comp == QLatin1String(">") || comp == QLatin1String("greaterThan")) { @@ -1403,7 +1402,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( flags = LoadSilent; if (args.count() >= 2) { parseInto = args.at(1).toQString(m_tmp2); - if (args.count() >= 3 && isTrue(args.at(2), m_tmp3)) + if (args.count() >= 3 && isTrue(args.at(2))) flags = LoadSilent; } QString fn = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1))); @@ -1441,7 +1440,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( case T_LOAD: { bool ignore_error = false; if (args.count() == 2) { - ignore_error = isTrue(args.at(1), m_tmp2); + ignore_error = isTrue(args.at(1)); } else if (args.count() != 1) { evalError(fL1S("load(feature) requires one or two arguments.")); return ReturnFalse; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp index 62badccefcfa1c51124751528bb5d61604a087f9..0173311bc69ffcf0161ea70dc09187751370f0de 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp @@ -2618,12 +2618,15 @@ bool Renderer11::getShareHandleSupport() const return false; } + // Qt: we don't care about the 9_3 limitation +#if 0 // Also disable share handles on Feature Level 9_3, since it doesn't support share handles on RGBA8 textures/swapchains. if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3) { mSupportsShareHandles = false; return false; } +#endif // Find out which type of D3D11 device the Renderer11 is using d3d11::ANGLED3D11DeviceType deviceType = getDeviceType(); diff --git a/src/3rdparty/angle/src/libANGLE/validationEGL.cpp b/src/3rdparty/angle/src/libANGLE/validationEGL.cpp index 972f6a7a5aed496411da10ded5e698c2472b6f5c..903f51b158d3dd7d971d32cb950ff31f7ca64b03 100644 --- a/src/3rdparty/angle/src/libANGLE/validationEGL.cpp +++ b/src/3rdparty/angle/src/libANGLE/validationEGL.cpp @@ -642,11 +642,14 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E return Error(EGL_BAD_ATTRIBUTE); } +// On Windows Store, we know the originating texture came from D3D11, so bypass this check +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) const Caps &caps = display->getCaps(); if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height))) { return Error(EGL_BAD_MATCH); } +#endif } return Error(EGL_SUCCESS); diff --git a/src/3rdparty/freetype/freetype.pro b/src/3rdparty/freetype/freetype.pro index d73d8ece5585a6b7bc4df31023898257a5a1fef7..e85ed1699bbb8fb590dbafc3135eb3dbad0feabb 100644 --- a/src/3rdparty/freetype/freetype.pro +++ b/src/3rdparty/freetype/freetype.pro @@ -64,10 +64,10 @@ win32 { INCLUDEPATH += $$PWD/include DEFINES += FT2_BUILD_LIBRARY -contains(QT_CONFIG, system-zlib) { - DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB - include($$PWD/../zlib_dependency.pri) -} + +DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB +include(../zlib_dependency.pri) + contains(QT_CONFIG, system-png) { DEFINES += FT_CONFIG_OPTION_USE_PNG include($$PWD/../png_dependency.pri) diff --git a/src/3rdparty/zlib_dependency.pri b/src/3rdparty/zlib_dependency.pri index 0bcb9f9e5ece15f9893ab8bc55d28c27aa45050f..53e0b3ef39d2c6d9de579164c7dbe1aabd4233f8 100644 --- a/src/3rdparty/zlib_dependency.pri +++ b/src/3rdparty/zlib_dependency.pri @@ -7,4 +7,8 @@ contains(QT_CONFIG, system-zlib) { } } else { INCLUDEPATH += $$PWD/zlib + !no_core_dep { + CONFIG += qt + QT_PRIVATE += core + } } diff --git a/src/angle/patches/0010-ANGLE-fixed-usage-of-shared-handles-for-WinRT-WinPho.patch b/src/angle/patches/0010-ANGLE-fixed-usage-of-shared-handles-for-WinRT-WinPho.patch new file mode 100644 index 0000000000000000000000000000000000000000..8f17018e6ec95072d9250b736a54b844f629b49c --- /dev/null +++ b/src/angle/patches/0010-ANGLE-fixed-usage-of-shared-handles-for-WinRT-WinPho.patch @@ -0,0 +1,57 @@ +From 5cacddc702624d64a4917a7a704dbbb92aeba53c Mon Sep 17 00:00:00 2001 +From: Oliver Wolff <oliver.wolff@qt.io> +Date: Thu, 19 May 2016 10:55:46 +0200 +Subject: [PATCH] ANGLE: fixed usage of shared handles for WinRT/WinPhone + applications + +Both checks are not relevant in Qt's context and were skipped before but +they sneaked back in with the latest ANGLE update. + +Change-Id: Ic44de5468a3254afd76ef4804d97d245676daeb1 +--- + src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp | 3 +++ + src/3rdparty/angle/src/libANGLE/validationEGL.cpp | 3 +++ + 2 files changed, 6 insertions(+) + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp +index 62badcc..0173311 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp +@@ -2618,12 +2618,15 @@ bool Renderer11::getShareHandleSupport() const + return false; + } + ++ // Qt: we don't care about the 9_3 limitation ++#if 0 + // Also disable share handles on Feature Level 9_3, since it doesn't support share handles on RGBA8 textures/swapchains. + if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3) + { + mSupportsShareHandles = false; + return false; + } ++#endif + + // Find out which type of D3D11 device the Renderer11 is using + d3d11::ANGLED3D11DeviceType deviceType = getDeviceType(); +diff --git a/src/3rdparty/angle/src/libANGLE/validationEGL.cpp b/src/3rdparty/angle/src/libANGLE/validationEGL.cpp +index 972f6a7..903f51b 100644 +--- a/src/3rdparty/angle/src/libANGLE/validationEGL.cpp ++++ b/src/3rdparty/angle/src/libANGLE/validationEGL.cpp +@@ -642,11 +642,14 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E + return Error(EGL_BAD_ATTRIBUTE); + } + ++// On Windows Store, we know the originating texture came from D3D11, so bypass this check ++#if !defined(ANGLE_ENABLE_WINDOWS_STORE) + const Caps &caps = display->getCaps(); + if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height))) + { + return Error(EGL_BAD_MATCH); + } ++#endif + } + + return Error(EGL_SUCCESS); +-- +2.7.0.windows.1 + diff --git a/src/angle/patches/0011-ANGLE-Disable-support-for-shared-handles-in-warp-mod.patch b/src/angle/patches/0011-ANGLE-Disable-support-for-shared-handles-in-warp-mod.patch new file mode 100644 index 0000000000000000000000000000000000000000..1c4ee1d513b838c514072e1543c2a13dd3ce5b7e --- /dev/null +++ b/src/angle/patches/0011-ANGLE-Disable-support-for-shared-handles-in-warp-mod.patch @@ -0,0 +1,44 @@ +From db13a9cf7e41207660f080827983655864df802d Mon Sep 17 00:00:00 2001 +From: Oliver Wolff <oliver.wolff@qt.io> +Date: Wed, 11 May 2016 13:51:54 +0200 +Subject: [PATCH] ANGLE: Disable support for shared handles in warp mode on + Windows < 8 + +Shared handles are not supported on Windows 7 and below. If the +according flag is set CreateTexture2D will fail with E_OUTOFMEMORY. The +check already happens with newer ANGLE versions, which we use in 5.7 +but has to happen here as well. Otherwise Qt applications running on +Windows 7 and below will crash at startup. + +Change-Id: I8f539f16dce298611fb1ec7b2f6804d4a04d04e0 +--- + .../angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp +index 223e2b0..dd554f4 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp +@@ -2370,6 +2370,19 @@ unsigned int Renderer11::getReservedFragmentUniformBuffers() const + + bool Renderer11::getShareHandleSupport() const + { ++ if (mDriverType == D3D_DRIVER_TYPE_WARP) ++ { ++#if !defined(ANGLE_ENABLE_WINDOWS_STORE) ++ // Warp mode does not support shared handles in Windows versions below Windows 8 ++ OSVERSIONINFO result = { sizeof(OSVERSIONINFO), 0, 0, 0, 0, {'\0'}}; ++ if (GetVersionEx(&result) && ++ ((result.dwMajorVersion == 6 && result.dwMinorVersion < 2) || result.dwMajorVersion < 6)) ++ { ++ // WARP on Windows 7 doesn't support shared handles ++ return false; ++ } ++#endif // ANGLE_ENABLE_WINDOWS_STORE ++ } + // We only currently support share handles with BGRA surfaces, because + // chrome needs BGRA. Once chrome fixes this, we should always support them. + // PIX doesn't seem to support using share handles, so disable them. +-- +2.7.0.windows.1 + diff --git a/src/concurrent/doc/qtconcurrent.qdocconf b/src/concurrent/doc/qtconcurrent.qdocconf index 3cd2fac075a76431fd79b6943878d81fe03e5674..d8ee963ef5c300da396ad7079c014ce5b6f49e5a 100644 --- a/src/concurrent/doc/qtconcurrent.qdocconf +++ b/src/concurrent/doc/qtconcurrent.qdocconf @@ -4,7 +4,7 @@ project = QtConcurrent description = Qt Concurrent Reference Documentation version = $QT_VERSION -examplesinstallpath = qtbase/qtconcurrent +examplesinstallpath = qtconcurrent qhp.projects = QtConcurrent diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf index e98f06d47d06307985611dc3a5d5884cc214a5f3..3d64708def40a7d793c196de9838eaae8a47e23b 100644 --- a/src/corelib/doc/qtcore.qdocconf +++ b/src/corelib/doc/qtcore.qdocconf @@ -4,7 +4,7 @@ project = QtCore description = Qt Core Reference Documentation version = $QT_VERSION -examplesinstallpath = qtbase/corelib +examplesinstallpath = corelib qhp.projects = QtCore diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index e35ee0987fa8e59aa269b4a2755bc01084e33241..2081ca8649153b65f31887029d5fdeb935347417 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -61,6 +61,9 @@ #include <QtCore/qfeatures.h> #endif +// The QT_SUPPORTS macro is deprecated. Don't use it in new code. +// Instead, use #ifdef/ndef QT_NO_feature. +// ### Qt6: remove macro #ifdef _MSC_VER # define QT_SUPPORTS(FEATURE) (!defined QT_NO_##FEATURE) #else diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 4851d1ce6f1c72a93a9ad427b69b8d3aca4b30a3..f2e293c45b6be7d60a96a2956f77ceb1e9177977 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -54,6 +54,7 @@ #include "qthread.h" #include "private/qloggingregistry_p.h" #include "private/qcoreapplication_p.h" +#include "private/qsimd_p.h" #endif #ifdef Q_OS_WIN #include <qt_windows.h> @@ -1193,6 +1194,89 @@ void QMessagePattern::setPattern(const QString &pattern) memcpy(literals, literalsVar.constData(), literalsVar.size() * sizeof(const char*)); } +#if defined(QLOGGING_HAVE_BACKTRACE) && !defined(QT_BOOTSTRAPPED) +// make sure the function has "Message" in the name so the function is removed + +#if (defined(Q_CC_GNU) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)) || QT_HAS_ATTRIBUTE(optimize) +// force skipping the frame pointer, to save the backtrace() function some work +__attribute__((optimize("omit-frame-pointer"))) +#endif +static QStringList backtraceFramesForLogMessage(int frameCount) +{ + QStringList result; + if (frameCount == 0) + return result; + + // The results of backtrace_symbols looks like this: + // /lib/libc.so.6(__libc_start_main+0xf3) [0x4a937413] + // The offset and function name are optional. + // This regexp tries to extract the library name (without the path) and the function name. + // This code is protected by QMessagePattern::mutex so it is thread safe on all compilers + static QRegularExpression rx(QStringLiteral("^(?:[^(]*/)?([^(/]+)\\(([^+]*)(?:[\\+[a-f0-9x]*)?\\) \\[[a-f0-9x]*\\]$"), + QRegularExpression::OptimizeOnFirstUsageOption); + + QVarLengthArray<void*, 32> buffer(7 + frameCount); + int n = backtrace(buffer.data(), buffer.size()); + if (n > 0) { + int numberPrinted = 0; + for (int i = 0; i < n && numberPrinted < frameCount; ++i) { + QScopedPointer<char*, QScopedPointerPodDeleter> strings(backtrace_symbols(buffer.data() + i, 1)); + QString trace = QString::fromLatin1(strings.data()[0]); + QRegularExpressionMatch m = rx.match(trace); + if (m.hasMatch()) { + QString library = m.captured(1); + QString function = m.captured(2); + + // skip the trace from QtCore that are because of the qDebug itself + if (!numberPrinted && library.contains(QLatin1String("Qt5Core")) + && (function.isEmpty() || function.contains(QLatin1String("Message"), Qt::CaseInsensitive) + || function.contains(QLatin1String("QDebug")))) { + continue; + } + + if (function.startsWith(QLatin1String("_Z"))) { + QScopedPointer<char, QScopedPointerPodDeleter> demangled( + abi::__cxa_demangle(function.toUtf8(), 0, 0, 0)); + if (demangled) + function = QString::fromUtf8(qCleanupFuncinfo(demangled.data())); + } + + if (function.isEmpty()) { + result.append(QLatin1Char('?') + library + QLatin1Char('?')); + } else { + result.append(function); + } + } else { + if (numberPrinted == 0) { + // innermost, unknown frames are usually the logging framework itself + continue; + } + result.append(QStringLiteral("???")); + } + numberPrinted++; + } + } + return result; +} + +static QString formatBacktraceForLogMessage(const QMessagePattern::BacktraceParams backtraceParams, + const char *function) +{ + QString backtraceSeparator = backtraceParams.backtraceSeparator; + int backtraceDepth = backtraceParams.backtraceDepth; + + QStringList frames = backtraceFramesForLogMessage(backtraceDepth); + if (frames.isEmpty()) + return QString(); + + // if the first frame is unknown, replace it with the context function + if (function && frames.at(0).startsWith(QLatin1Char('?'))) + frames[0] = QString::fromUtf8(qCleanupFuncinfo(function)); + + return frames.join(backtraceSeparator); +} +#endif // QLOGGING_HAVE_BACKTRACE && !QT_BOOTSTRAPPED + #if defined(QT_USE_SLOG2) #ifndef QT_LOG_CODE #define QT_LOG_CODE 9000 @@ -1336,62 +1420,8 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con #ifdef QLOGGING_HAVE_BACKTRACE } else if (token == backtraceTokenC) { QMessagePattern::BacktraceParams backtraceParams = pattern->backtraceArgs.at(backtraceArgsIdx); - QString backtraceSeparator = backtraceParams.backtraceSeparator; - int backtraceDepth = backtraceParams.backtraceDepth; backtraceArgsIdx++; - QVarLengthArray<void*, 32> buffer(7 + backtraceDepth); - int n = backtrace(buffer.data(), buffer.size()); - if (n > 0) { - int numberPrinted = 0; - for (int i = 0; i < n && numberPrinted < backtraceDepth; ++i) { - QScopedPointer<char*, QScopedPointerPodDeleter> strings(backtrace_symbols(buffer.data() + i, 1)); - QString trace = QString::fromLatin1(strings.data()[0]); - // The results of backtrace_symbols looks like this: - // /lib/libc.so.6(__libc_start_main+0xf3) [0x4a937413] - // The offset and function name are optional. - // This regexp tries to extract the librry name (without the path) and the function name. - // This code is protected by QMessagePattern::mutex so it is thread safe on all compilers - static QRegularExpression rx(QStringLiteral("^(?:[^(]*/)?([^(/]+)\\(([^+]*)(?:[\\+[a-f0-9x]*)?\\) \\[[a-f0-9x]*\\]$"), - QRegularExpression::OptimizeOnFirstUsageOption); - - QRegularExpressionMatch m = rx.match(trace); - if (m.hasMatch()) { - // skip the trace from QtCore that are because of the qDebug itself - QString library = m.captured(1); - QString function = m.captured(2); - if (!numberPrinted && library.contains(QLatin1String("Qt5Core")) - && (function.isEmpty() || function.contains(QLatin1String("Message"), Qt::CaseInsensitive) - || function.contains(QLatin1String("QDebug")))) { - continue; - } - - if (function.startsWith(QLatin1String("_Z"))) { - QScopedPointer<char, QScopedPointerPodDeleter> demangled( - abi::__cxa_demangle(function.toUtf8(), 0, 0, 0)); - if (demangled) - function = QString::fromUtf8(qCleanupFuncinfo(demangled.data())); - } - - if (numberPrinted > 0) - message.append(backtraceSeparator); - - if (function.isEmpty()) { - if (numberPrinted == 0 && context.function) - message += QString::fromUtf8(qCleanupFuncinfo(context.function)); - else - message += QLatin1Char('?') + library + QLatin1Char('?'); - } else { - message += function; - } - - } else { - if (numberPrinted == 0) - continue; - message += backtraceSeparator + QLatin1String("???"); - } - numberPrinted++; - } - } + message.append(formatBacktraceForLogMessage(backtraceParams, context.function)); #endif } else if (token == timeTokenC) { QString timeFormat = pattern->timeArgs.at(timeArgsIdx); diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index c73ceb950335cdf25c28ca06654dd8e99487b8c1..2a0b8461cd574be3881aceb271325431650d7cb6 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -508,6 +508,7 @@ public: AA_UseStyleSheetPropagationInWidgetStyles = 22, // ### Qt 6: remove me AA_DontUseNativeDialogs = 23, AA_SynthesizeMouseForUnhandledTabletEvents = 24, + AA_CompressHighFrequencyEvents = 25, // Add new attributes before this line AA_AttributeCount diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 60ce1fc9160d6884d44c960466c846804cecbb0c..3c53a23896c91ee8914e286d46b17ae8e54b2f29 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -239,6 +239,17 @@ to mouse events instead. This attribute is enabled by default. This value has been added in Qt 5.7. + \value AA_CompressHighFrequencyEvents Enables compression of certain frequent events. + On the X11 windowing system, the default value is true, which means that + QEvent::MouseMove, QEvent::TouchUpdate, and changes in window size and + position will be combined whenever they occur more frequently than the + application handles them, so that they don't accumulate and overwhelm the + application later. On other platforms, the default is false. + (In the future, the compression feature may be implemented across platforms.) + You can test the attribute to see whether compression is enabled. + If your application needs to handle all events with no compression, + you can unset this attribute. This value has been added in Qt 5.7. + The following values are obsolete: \value AA_ImmediateWidgetCreation This attribute is no longer fully diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index ee94720e7a973df20a5024eba53008b25fb1b7dd..6ecd41bc30d6221ff2fc737941e7b5ec718ad5bb 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -107,7 +107,7 @@ # define Q_PROCESSOR_ARM __TARGET_ARCH_ARM # elif defined(_M_ARM) && _M_ARM > 1 # define Q_PROCESSOR_ARM _M_ARM -# elif defined(__ARM64_ARCH_8__) +# elif defined(__ARM64_ARCH_8__) || defined(__aarch64__) # define Q_PROCESSOR_ARM 8 # elif defined(__ARM_ARCH_7__) \ || defined(__ARM_ARCH_7A__) \ diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 115b31dd2ec5db610198387bdb1f3d7d45354f1d..85c795fadd3e722f005d0df3291aeed3c16e1da0 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -885,7 +885,9 @@ static bool tryDriveUNCFallback(const QFileSystemEntry &fname, QFileSystemMetaDa #if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) if (fname.isDriveRoot()) { // a valid drive ?? + const UINT oldErrorMode = ::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); DWORD drivesBitmask = ::GetLogicalDrives(); + ::SetErrorMode(oldErrorMode); int drivebit = 1 << (fname.filePath().at(0).toUpper().unicode() - QLatin1Char('A').unicode()); if (drivesBitmask & drivebit) { fileAttrib = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM; diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index d94a8433a96789cfaeb79b4e8fd2c371ffa14b12..c37a690646883388dd597d40f145d5f223e1be7e 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -632,7 +632,9 @@ QFileInfoList QFSFileEngine::drives() QFileInfoList ret; #if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) #if defined(Q_OS_WIN32) + const UINT oldErrorMode = ::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); quint32 driveBits = (quint32) GetLogicalDrives() & 0x3ffffff; + ::SetErrorMode(oldErrorMode); #endif char driveName[] = "A:/"; diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index a826bcbd9b391bf04b52691d2c3457bd06d101a8..3a9f74bf59f089a5a4e25503506e6cfce8bd6fd2 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -108,25 +108,6 @@ QT_BEGIN_NAMESPACE -static bool isPseudoFs(const QString &mountDir, const QByteArray &type) -{ - if (mountDir.startsWith(QLatin1String("/dev")) - || mountDir.startsWith(QLatin1String("/proc")) - || mountDir.startsWith(QLatin1String("/sys")) - || mountDir.startsWith(QLatin1String("/var/run")) - || mountDir.startsWith(QLatin1String("/var/lock"))) { - return true; - } - if (type == "tmpfs") - return true; -#if defined(Q_OS_LINUX) - if (type == "rootfs" || type == "rpc_pipefs") - return true; -#endif - - return false; -} - class QStorageIterator { public: @@ -164,6 +145,39 @@ private: #endif }; +template <typename String> +static bool isParentOf(const String &parent, const QString &dirName) +{ + return dirName.startsWith(parent) && + (dirName.size() == parent.size() || dirName.at(parent.size()) == QLatin1Char('/') || + parent.size() == 1); +} + +static bool isPseudoFs(const QStorageIterator &it) +{ + QString mountDir = it.rootPath(); + if (isParentOf(QLatin1String("/dev"), mountDir) + || isParentOf(QLatin1String("/proc"), mountDir) + || isParentOf(QLatin1String("/sys"), mountDir) + || isParentOf(QLatin1String("/var/run"), mountDir) + || isParentOf(QLatin1String("/var/lock"), mountDir)) { + return true; + } + + QByteArray type = it.fileSystemType(); + if (type == "tmpfs") + return false; +#if defined(Q_OS_LINUX) + if (type == "rootfs" || type == "rpc_pipefs") + return true; +#endif + + if (!it.device().startsWith('/')) + return true; + + return false; +} + #if defined(Q_OS_BSD4) inline QStorageIterator::QStorageIterator() @@ -450,10 +464,8 @@ void QStorageInfoPrivate::initRootPath() while (it.next()) { const QString mountDir = it.rootPath(); const QByteArray fsName = it.fileSystemType(); - if (isPseudoFs(mountDir, fsName)) - continue; // we try to find most suitable entry - if (oldRootPath.startsWith(mountDir) && maxLength < mountDir.length()) { + if (isParentOf(mountDir, oldRootPath) && maxLength < mountDir.length()) { maxLength = mountDir.length(); rootPath = mountDir; device = it.device(); @@ -467,11 +479,14 @@ static inline QString retrieveLabel(const QByteArray &device) #ifdef Q_OS_LINUX static const char pathDiskByLabel[] = "/dev/disk/by-label"; + QFileInfo devinfo(QFile::decodeName(device)); + QString devicePath = devinfo.canonicalFilePath(); + QDirIterator it(QLatin1String(pathDiskByLabel), QDir::NoDotAndDotDot); while (it.hasNext()) { it.next(); QFileInfo fileInfo(it.fileInfo()); - if (fileInfo.isSymLink() && fileInfo.symLinkTarget().toLocal8Bit() == device) + if (fileInfo.isSymLink() && fileInfo.symLinkTarget() == devicePath) return fileInfo.fileName(); } #elif defined Q_OS_HAIKU @@ -542,11 +557,10 @@ QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes() QList<QStorageInfo> volumes; while (it.next()) { - const QString mountDir = it.rootPath(); - const QByteArray fsName = it.fileSystemType(); - if (isPseudoFs(mountDir, fsName)) + if (isPseudoFs(it)) continue; + const QString mountDir = it.rootPath(); volumes.append(QStorageInfo(mountDir)); } diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index 54afb8a97430120754742266dc494ea750be5315..d645205155b028935744bcbf880a51bfb41c8b65 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -3690,7 +3690,7 @@ bool QAbstractListModel::dropMimeData(const QMimeData *data, Qt::DropAction acti \fn QAbstractItemModel::modelAboutToBeReset() \since 4.2 - This signal is emitted when reset() is called, before the model's internal + This signal is emitted when beginResetModel() is called, before the model's internal state (e.g. persistent model indexes) has been invalidated. \sa beginResetModel(), modelReset() @@ -3700,7 +3700,7 @@ bool QAbstractListModel::dropMimeData(const QMimeData *data, Qt::DropAction acti \fn QAbstractItemModel::modelReset() \since 4.1 - This signal is emitted when reset() or endResetModel() is called, after the + This signal is emitted when endResetModel() is called, after the model's internal state (e.g. persistent model indexes) has been invalidated. Note that if a model is reset it should be considered that all information diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 5feb7a409b26c45f5375925e376eb03e27980885..f1d38db96cae0f629faf793d4ef9c27f4cea1803 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -945,6 +945,26 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok) } } #endif + if (QMetaType::typeFlags(t) & QMetaType::IsEnumeration) { + qlonglong value = qConvertToNumber(d, ok); + if (*ok) { + switch (QMetaType::sizeOf(t)) { + case 1: + *static_cast<signed char *>(result) = value; + return true; + case 2: + *static_cast<qint16 *>(result) = value; + return true; + case 4: + *static_cast<qint32 *>(result) = value; + return true; + case 8: + *static_cast<qint64 *>(result) = value; + return true; + } + } + return *ok; + } return false; } return true; @@ -2819,7 +2839,7 @@ static const quint32 qCanConvertMatrix[QVariant::LastCoreType + 1] = /*Int*/ 1 << QVariant::UInt | 1 << QVariant::String | 1 << QVariant::Double | 1 << QVariant::Bool | 1 << QVariant::LongLong | 1 << QVariant::ULongLong - | 1 << QVariant::Char | 1 << QVariant::ByteArray, + | 1 << QVariant::Char | 1 << QVariant::ByteArray | 1 << QVariant::Int, /*UInt*/ 1 << QVariant::Int | 1 << QVariant::String | 1 << QVariant::Double | 1 << QVariant::Bool | 1 << QVariant::LongLong | 1 << QVariant::ULongLong diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h index 5ea8bbe770a605aef4c81f8c156c6b3c38c574d5..447fca44c01435c76acff7e9402d0bba3c210898 100644 --- a/src/corelib/thread/qbasicatomic.h +++ b/src/corelib/thread/qbasicatomic.h @@ -232,8 +232,8 @@ public: AtomicType _q_value; - Type load() const Q_DECL_NOTHROW { return _q_value; } - void store(Type newValue) Q_DECL_NOTHROW { _q_value = newValue; } + Type load() const Q_DECL_NOTHROW { return Ops::load(_q_value); } + void store(Type newValue) Q_DECL_NOTHROW { Ops::store(_q_value, newValue); } operator Type() const Q_DECL_NOTHROW { return loadAcquire(); } Type operator=(Type newValue) Q_DECL_NOTHROW { storeRelease(newValue); return newValue; } diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index bf336a8f31122a1e1602363213be85fdd57733e6..36f1997a6c2732fd190c08eda681c78b8dffdbab 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -71,7 +71,7 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment, // Don't allocate empty headers if (!(options & RawData) && !capacity) { -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) if (options & Unsharable) return const_cast<QArrayData *>(&qt_array_unsharable_empty); #endif @@ -116,7 +116,7 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment, quintptr data = (quintptr(header) + sizeof(QArrayData) + alignment - 1) & ~(alignment - 1); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) header->ref.atomic.store(bool(!(options & Unsharable))); #else header->ref.atomic.store(1); @@ -138,7 +138,7 @@ void QArrayData::deallocate(QArrayData *data, size_t objectSize, && !(alignment & (alignment - 1))); Q_UNUSED(objectSize) Q_UNUSED(alignment) -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) if (data == &qt_array_unsharable_empty) return; #endif diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h index 79d0d006ac7c072824f4a9537464f298557322cd..5a369baf086390050bb2adccc6dbb8945e77c912 100644 --- a/src/corelib/tools/qarraydata.h +++ b/src/corelib/tools/qarraydata.h @@ -78,7 +78,7 @@ struct Q_CORE_EXPORT QArrayData enum AllocationOption { CapacityReserved = 0x1, -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) Unsharable = 0x2, #endif RawData = 0x4, @@ -255,7 +255,7 @@ struct QTypedArrayData return allocate(/* capacity */ 0); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) static QTypedArrayData *unsharableEmpty() { Q_STATIC_ASSERT(sizeof(QTypedArrayData) == sizeof(QArrayData)); diff --git a/src/corelib/tools/qarraydatapointer.h b/src/corelib/tools/qarraydatapointer.h index 20361205202156302b9cf17c92c37362ee462840..b97dde5a61d774b939acb2257ee2162bed3f3fad 100644 --- a/src/corelib/tools/qarraydatapointer.h +++ b/src/corelib/tools/qarraydatapointer.h @@ -133,7 +133,7 @@ public: return (!d->isMutable() || d->ref.isShared()); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) void setSharable(bool sharable) { if (needsDetach()) { diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index 06b539933e284be875ec047993e55af8b1167d7b..18facf7e429fa7b0fb40fb3a460494cfb8acc4f4 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -102,7 +102,7 @@ public: inline void detach() { if (d->ref.load() != 1) detach_helper(); } inline bool isDetached() const { return d->ref.load() == 1; } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; } #endif diff --git a/src/corelib/tools/qelapsedtimer_unix.cpp b/src/corelib/tools/qelapsedtimer_unix.cpp index e1fc77fb4ccc812e0dba15102cd4bf1f484b3b19..e2c3ae62808df9fb403a1aa1566270fb7487df0a 100644 --- a/src/corelib/tools/qelapsedtimer_unix.cpp +++ b/src/corelib/tools/qelapsedtimer_unix.cpp @@ -38,9 +38,6 @@ ** ****************************************************************************/ -// ask for the latest POSIX, just in case -#define _POSIX_C_SOURCE 200809L - #include "qelapsedtimer.h" #if defined(Q_OS_VXWORKS) #include "qfunctions_vxworks.h" diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index b15dc7b07be2e4678617cc3f4f3d03feb3d872ca..7abbeabeae34cfcae981a2bca30e3664f75beba3 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -272,7 +272,7 @@ public: inline void detach() { if (d->ref.isShared()) detach_helper(); } inline bool isDetached() const { return !d->ref.isShared(); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QHashData::shared_null) d->sharable = sharable; } #endif bool isSharedWith(const QHash &other) const { return d == other.d; } @@ -1092,9 +1092,6 @@ Q_INLINE_TEMPLATE int QMultiHash<Key, T>::count(const Key &key, const T &value) return n; } -Q_CORE_EXPORT int qGlobalQHashSeed(); -Q_CORE_EXPORT void qSetGlobalQHashSeed(int newSeed); - Q_DECLARE_ASSOCIATIVE_ITERATOR(Hash) Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(Hash) diff --git a/src/corelib/tools/qhashfunctions.h b/src/corelib/tools/qhashfunctions.h index b6cb84ee158e974b9550249945883aae81f433bd..0eb6c1b5ce71798f3a9932959af4af19a2387f89 100644 --- a/src/corelib/tools/qhashfunctions.h +++ b/src/corelib/tools/qhashfunctions.h @@ -64,6 +64,9 @@ class QString; class QStringRef; class QLatin1String; +Q_CORE_EXPORT int qGlobalQHashSeed(); +Q_CORE_EXPORT void qSetGlobalQHashSeed(int newSeed); + Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHashBits(const void *p, size_t size, uint seed = 0) Q_DECL_NOTHROW; Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(char key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; } diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h index 3e0de52da63c93d352249bd1a571e782fd158f13..e3eed9184fb1126ea69188d2d56004f40431efec 100644 --- a/src/corelib/tools/qlinkedlist.h +++ b/src/corelib/tools/qlinkedlist.h @@ -105,7 +105,7 @@ public: inline void detach() { if (d->ref.isShared()) detach_helper2(this->e); } inline bool isDetached() const { return !d->ref.isShared(); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QLinkedListData::shared_null) d->sharable = sharable; } #endif inline bool isSharedWith(const QLinkedList<T> &other) const { return d == other.d; } diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index ec279769ebd2d06a8d3c513471055e676694a62c..90ed5072e76537af6107109dbf1f4946fb9d4922 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -175,7 +175,7 @@ public: } inline bool isDetached() const { return !d->ref.isShared(); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (sharable == d->ref.isSharable()) diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index f84d733db0f6f9e68dde9ab0268f5454c8d0db6b..baa10b7a95039b3bb80732319959a82cd0902959 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -365,7 +365,7 @@ public: inline void detach() { if (d->ref.isShared()) detach_helper(); } inline bool isDetached() const { return !d->ref.isShared(); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (sharable == d->ref.isSharable()) diff --git a/src/corelib/tools/qrefcount.h b/src/corelib/tools/qrefcount.h index 77f06c807720c0a98c54f685af18d4bfbc5ccb8b..9586c3a79a1cb1145807b09cd69b4df9a9e9ad1b 100644 --- a/src/corelib/tools/qrefcount.h +++ b/src/corelib/tools/qrefcount.h @@ -53,7 +53,7 @@ class RefCount public: inline bool ref() Q_DECL_NOTHROW { int count = atomic.load(); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) if (count == 0) // !isSharable return false; #endif @@ -64,7 +64,7 @@ public: inline bool deref() Q_DECL_NOTHROW { int count = atomic.load(); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) if (count == 0) // !isSharable return false; #endif @@ -73,7 +73,7 @@ public: return atomic.deref(); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) bool setSharable(bool sharable) Q_DECL_NOTHROW { Q_ASSERT(!isShared()); diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h index 088403f09ddc23f74f1f005456ece9ba254ba5b3..08b38a08c2b282a132c31b38d5a811a708074035 100644 --- a/src/corelib/tools/qset.h +++ b/src/corelib/tools/qset.h @@ -85,7 +85,7 @@ public: inline void detach() { q_hash.detach(); } inline bool isDetached() const { return q_hash.isDetached(); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { q_hash.setSharable(sharable); } #endif diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index 9037442d9d546542c9ddb86c46469c0df7fb95bf..3a5f0f18a11f214976a56a0d3ee19259c95ce5e6 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -697,7 +697,11 @@ void qDetectCpuFeatures() // contains all the features that the code required. Qt 4 ran for years // like that, so it shouldn't be a problem. - qt_cpu_features.store(minFeature | quint32(QSimdInitialized)); + qt_cpu_features[0].store(minFeature | quint32(QSimdInitialized)); +#ifndef Q_ATOMIC_INT64_IS_SUPPORTED + qt_cpu_features[1].store(minFeature >> 32); +#endif + return; # endif #endif diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 557bec967658f2596f2b4d9a9cf65cc2e0960b9b..fea50f4c34533a3858b594cbc79e42b30e39a77a 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -106,7 +106,7 @@ public: inline void detach(); inline bool isDetached() const { return !d->ref.isShared(); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (sharable == d->ref.isSharable()) @@ -382,7 +382,7 @@ template <typename T> void QVector<T>::detach() { if (!isDetached()) { -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) if (!d->alloc) d = Data::unsharableEmpty(); else @@ -539,7 +539,7 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo x = Data::allocate(aalloc, options); Q_CHECK_PTR(x); // aalloc is bigger then 0 so it is not [un]sharedEmpty -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) Q_ASSERT(x->ref.isSharable() || options.testFlag(QArrayData::Unsharable)); #endif Q_ASSERT(!x->ref.isStatic()); @@ -607,7 +607,7 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo Q_ASSERT(d->data()); Q_ASSERT(uint(d->size) <= d->alloc); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) Q_ASSERT(d != Data::unsharableEmpty()); #endif Q_ASSERT(aalloc ? d != Data::sharedNull() : d == Data::sharedNull()); diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index 93dc71c3d8a015d1b435013cbf3e0a0c373ef8a0..b64ec756ba53c35d3840525d90121295cdfda797 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -155,6 +155,7 @@ else:SOURCES += tools/qelapsedtimer_generic.cpp contains(QT_CONFIG, zlib) { include($$PWD/../../3rdparty/zlib.pri) } else { + CONFIG += no_core_dep include($$PWD/../../3rdparty/zlib_dependency.pri) } diff --git a/src/dbus/doc/qtdbus.qdocconf b/src/dbus/doc/qtdbus.qdocconf index fc8921ff350356f3f3c342932d959a00cda8e879..ff46cc5961b508921092c470931f2e7ec45b1675 100644 --- a/src/dbus/doc/qtdbus.qdocconf +++ b/src/dbus/doc/qtdbus.qdocconf @@ -19,7 +19,7 @@ sourcedirs += .. \ ../../../examples/dbus/doc/src excludedirs += ../../../examples/widgets/doc -examplesinstallpath = qtbase/dbus +examplesinstallpath = dbus depends += qtdoc qtcore diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index f00988c05fda75c9e8ce36f3a592d56a3215465c..b710bfd2aa9f17092483348d5c843cb2060fed8e 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -259,7 +259,7 @@ private: const QVector<int> &metaTypes, int slotIdx); SignalHookHash::Iterator removeSignalHookNoLock(SignalHookHash::Iterator it); - void disconnectObjectTree(ObjectTreeNode &node); + void collectAllObjects(ObjectTreeNode &node, QSet<QObject *> &set); bool isServiceRegisteredByThread(const QString &serviceName); diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index c73f8084855044f0894479121bb06a51adea975d..54418c213ad4df35bd9ffb50201581425d314a9a 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1076,17 +1076,18 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate() } } -void QDBusConnectionPrivate::disconnectObjectTree(QDBusConnectionPrivate::ObjectTreeNode &haystack) +void QDBusConnectionPrivate::collectAllObjects(QDBusConnectionPrivate::ObjectTreeNode &haystack, + QSet<QObject *> &set) { QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it = haystack.children.begin(); while (it != haystack.children.end()) { - disconnectObjectTree(*it); + collectAllObjects(*it, set); it++; } if (haystack.obj) - haystack.obj->disconnect(this); + set.insert(haystack.obj); } void QDBusConnectionPrivate::closeConnection() @@ -1115,15 +1116,23 @@ void QDBusConnectionPrivate::closeConnection() // Disconnect all signals from signal hooks and from the object tree to // avoid QObject::destroyed being sent to dbus daemon thread which has - // already quit. - SignalHookHash::iterator sit = signalHooks.begin(); - while (sit != signalHooks.end()) { - sit.value().obj->disconnect(this); - sit++; + // already quit. We need to make sure we disconnect exactly once per + // object, because if we tried a second time, we might be hitting a + // dangling pointer. + QSet<QObject *> allObjects; + collectAllObjects(rootNode, allObjects); + SignalHookHash::const_iterator sit = signalHooks.constBegin(); + while (sit != signalHooks.constEnd()) { + allObjects.insert(sit.value().obj); + ++sit; + } + + // now disconnect ourselves + QSet<QObject *>::const_iterator oit = allObjects.constBegin(); + while (oit != allObjects.constEnd()) { + (*oit)->disconnect(this); + ++oit; } - - disconnectObjectTree(rootNode); - rootNode.children.clear(); // free resources } void QDBusConnectionPrivate::handleDBusDisconnection() diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf index 027d2663deadc734f71cae964ccae2e5848bfdc0..b07d39fa37bb6f1d1513ec29b3d393e8fa72687e 100644 --- a/src/gui/doc/qtgui.qdocconf +++ b/src/gui/doc/qtgui.qdocconf @@ -4,7 +4,7 @@ project = QtGui description = Qt GUI Reference Documentation version = $QT_VERSION -examplesinstallpath = qtbase/gui +examplesinstallpath = gui qhp.projects = QtGui diff --git a/src/gui/opengl/qopengl.cpp b/src/gui/opengl/qopengl.cpp index a798db662caf7ca31ec489b9501eb129668d7613..1a8fc599ce2772b73188d95f498e1701a6955eac 100644 --- a/src/gui/opengl/qopengl.cpp +++ b/src/gui/opengl/qopengl.cpp @@ -138,22 +138,6 @@ QDebug operator<<(QDebug d, const QOpenGLConfig::Gpu &g) enum Operator { NotEqual, LessThan, LessEqualThan, Equals, GreaterThan, GreaterEqualThan }; static const char operators[][3] = {"!=", "<", "<=", "=", ">", ">="}; -static inline QString valueKey() { return QStringLiteral("value"); } -static inline QString opKey() { return QStringLiteral("op"); } -static inline QString versionKey() { return QStringLiteral("version"); } -static inline QString releaseKey() { return QStringLiteral("release"); } -static inline QString typeKey() { return QStringLiteral("type"); } -static inline QString osKey() { return QStringLiteral("os"); } -static inline QString vendorIdKey() { return QStringLiteral("vendor_id"); } -static inline QString glVendorKey() { return QStringLiteral("gl_vendor"); } -static inline QString deviceIdKey() { return QStringLiteral("device_id"); } -static inline QString driverVersionKey() { return QStringLiteral("driver_version"); } -static inline QString driverDescriptionKey() { return QStringLiteral("driver_description"); } -static inline QString featuresKey() { return QStringLiteral("features"); } -static inline QString idKey() { return QStringLiteral("id"); } -static inline QString descriptionKey() { return QStringLiteral("description"); } -static inline QString exceptionsKey() { return QStringLiteral("exceptions"); } - typedef QJsonArray::ConstIterator JsonArrayConstIt; static inline bool contains(const QJsonArray &haystack, unsigned needle) @@ -216,8 +200,8 @@ VersionTerm VersionTerm::fromJson(const QJsonValue &v) if (!v.isObject()) return result; const QJsonObject o = v.toObject(); - result.number = QVersionNumber::fromString(o.value(valueKey()).toString()); - const QString opS = o.value(opKey()).toString(); + result.number = QVersionNumber::fromString(o.value(QLatin1String("value")).toString()); + const QString opS = o.value(QLatin1String("op")).toString(); for (size_t i = 0; i < sizeof(operators) / sizeof(operators[0]); ++i) { if (opS == QLatin1String(operators[i])) { result.op = static_cast<Operator>(i); @@ -292,9 +276,9 @@ OsTypeTerm OsTypeTerm::fromJson(const QJsonValue &v) if (!v.isObject()) return result; const QJsonObject o = v.toObject(); - result.type = o.value(typeKey()).toString(); - result.versionTerm = VersionTerm::fromJson(o.value(versionKey())); - result.release = o.value(releaseKey()).toArray(); + result.type = o.value(QLatin1String("type")).toString(); + result.versionTerm = VersionTerm::fromJson(o.value(QLatin1String("version"))); + result.release = o.value(QLatin1String("release")).toArray(); return result; } @@ -318,8 +302,8 @@ QString OsTypeTerm::hostOs() static QString msgSyntaxWarning(const QJsonObject &object, const QString &what) { QString result; - QTextStream(&result) << "Id " << object.value(idKey()).toInt() - << " (\"" << object.value(descriptionKey()).toString() + QTextStream(&result) << "Id " << object.value(QLatin1String("id")).toInt() + << " (\"" << object.value(QLatin1String("description")).toString() << "\"): " << what; return result; } @@ -333,11 +317,11 @@ static bool matches(const QJsonObject &object, const QString &osRelease, const QOpenGLConfig::Gpu &gpu) { - const OsTypeTerm os = OsTypeTerm::fromJson(object.value(osKey())); + const OsTypeTerm os = OsTypeTerm::fromJson(object.value(QLatin1String("os"))); if (!os.isNull() && !os.matches(osName, kernelVersion, osRelease)) return false; - const QJsonValue exceptionsV = object.value(exceptionsKey()); + const QJsonValue exceptionsV = object.value(QLatin1String("exceptions")); if (exceptionsV.isArray()) { const QJsonArray exceptionsA = exceptionsV.toArray(); for (JsonArrayConstIt it = exceptionsA.constBegin(), cend = exceptionsA.constEnd(); it != cend; ++it) { @@ -346,20 +330,20 @@ static bool matches(const QJsonObject &object, } } - const QJsonValue vendorV = object.value(vendorIdKey()); + const QJsonValue vendorV = object.value(QLatin1String("vendor_id")); if (vendorV.isString()) { if (gpu.vendorId != vendorV.toString().toUInt(Q_NULLPTR, /* base */ 0)) return false; } else { - if (object.contains(glVendorKey())) { - const QByteArray glVendorV = object.value(glVendorKey()).toString().toUtf8(); + if (object.contains(QLatin1String("gl_vendor"))) { + const QByteArray glVendorV = object.value(QLatin1String("gl_vendor")).toString().toUtf8(); if (!gpu.glVendor.contains(glVendorV)) return false; } } if (gpu.deviceId) { - const QJsonValue deviceIdV = object.value(deviceIdKey()); + const QJsonValue deviceIdV = object.value(QLatin1String("device_id")); switch (deviceIdV.type()) { case QJsonValue::Array: if (!contains(deviceIdV.toArray(), gpu.deviceId)) @@ -375,7 +359,7 @@ static bool matches(const QJsonObject &object, } } if (!gpu.driverVersion.isNull()) { - const QJsonValue driverVersionV = object.value(driverVersionKey()); + const QJsonValue driverVersionV = object.value(QLatin1String("driver_version")); switch (driverVersionV.type()) { case QJsonValue::Object: if (!VersionTerm::fromJson(driverVersionV).matches(gpu.driverVersion)) @@ -392,7 +376,7 @@ static bool matches(const QJsonObject &object, } if (!gpu.driverDescription.isEmpty()) { - const QJsonValue driverDescriptionV = object.value(driverDescriptionKey()); + const QJsonValue driverDescriptionV = object.value(QLatin1String("driver_description")); if (driverDescriptionV.isString()) { if (!gpu.driverDescription.contains(driverDescriptionV.toString().toUtf8())) return false; @@ -412,7 +396,7 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, { result->clear(); errorMessage->clear(); - const QJsonValue entriesV = doc.object().value(QStringLiteral("entries")); + const QJsonValue entriesV = doc.object().value(QLatin1String("entries")); if (!entriesV.isArray()) { *errorMessage = QLatin1String("No entries read."); return false; @@ -423,7 +407,7 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, if (eit->isObject()) { const QJsonObject object = eit->toObject(); if (matches(object, osName, kernelVersion, osRelease, gpu)) { - const QJsonValue featuresListV = object.value(featuresKey()); + const QJsonValue featuresListV = object.value(QLatin1String("features")); if (featuresListV.isArray()) { const QJsonArray featuresListA = featuresListV.toArray(); for (JsonArrayConstIt fit = featuresListA.constBegin(), fcend = featuresListA.constEnd(); fit != fcend; ++fit) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 1b947154eff59f7ceae7447b29d1dc78da3a93c8..8bc15bf777ba2b00f29363967ac61808fd4fcc42 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6272,7 +6272,7 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const pen.setColor(uc); // Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms - const QPixmap wave = generateWavyPixmap(qMin(qMax(underlineOffset, pen.widthF()), maxHeight / 2.), pen); + const QPixmap wave = generateWavyPixmap(qMin(qMax(underlineOffset, pen.widthF()), maxHeight / qreal(2.)), pen); const int descent = qFloor(maxHeight); painter->setBrushOrigin(painter->brushOrigin().x(), 0); @@ -6283,7 +6283,7 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const // the text above it, but limit it to stay within descent. qreal adjustedUnderlineOffset = std::ceil(underlineOffset) + 0.5; if (underlineOffset <= fe->descent().toReal()) - adjustedUnderlineOffset = qMin(adjustedUnderlineOffset, fe->descent().toReal() - 0.5); + adjustedUnderlineOffset = qMin(adjustedUnderlineOffset, fe->descent().toReal() - qreal(0.5)); const qreal underlinePos = pos.y() + adjustedUnderlineOffset; QColor uc = charFormat.underlineColor(); if (uc.isValid()) diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 6cec4a0a8db513b6e8d316649d621bc3d80bcf3d..35cf1dae86452cb489c52c6e4623811167961f73 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -232,7 +232,8 @@ void QPlatformTextureList::clear() Flushes the given \a region from the specified \a window onto the screen. - Note that the \a offset parameter is currently unused. + The \a offset parameter is relative to the origin of the backing + store image. */ #ifndef QT_NO_OPENGL diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index 92683448aa92fefa8ded6805ef2696ec4266011d..c52792c2d329abb624e04aaa13ee1deb270ca4b3 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -428,7 +428,7 @@ void QStroker::processCurrentSubpath() bool fwclosed = qt_stroke_side(&fwit, this, false, &fwStartTangent); bool bwclosed = qt_stroke_side(&bwit, this, !fwclosed, &bwStartTangent); - if (!bwclosed) + if (!bwclosed && !fwStartTangent.isNull()) joinPoints(m_elements.at(0).x, m_elements.at(0).y, fwStartTangent, m_capStyle); } diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index d2b1a8a9120b2f9fe9b2a8ecd64e3de3aa528080..927e103abc5fb77f1aeda07226d68c2c0b3f59db 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -480,6 +480,9 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent) // connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)), SLOT(_q_onlineStateChanged(bool))); + connect(&d->networkConfigurationManager, SIGNAL(configurationChanged(const QNetworkConfiguration &)), + SLOT(_q_configurationChanged(const QNetworkConfiguration &))); + #endif } @@ -1570,6 +1573,8 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed())); QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(stateChanged(QNetworkSession::State)), q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State))); + QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)), + q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); } //switch to new session (null if config was invalid) @@ -1577,7 +1582,6 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co networkSessionWeakRef = networkSessionStrongRef.toWeakRef(); if (!networkSessionStrongRef) { - online = false; if (networkAccessible == QNetworkAccessManager::NotAccessible || !online) emit q->networkAccessibleChanged(QNetworkAccessManager::NotAccessible); @@ -1593,6 +1597,8 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co QObject::connect(networkSessionStrongRef.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()), Qt::QueuedConnection); QObject::connect(networkSessionStrongRef.data(), SIGNAL(stateChanged(QNetworkSession::State)), q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection); + QObject::connect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)), + q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); _q_networkSessionStateChanged(networkSessionStrongRef->state()); } @@ -1609,6 +1615,9 @@ void QNetworkAccessManagerPrivate::_q_networkSessionClosed() QObject::disconnect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed())); QObject::disconnect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)), q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State))); + QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)), + q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); + networkSessionStrongRef.clear(); networkSessionWeakRef.clear(); } @@ -1617,46 +1626,57 @@ void QNetworkAccessManagerPrivate::_q_networkSessionClosed() void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession::State state) { Q_Q(QNetworkAccessManager); - + bool reallyOnline = false; //Do not emit the networkSessionConnected signal here, except for roaming -> connected //transition, otherwise it is emitted twice in a row when opening a connection. - if (state == QNetworkSession::Connected && lastSessionState == QNetworkSession::Roaming) + if (state == QNetworkSession::Connected && lastSessionState != QNetworkSession::Roaming) emit q->networkSessionConnected(); lastSessionState = state; - if (online) { + if (online && state == QNetworkSession::Disconnected) { + const auto cfgs = networkConfigurationManager.allConfigurations(); + for (const QNetworkConfiguration &cfg : cfgs) { + if (cfg.state().testFlag(QNetworkConfiguration::Active)) { + reallyOnline = true; + } + } + } else if (state == QNetworkSession::Connected || state == QNetworkSession::Roaming) { + reallyOnline = true; + } + + if (!reallyOnline) { if (state != QNetworkSession::Connected && state != QNetworkSession::Roaming) { - online = false; if (networkAccessible != QNetworkAccessManager::NotAccessible) { networkAccessible = QNetworkAccessManager::NotAccessible; emit q->networkAccessibleChanged(networkAccessible); } } } else { - if (state == QNetworkSession::Connected || state == QNetworkSession::Roaming) { - online = true; - if (defaultAccessControl) - if (networkAccessible != QNetworkAccessManager::Accessible) { - networkAccessible = QNetworkAccessManager::Accessible; - emit q->networkAccessibleChanged(networkAccessible); - } - } + if (defaultAccessControl) + if (networkAccessible != QNetworkAccessManager::Accessible) { + networkAccessible = QNetworkAccessManager::Accessible; + emit q->networkAccessibleChanged(networkAccessible); + } + } + online = reallyOnline; + if (online && (state != QNetworkSession::Connected && state != QNetworkSession::Roaming)) { + _q_networkSessionClosed(); + createSession(q->configuration()); } } void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) { Q_Q(QNetworkAccessManager); + // if the user set a config, we only care whether this one is active. // Otherwise, this QNAM is online if there is an online config. if (customNetworkConfiguration) { online = (networkConfiguration.state() & QNetworkConfiguration::Active); } else { if (online != isOnline) { - if (isOnline) { - networkSessionStrongRef.clear(); - networkSessionWeakRef.clear(); - } + _q_networkSessionClosed(); + createSession(q->configuration()); online = isOnline; } } @@ -1667,11 +1687,6 @@ void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) emit q->networkAccessibleChanged(networkAccessible); } } - } else if (networkConfiguration.state().testFlag(QNetworkConfiguration::Undefined)) { - if (networkAccessible != QNetworkAccessManager::UnknownAccessibility) { - networkAccessible = QNetworkAccessManager::UnknownAccessibility; - emit q->networkAccessibleChanged(networkAccessible); - } } else { if (networkAccessible != QNetworkAccessManager::NotAccessible) { networkAccessible = QNetworkAccessManager::NotAccessible; @@ -1680,6 +1695,50 @@ void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) } } +void QNetworkAccessManagerPrivate::_q_configurationChanged(const QNetworkConfiguration &configuration) +{ + const QString id = configuration.identifier(); + if (configuration.state().testFlag(QNetworkConfiguration::Active)) { + if (!onlineConfigurations.contains(id)) { + + QSharedPointer<QNetworkSession> session(getNetworkSession()); + if (session) { + if (online && session->configuration().identifier() + != networkConfigurationManager.defaultConfiguration().identifier()) { + + onlineConfigurations.insert(id); + //this one disconnected but another one is online, + // close and create new session + _q_networkSessionClosed(); + createSession(networkConfigurationManager.defaultConfiguration()); + } + } + } + + } else if (onlineConfigurations.contains(id)) { + //this one is disconnecting + onlineConfigurations.remove(id); + if (!onlineConfigurations.isEmpty()) { + _q_networkSessionClosed(); + createSession(configuration); + } + } +} + + +void QNetworkAccessManagerPrivate::_q_networkSessionFailed(QNetworkSession::SessionError) +{ + const auto cfgs = networkConfigurationManager.allConfigurations(); + for (const QNetworkConfiguration &cfg : cfgs) { + if (cfg.state().testFlag(QNetworkConfiguration::Active)) { + online = true; + _q_networkSessionClosed(); + createSession(networkConfigurationManager.defaultConfiguration()); + return; + } + } +} + #endif // QT_NO_BEARERMANAGEMENT QNetworkRequest QNetworkAccessManagerPrivate::prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart) diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h index 4efa30df490e4cb72e15af6ad6d5f5f201a86058..4ce47577c85ec3b32745ed64d3e57e10f508736b 100644 --- a/src/network/access/qnetworkaccessmanager.h +++ b/src/network/access/qnetworkaccessmanager.h @@ -182,6 +182,8 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_networkSessionClosed()) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State)) Q_PRIVATE_SLOT(d_func(), void _q_onlineStateChanged(bool)) + Q_PRIVATE_SLOT(d_func(), void _q_configurationChanged(const QNetworkConfiguration &)) + Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed(QNetworkSession::SessionError)) #endif }; diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index 413de2a4fed399fe21093d7d0fe7be0782bce1f3..44cf2533681f50f852ba3bcf69267452583bf420 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -149,6 +149,11 @@ public: bool isSeamless); void _q_networkSessionStateChanged(QNetworkSession::State state); void _q_onlineStateChanged(bool isOnline); + void _q_configurationChanged(const QNetworkConfiguration &configuration); + void _q_networkSessionFailed(QNetworkSession::SessionError error); + + QSet<QString> onlineConfigurations; + #endif QNetworkRequest prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart); diff --git a/src/network/doc/qtnetwork.qdocconf b/src/network/doc/qtnetwork.qdocconf index 87e322d6c0038314724c01ea8b51c64c23da8efa..2a8e577dda0501fc6b809425e7817c69042592f2 100644 --- a/src/network/doc/qtnetwork.qdocconf +++ b/src/network/doc/qtnetwork.qdocconf @@ -4,7 +4,7 @@ project = QtNetwork description = Qt Network Reference Documentation version = $QT_VERSION -examplesinstallpath = qtbase/network +examplesinstallpath = network qhp.projects = QtNetwork diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index 78753a7393584fb9edb233e78d8a27d626afe315..a73f01a2fcfc15c42b6cc7f28197ad8d372fd0be 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -199,6 +199,8 @@ bool QAuthenticator::operator==(const QAuthenticator &other) const { if (d == other.d) return true; + if (!d || !other.d) + return false; return d->user == other.d->user && d->password == other.d->password && d->realm == other.d->realm diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h index cf36887e9234f389ca18cdf63b0b26c6a3082c4f..56f8b590f1e7d903a461f170ce03b782a14b9d0d 100644 --- a/src/network/socket/qlocalsocket_p.h +++ b/src/network/socket/qlocalsocket_p.h @@ -61,7 +61,6 @@ #if defined(QT_LOCALSOCKET_TCP) # include "qtcpsocket.h" #elif defined(Q_OS_WIN) -# include <private/qringbuffer_p.h> # include "private/qwindowspipereader_p.h" # include "private/qwindowspipewriter_p.h" # include <qwineventnotifier.h> @@ -134,7 +133,6 @@ public: void _q_pipeClosed(); void _q_winError(ulong windowsError, const QString &function); HANDLE handle; - QRingBuffer writeBuffer; QWindowsPipeWriter *pipeWriter; QWindowsPipeReader *pipeReader; QLocalSocket::LocalSocketError error; diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 66b461522b636ff44fc57975257049aae5181f86..bed4355aa979295f1ced93e00dd5e71702b8fcf1 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -107,6 +107,7 @@ QLocalSocketPrivate::QLocalSocketPrivate() : QIODevicePrivate(), error(QLocalSocket::UnknownSocketError), state(QLocalSocket::UnconnectedState) { + writeBufferChunkSize = QIODEVICE_BUFFERSIZE; } QLocalSocketPrivate::~QLocalSocketPrivate() @@ -214,8 +215,7 @@ qint64 QLocalSocket::writeData(const char *data, qint64 len) Q_D(QLocalSocket); if (len == 0) return 0; - char *dest = d->writeBuffer.reserve(len); - memcpy(dest, data, len); + d->writeBuffer.append(data, len); if (!d->pipeWriter) { d->pipeWriter = new QWindowsPipeWriter(d->handle, this); connect(d->pipeWriter, &QWindowsPipeWriter::bytesWritten, @@ -233,7 +233,6 @@ void QLocalSocket::abort() if (d->pipeWriter) { delete d->pipeWriter; d->pipeWriter = 0; - d->writeBuffer.clear(); } close(); } @@ -291,6 +290,7 @@ void QLocalSocket::close() if (openMode() == NotOpen) return; + d->setWriteChannelCount(0); QIODevice::close(); d->serverName = QString(); d->fullServerName = QString(); diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 18f90a8a4edd77ec1d5e91bf3bc8503668fd7795..181c49f200e6686fdd5241f3dd22b63cd436935b 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -464,17 +464,24 @@ void QNativeSocketEngine::close() } #if _MSC_VER >= 1900 - // To close the connection properly (not with a hard reset) all pending read operation have to - // be finished or cancelled. The API isn't available on Windows 8.1 though. - ComPtr<IStreamSocket3> socket3; - hr = d->tcpSocket()->QueryInterface(IID_PPV_ARGS(&socket3)); - Q_ASSERT_SUCCEEDED(hr); + if (d->socketType == QAbstractSocket::TcpSocket) { + hr = QEventDispatcherWinRT::runOnXamlThread([d]() { + HRESULT hr; + // To close the connection properly (not with a hard reset) all pending read operation have to + // be finished or cancelled. The API isn't available on Windows 8.1 though. + ComPtr<IStreamSocket3> socket3; + hr = d->tcpSocket()->QueryInterface(IID_PPV_ARGS(&socket3)); + Q_ASSERT_SUCCEEDED(hr); - ComPtr<IAsyncAction> action; - hr = socket3->CancelIOAsync(&action); - Q_ASSERT_SUCCEEDED(hr); - hr = QWinRTFunctions::await(action); - Q_ASSERT_SUCCEEDED(hr); + ComPtr<IAsyncAction> action; + hr = socket3->CancelIOAsync(&action); + Q_ASSERT_SUCCEEDED(hr); + hr = QWinRTFunctions::await(action); + Q_ASSERT_SUCCEEDED(hr); + return S_OK; + }); + Q_ASSERT_SUCCEEDED(hr); + } #endif // _MSC_VER >= 1900 if (d->readOp) { @@ -1271,9 +1278,12 @@ void QNativeSocketEnginePrivate::handleConnectionEstablished(IAsyncAction *actio HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *asyncInfo, AsyncStatus status) { - Q_Q(QNativeSocketEngine); - if (wasDeleted || isDeletingChildren) + if (closingDown || wasDeleted || isDeletingChildren + || socketState == QAbstractSocket::UnconnectedState) { return S_OK; + } + + Q_Q(QNativeSocketEngine); // A read in UnconnectedState will close the socket and return -1 and thus tell the caller, // that the connection was closed. The socket cannot be closed here, as the subsequent read diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index 2c4d439a29b598589fb562e79dc1cc222882c6e4..325e4965e682571ba1bb6c286c4891e8596a5514 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -154,7 +154,7 @@ public: qintptr socketDescriptor; bool notifyOnRead, notifyOnWrite, notifyOnException; - bool closingDown; + QAtomicInt closingDown; enum ErrorString { NonBlockingInitFailedErrorString, diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp index f9bb28e033ebdd706ef86c70638a402b1061aa53..c8040dec7fdc5e58efe6a22cf3f8dae80d618899 100644 --- a/src/network/ssl/qsslconfiguration.cpp +++ b/src/network/ssl/qsslconfiguration.cpp @@ -211,6 +211,7 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const d->sessionProtocol == other.d->sessionProtocol && d->ciphers == other.d->ciphers && d->ellipticCurves == other.d->ellipticCurves && + d->ephemeralServerKey == other.d->ephemeralServerKey && d->caCertificates == other.d->caCertificates && d->protocol == other.d->protocol && d->peerVerifyMode == other.d->peerVerifyMode && @@ -252,6 +253,7 @@ bool QSslConfiguration::isNull() const d->caCertificates.count() == 0 && d->ciphers.count() == 0 && d->ellipticCurves.isEmpty() && + d->ephemeralServerKey.isNull() && d->localCertificateChain.isEmpty() && d->privateKey.isNull() && d->peerCertificate.isNull() && diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h index 093c9d6598ea44c0504137cb66f45ab4393afd65..364bba92ec777f7b2b9509174a7d9f64ef334e49 100644 --- a/src/network/ssl/qsslconfiguration_p.h +++ b/src/network/ssl/qsslconfiguration_p.h @@ -88,6 +88,7 @@ public: peerSessionShared(false), sslOptions(QSslConfigurationPrivate::defaultSslOptions), sslSessionTicketLifeTimeHint(-1), + ephemeralServerKey(), nextProtocolNegotiationStatus(QSslConfiguration::NextProtocolNegotiationNone) { } diff --git a/src/opengl/doc/qtopengl.qdocconf b/src/opengl/doc/qtopengl.qdocconf index 3c5fc280bd57320aeed6364546231db197bec6df..6ff6cae2cb0260218e079dcb9effb2e1f589b83c 100644 --- a/src/opengl/doc/qtopengl.qdocconf +++ b/src/opengl/doc/qtopengl.qdocconf @@ -21,7 +21,7 @@ imagedirs += images \ depends += qtdoc qtcore qtgui qtwidgets qmake -examplesinstallpath = qtbase/opengl +examplesinstallpath = opengl # The following parameters are for creating a qhp file, the qhelpgenerator # program can convert the qhp file into a qch file which can be opened in diff --git a/src/platformheaders/doc/qtplatformheaders.qdocconf b/src/platformheaders/doc/qtplatformheaders.qdocconf index 989df524e66c8ef0f59d8cc655bbce7fc663a978..1ff6fe7a21752cb76961c4ecd8395a2ab5749a5b 100644 --- a/src/platformheaders/doc/qtplatformheaders.qdocconf +++ b/src/platformheaders/doc/qtplatformheaders.qdocconf @@ -4,7 +4,7 @@ project = QtPlatformHeaders description = Qt Platform Headers Reference Documentation version = $QT_VERSION -examplesinstallpath = qtbase/qtplatformheaders +examplesinstallpath = qtplatformheaders qhp.projects = QtPlatformHeaders diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm index 2ad734b8b9e8fca0f932b7d1a39088228ba40c94..68a367cce38315724e3fc9085763f6bfcbf5226c 100644 --- a/src/platformsupport/clipboard/qmacmime.mm +++ b/src/platformsupport/clipboard/qmacmime.mm @@ -757,7 +757,7 @@ bool QMacPasteboardMimeVCard::canConvert(const QString &mime, QString flav) QString QMacPasteboardMimeVCard::flavorFor(const QString &mime) { - if (mime.startsWith(QLatin1String("text/plain"))) + if (mime.startsWith(QLatin1String("text/vcard"))) return QLatin1String("public.vcard"); return QString(); } @@ -765,14 +765,14 @@ QString QMacPasteboardMimeVCard::flavorFor(const QString &mime) QString QMacPasteboardMimeVCard::mimeFor(QString flav) { if (flav == QLatin1String("public.vcard")) - return QLatin1String("text/plain"); + return QLatin1String("text/vcard"); return QString(); } QVariant QMacPasteboardMimeVCard::convertToMime(const QString &mime, QList<QByteArray> data, QString) { QByteArray cards; - if (mime == QLatin1String("text/plain")) { + if (mime == QLatin1String("text/vcard")) { for (int i=0; i<data.size(); ++i) cards += data[i]; } @@ -782,7 +782,7 @@ QVariant QMacPasteboardMimeVCard::convertToMime(const QString &mime, QList<QByte QList<QByteArray> QMacPasteboardMimeVCard::convertFromMime(const QString &mime, QVariant data, QString) { QList<QByteArray> ret; - if (mime == QLatin1String("text/plain")) + if (mime == QLatin1String("text/vcard")) ret.append(data.toString().toUtf8()); return ret; } diff --git a/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp b/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp index ee25f1a2b0ecea10e6df2d07d16aa3c4a0aaf60b..361146dc232a517b85a926911e190d4f58b9047b 100644 --- a/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp +++ b/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp @@ -65,9 +65,10 @@ const QString MenuBarPath = QLatin1String("/MenuBar"); A D-Bus connection which is used for both menu and tray icon services. Connects to the session bus and registers with the respective watcher services. */ -QDBusMenuConnection::QDBusMenuConnection(QObject *parent) +QDBusMenuConnection::QDBusMenuConnection(QObject *parent, const QString &serviceName) : QObject(parent) - , m_connection(QDBusConnection::sessionBus()) + , m_connection(serviceName.isNull() ? QDBusConnection::sessionBus() + : QDBusConnection::connectToBus(QDBusConnection::SessionBus, serviceName)) , m_dbusWatcher(new QDBusServiceWatcher(StatusNotifierWatcherService, m_connection, QDBusServiceWatcher::WatchForRegistration, this)) , m_statusNotifierHostRegistered(false) { diff --git a/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h b/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h index b9434ee4d783d0aac192c233b8f232f3181fdeda..84eb2a6f3a95fab2092b3d9c296ce74bdaf81601 100644 --- a/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h +++ b/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h @@ -67,7 +67,7 @@ class QDBusMenuConnection : public QObject Q_OBJECT public: - QDBusMenuConnection(QObject *parent = 0); + QDBusMenuConnection(QObject *parent = 0, const QString &serviceName = QString()); QDBusConnection connection() const { return m_connection; } bool isStatusNotifierHostRegistered() const { return m_statusNotifierHostRegistered; } #ifndef QT_NO_SYSTEMTRAYICON diff --git a/src/platformsupport/dbustray/qdbustrayicon.cpp b/src/platformsupport/dbustray/qdbustrayicon.cpp index c8de50ebe1c4eafe92777a16d8d6d637453112fc..724992f348174408ff6f05a359cca421b0df6ed5 100644 --- a/src/platformsupport/dbustray/qdbustrayicon.cpp +++ b/src/platformsupport/dbustray/qdbustrayicon.cpp @@ -171,7 +171,7 @@ QTemporaryFile *QDBusTrayIcon::tempIcon(const QIcon &icon) QDBusMenuConnection * QDBusTrayIcon::dBusConnection() { if (!m_dbusConnection) { - m_dbusConnection = new QDBusMenuConnection(this); + m_dbusConnection = new QDBusMenuConnection(this, m_instanceId); m_notifier = new QXdgNotificationInterface(XdgNotificationService, XdgNotificationPath, m_dbusConnection->connection(), this); connect(m_notifier, SIGNAL(NotificationClosed(uint,uint)), this, SLOT(notificationClosed(uint,uint))); diff --git a/src/platformsupport/eglconvenience/qeglpbuffer_p.h b/src/platformsupport/eglconvenience/qeglpbuffer_p.h index e454f14f33ebd44299ae76990581545d151fd795..19a29d5dd8c121c58f2a417631e5dfe7d9491ce2 100644 --- a/src/platformsupport/eglconvenience/qeglpbuffer_p.h +++ b/src/platformsupport/eglconvenience/qeglpbuffer_p.h @@ -51,9 +51,9 @@ // We mean it. // -#include <EGL/egl.h> #include <qpa/qplatformoffscreensurface.h> #include <QtPlatformSupport/private/qeglplatformcontext_p.h> +#include <EGL/egl.h> QT_BEGIN_NAMESPACE diff --git a/src/platformsupport/fbconvenience/qfbbackingstore.cpp b/src/platformsupport/fbconvenience/qfbbackingstore.cpp index 3a919887993df06dbd9fe678148014d80ced1337..fa1b8d0acd1cdb6a4e6f30ac94112769c318e5b5 100644 --- a/src/platformsupport/fbconvenience/qfbbackingstore.cpp +++ b/src/platformsupport/fbconvenience/qfbbackingstore.cpp @@ -43,6 +43,7 @@ #include <qpa/qplatformwindow.h> #include <QtGui/qscreen.h> +#include <QtGui/qpainter.h> QT_BEGIN_NAMESPACE @@ -90,9 +91,17 @@ void QFbBackingStore::unlock() mImageMutex.unlock(); } -void QFbBackingStore::beginPaint(const QRegion &) +void QFbBackingStore::beginPaint(const QRegion ®ion) { lock(); + + if (mImage.hasAlphaChannel()) { + QPainter p(&mImage); + p.setCompositionMode(QPainter::CompositionMode_Source); + const QVector<QRect> rects = region.rects(); + for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) + p.fillRect(*it, Qt::transparent); + } } void QFbBackingStore::endPaint() diff --git a/src/platformsupport/fbconvenience/qfbscreen.cpp b/src/platformsupport/fbconvenience/qfbscreen.cpp index d6318497752e60a252cc81a5e8a7a3c99f6780fb..4066743cc286a52f0838474913bfaaf73c69f770 100644 --- a/src/platformsupport/fbconvenience/qfbscreen.cpp +++ b/src/platformsupport/fbconvenience/qfbscreen.cpp @@ -239,6 +239,7 @@ QRegion QFbScreen::doRedraw() if (!mCompositePainter) mCompositePainter = new QPainter(mScreenImage); + for (int rectIndex = 0; rectIndex < mRepaintRegion.rectCount(); rectIndex++) { QRegion rectRegion = rects[rectIndex]; @@ -256,7 +257,8 @@ QRegion QFbScreen::doRedraw() foreach (const QRect &rect, intersect.rects()) { bool firstLayer = true; if (layer == -1) { - mCompositePainter->fillRect(rect, Qt::black); + mCompositePainter->setCompositionMode(QPainter::CompositionMode_Source); + mCompositePainter->fillRect(rect, mScreenImage->hasAlphaChannel() ? Qt::transparent : Qt::black); firstLayer = false; layer = mWindowStack.size() - 1; } @@ -289,6 +291,7 @@ QRegion QFbScreen::doRedraw() QRect cursorRect; if (mCursor && (mCursor->isDirty() || mRepaintRegion.intersects(mCursor->lastPainted()))) { + mCompositePainter->setCompositionMode(QPainter::CompositionMode_SourceOver); cursorRect = mCursor->drawCursor(*mCompositePainter); touchedRegion += cursorRect; } diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index f5372151b790a58f84bc4d562ffa2af32186a241..533e0e2d5b5165a5e40333d54cfb4bf6031633b9 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -373,7 +373,7 @@ static QByteArray filenameForCFUrl(CFURLRef url) if (!CFURLGetFileSystemRepresentation(url, true, buffer, sizeof(buffer))) { qWarning("QCoreTextFontDatabase::filenameForCFUrl: could not resolve file for URL %s", - qPrintable(QString::fromCFString(CFURLGetString(url)))); + url ? qPrintable(QString::fromCFString(CFURLGetString(url))) : "(null)"); } else { QCFType<CFStringRef> scheme = CFURLCopyScheme(url); if (QString::fromCFString(scheme) == QLatin1String("qrc")) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index c7209fe696c4306e17efd9f2ebfe7909d88c754e..3d214b6f39247cbd1ce45d97475e6befde03cfa4 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -47,6 +47,49 @@ #include <cmath> +#if defined(Q_OS_OSX) && !QT_OSX_DEPLOYMENT_TARGET_BELOW(__MAC_10_11) +#import <AppKit/AppKit.h> +#endif + +#if defined(Q_OS_IOS) && !QT_IOS_DEPLOYMENT_TARGET_BELOW(__IPHONE_8_2) +#import <UIKit/UIKit.h> +#endif + +// These are available cross platform, exported as kCTFontWeightXXX from CoreText.framework, +// but they are not documented and are not in public headers so are private API and exposed +// only through the NSFontWeightXXX and UIFontWeightXXX aliases in AppKit and UIKit (rdar://26109857) +#if QT_MAC_DEPLOYMENT_TARGET_BELOW(__MAC_10_11, __IPHONE_8_2) +#define kCTFontWeightUltraLight -0.8 +#define kCTFontWeightThin -0.6 +#define kCTFontWeightLight -0.4 +#define kCTFontWeightRegular 0 +#define kCTFontWeightMedium 0.23 +#define kCTFontWeightSemibold 0.3 +#define kCTFontWeightBold 0.4 +#define kCTFontWeightHeavy 0.56 +#define kCTFontWeightBlack 0.62 +#elif defined(Q_OS_OSX) +#define kCTFontWeightUltraLight NSFontWeightUltraLight +#define kCTFontWeightThin NSFontWeightThin +#define kCTFontWeightLight NSFontWeightLight +#define kCTFontWeightRegular NSFontWeightRegular +#define kCTFontWeightMedium NSFontWeightMedium +#define kCTFontWeightSemibold NSFontWeightSemibold +#define kCTFontWeightBold NSFontWeightBold +#define kCTFontWeightHeavy NSFontWeightHeavy +#define kCTFontWeightBlack NSFontWeightBlack +#elif defined(Q_OS_IOS) +#define kCTFontWeightUltraLight UIFontWeightUltraLight +#define kCTFontWeightThin UIFontWeightThin +#define kCTFontWeightLight UIFontWeightLight +#define kCTFontWeightRegular UIFontWeightRegular +#define kCTFontWeightMedium UIFontWeightMedium +#define kCTFontWeightSemibold UIFontWeightSemibold +#define kCTFontWeightBold UIFontWeightBold +#define kCTFontWeightHeavy UIFontWeightHeavy +#define kCTFontWeightBlack UIFontWeightBlack +#endif + QT_BEGIN_NAMESPACE static float SYNTHETIC_ITALIC_SKEW = std::tan(14.f * std::acos(0.f) / 90.f); @@ -69,24 +112,24 @@ bool QCoreTextFontEngine::ct_getSfntTable(void *user_data, uint tag, uchar *buff QFont::Weight QCoreTextFontEngine::qtWeightFromCFWeight(float value) { - if (value >= 0.62) + if (value >= kCTFontWeightBlack) return QFont::Black; - if (value >= 0.5) + if (value >= kCTFontWeightHeavy) return QFont::ExtraBold; - if (value >= 0.4) + if (value >= kCTFontWeightBold) return QFont::Bold; - if (value >= 0.3) + if (value >= kCTFontWeightSemibold) return QFont::DemiBold; - if (value >= 0.2) + if (value >= kCTFontWeightMedium) return QFont::Medium; - if (value == 0.0) + if (value == kCTFontWeightRegular) return QFont::Normal; - if (value <= -0.4) - return QFont::Light; - if (value <= -0.6) - return QFont::ExtraLight; - if (value <= -0.8) + if (value <= kCTFontWeightUltraLight) return QFont::Thin; + if (value <= kCTFontWeightThin) + return QFont::ExtraLight; + if (value <= kCTFontWeightLight) + return QFont::Light; return QFont::Normal; } diff --git a/src/plugins/bearer/nativewifi/main.cpp b/src/plugins/bearer/nativewifi/main.cpp index 84320bfe14d3854cc3374f262d3e202bc51a8901..826c0104e44ea20f49fd7f2ff5025acdac3ffc3e 100644 --- a/src/plugins/bearer/nativewifi/main.cpp +++ b/src/plugins/bearer/nativewifi/main.cpp @@ -41,7 +41,6 @@ #include "platformdefs.h" #include <QtCore/qmutex.h> -#include <QtCore/private/qmutexpool_p.h> #include <QtCore/qlibrary.h> #include <QtNetwork/private/qbearerplugin_p.h> @@ -52,42 +51,32 @@ QT_BEGIN_NAMESPACE -static void resolveLibrary() +static bool resolveLibraryInternal() { - static QBasicAtomicInt triedResolve = Q_BASIC_ATOMIC_INITIALIZER(false); - - if (!triedResolve.loadAcquire()) { -#ifndef QT_NO_THREAD - QMutexLocker locker(QMutexPool::globalInstanceGet(&local_WlanOpenHandle)); -#endif - - if (!triedResolve.load()) { - QLibrary wlanapiLib(QLatin1String("wlanapi")); - local_WlanOpenHandle = (WlanOpenHandleProto) - wlanapiLib.resolve("WlanOpenHandle"); - local_WlanRegisterNotification = (WlanRegisterNotificationProto) - wlanapiLib.resolve("WlanRegisterNotification"); - local_WlanEnumInterfaces = (WlanEnumInterfacesProto) - wlanapiLib.resolve("WlanEnumInterfaces"); - local_WlanGetAvailableNetworkList = (WlanGetAvailableNetworkListProto) - wlanapiLib.resolve("WlanGetAvailableNetworkList"); - local_WlanQueryInterface = (WlanQueryInterfaceProto) - wlanapiLib.resolve("WlanQueryInterface"); - local_WlanConnect = (WlanConnectProto) - wlanapiLib.resolve("WlanConnect"); - local_WlanDisconnect = (WlanDisconnectProto) - wlanapiLib.resolve("WlanDisconnect"); - local_WlanScan = (WlanScanProto) - wlanapiLib.resolve("WlanScan"); - local_WlanFreeMemory = (WlanFreeMemoryProto) - wlanapiLib.resolve("WlanFreeMemory"); - local_WlanCloseHandle = (WlanCloseHandleProto) - wlanapiLib.resolve("WlanCloseHandle"); - - triedResolve.storeRelease(true); - } - } + QLibrary wlanapiLib(QLatin1String("wlanapi")); + local_WlanOpenHandle = (WlanOpenHandleProto) + wlanapiLib.resolve("WlanOpenHandle"); + local_WlanRegisterNotification = (WlanRegisterNotificationProto) + wlanapiLib.resolve("WlanRegisterNotification"); + local_WlanEnumInterfaces = (WlanEnumInterfacesProto) + wlanapiLib.resolve("WlanEnumInterfaces"); + local_WlanGetAvailableNetworkList = (WlanGetAvailableNetworkListProto) + wlanapiLib.resolve("WlanGetAvailableNetworkList"); + local_WlanQueryInterface = (WlanQueryInterfaceProto) + wlanapiLib.resolve("WlanQueryInterface"); + local_WlanConnect = (WlanConnectProto) + wlanapiLib.resolve("WlanConnect"); + local_WlanDisconnect = (WlanDisconnectProto) + wlanapiLib.resolve("WlanDisconnect"); + local_WlanScan = (WlanScanProto) + wlanapiLib.resolve("WlanScan"); + local_WlanFreeMemory = (WlanFreeMemoryProto) + wlanapiLib.resolve("WlanFreeMemory"); + local_WlanCloseHandle = (WlanCloseHandleProto) + wlanapiLib.resolve("WlanCloseHandle"); + return true; } +Q_GLOBAL_STATIC_WITH_ARGS(bool, resolveLibrary, (resolveLibraryInternal())) class QNativeWifiEnginePlugin : public QBearerEnginePlugin { diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp index f15c4dd49692b9e5341941e7217900b9a881314c..17d1aeeb5ddfeb89eb560166cc407bb26d1b1294 100644 --- a/src/plugins/imageformats/ico/qicohandler.cpp +++ b/src/plugins/imageformats/ico/qicohandler.cpp @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE typedef struct { quint8 bWidth; // Width of the image - quint8 bHeight; // Height of the image (times 2) + quint8 bHeight; // Height of the image (actual height, not times 2) quint8 bColorCount; // Number of colors in image (0 if >=8bpp) [ not ture ] quint8 bReserved; // Reserved quint16 wPlanes; // Color Planes @@ -687,8 +687,8 @@ bool ICOReader::write(QIODevice *device, const QVector<QImage> &images) entries[i].bColorCount = 0; entries[i].bReserved = 0; entries[i].wBitCount = nbits; - entries[i].bHeight = image.height(); - entries[i].bWidth = image.width(); + entries[i].bHeight = image.height() < 256 ? image.height() : 0; // 0 means 256 + entries[i].bWidth = image.width() < 256 ? image.width() : 0; // 0 means 256 entries[i].dwBytesInRes = BMP_INFOHDR_SIZE + (bpl_bmp * image.height()) + (maskImage.bytesPerLine() * maskImage.height()); entries[i].wPlanes = 1; @@ -702,11 +702,11 @@ bool ICOReader::write(QIODevice *device, const QVector<QImage> &images) bmpHeaders[i].biClrImportant = 0; bmpHeaders[i].biClrUsed = entries[i].bColorCount; bmpHeaders[i].biCompression = 0; - bmpHeaders[i].biHeight = entries[i].bHeight * 2; // 2 is for the mask + bmpHeaders[i].biHeight = entries[i].bHeight ? entries[i].bHeight * 2 : 256 * 2; // 2 is for the mask bmpHeaders[i].biPlanes = entries[i].wPlanes; bmpHeaders[i].biSize = BMP_INFOHDR_SIZE; bmpHeaders[i].biSizeImage = entries[i].dwBytesInRes - BMP_INFOHDR_SIZE; - bmpHeaders[i].biWidth = entries[i].bWidth; + bmpHeaders[i].biWidth = entries[i].bWidth ? entries[i].bWidth : 256; bmpHeaders[i].biXPelsPerMeter = 0; bmpHeaders[i].biYPelsPerMeter = 0; diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm index 47f9539d9cafa1079010b5eb206be8eeab1826d8..85468009f32103098ec356f7cb6422bd1aab1dc4 100644 --- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm @@ -58,7 +58,7 @@ static NSButton *macCreateButton(const char *text, NSView *superview) [button setButtonType:NSMomentaryLightButton]; [button setBezelStyle:NSRoundedBezelStyle]; [button setTitle:(NSString*)(CFStringRef)QCFString( - QPlatformTheme::removeMnemonics(QCoreApplication::translate("QDialogButtonBox", text)))]; + QPlatformTheme::removeMnemonics(QCoreApplication::translate("QPlatformTheme", text)))]; [[button cell] setFont:[NSFont systemFontOfSize: [NSFont systemFontSizeForControlSize:NSRegularControlSize]]]; [superview addSubview:button]; diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index a445b6e9bf2123f524b2605ea93d8a7f312f1d87..86f6dda2e9bb7f3415b293f791cc32126fdc7d5f 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -179,7 +179,9 @@ void QCocoaMenuBar::syncMenu(QPlatformMenu *menu) } } - nativeItemForMenu(cocoaMenu).hidden = shouldHide; + NSMenuItem *nativeMenuItem = nativeItemForMenu(cocoaMenu); + nativeMenuItem.title = cocoaMenu->nsMenu().title; + nativeMenuItem.hidden = shouldHide; } NSMenuItem *QCocoaMenuBar::nativeItemForMenu(QCocoaMenu *menu) const diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index fa54c1e90ef4c0757523d6dde092eba973a227e6..64c460feb996a63cc6487afeaae1bd326dad4dd2 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -118,6 +118,8 @@ QCocoaMenuItem::~QCocoaMenuItem() if (m_merged) { [m_native setHidden:YES]; } else { + if (m_menu && m_menu->attachedItem() == m_native) + m_menu->setAttachedItem(nil); [m_native release]; } diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 4d5f5d74f2ae70c9d058fe53188a81581ef44b3e..d9e94735ac101349aa55b2c308a163591916d5e7 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -44,6 +44,7 @@ #include <qpa/qplatformwindow.h> #include <QRect> +#include <QPointer> #ifndef QT_NO_OPENGL #include "qcocoaglcontext.h" @@ -53,6 +54,32 @@ QT_FORWARD_DECLARE_CLASS(QCocoaWindow) +QT_BEGIN_NAMESPACE + +class QCocoaWindowPointer +{ +public: + void assign(QCocoaWindow *w); + void clear(); + + QCocoaWindow *data() const + { return watcher.isNull() ? Q_NULLPTR : window; } + bool isNull() const + { return watcher.isNull(); } + operator QCocoaWindow*() const + { return data(); } + QCocoaWindow *operator->() const + { return data(); } + QCocoaWindow &operator*() const + { return *data(); } + +private: + QPointer<QObject> watcher; + QCocoaWindow *window; +}; + +QT_END_NAMESPACE + @class QT_MANGLE_NAMESPACE(QNSWindowHelper); @protocol QNSWindowProtocol @@ -69,14 +96,13 @@ typedef NSWindow<QNSWindowProtocol> QCocoaNSWindow; @interface QT_MANGLE_NAMESPACE(QNSWindowHelper) : NSObject { QCocoaNSWindow *_window; - QCocoaWindow *_platformWindow; + QCocoaWindowPointer _platformWindow; BOOL _grabbingMouse; BOOL _releaseOnMouseUp; - QPointer<QObject> _watcher; } @property (nonatomic, readonly) QCocoaNSWindow *window; -@property (nonatomic, readonly) QCocoaWindow *platformWindow; +@property (nonatomic, readonly) QCocoaWindowPointer platformWindow; @property (nonatomic) BOOL grabbingMouse; @property (nonatomic) BOOL releaseOnMouseUp; @@ -260,7 +286,7 @@ public: // for QNSView NSView *m_contentView; QNSView *m_qtView; QCocoaNSWindow *m_nsWindow; - QCocoaWindow *m_forwardWindow; + QCocoaWindowPointer m_forwardWindow; // TODO merge to one variable if possible bool m_contentViewIsEmbedded; // true if the m_contentView is actually embedded in a "foreign" NSView hiearchy @@ -323,9 +349,8 @@ public: // for QNSView QHash<quintptr, BorderRange> m_contentBorderAreas; // identifer -> uppper/lower QHash<quintptr, bool> m_enabledContentBorderAreas; // identifer -> enabled state (true/false) - // This object is tracked by a 'watcher' - // object in a window helper, preventing use of dangling - // pointers. + // This object is tracked by QCocoaWindowPointer, + // preventing the use of dangling pointers. QObject sentinel; }; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 01e72303be4ba702115b78d587dc6e03b682d8f6..eaa01707489d23ad21a46a87545c0bbdf9b10c6e 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -90,7 +90,7 @@ static bool isMouseEvent(NSEvent *ev) self = [super init]; if (self) { _window = window; - _platformWindow = platformWindow; + _platformWindow.assign(platformWindow); _window.delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:_platformWindow]; @@ -99,7 +99,6 @@ static bool isMouseEvent(NSEvent *ev) // make sure that m_nsWindow stays valid until the // QCocoaWindow is deleted by Qt. [_window setReleasedWhenClosed:NO]; - _watcher = &_platformWindow->sentinel; } return self; @@ -108,19 +107,19 @@ static bool isMouseEvent(NSEvent *ev) - (void)handleWindowEvent:(NSEvent *)theEvent { QCocoaWindow *pw = self.platformWindow; - if (_watcher && pw && pw->m_forwardWindow) { + if (pw && pw->m_forwardWindow) { if (theEvent.type == NSLeftMouseUp || theEvent.type == NSLeftMouseDragged) { QNSView *forwardView = pw->m_qtView; if (theEvent.type == NSLeftMouseUp) { [forwardView mouseUp:theEvent]; - pw->m_forwardWindow = 0; + pw->m_forwardWindow.clear(); } else { [forwardView mouseDragged:theEvent]; } } if (!pw->m_isNSWindowChild && theEvent.type == NSLeftMouseDown) { - pw->m_forwardWindow = 0; + pw->m_forwardWindow.clear(); } } @@ -147,7 +146,7 @@ static bool isMouseEvent(NSEvent *ev) if (!self.window.delegate) return; // Already detached, pending NSAppKitDefined event - if (_watcher && pw && pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) { + if (pw && pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) { NSPoint loc = [theEvent locationInWindow]; NSRect windowFrame = [self.window convertRectFromScreen:[self.window frame]]; NSRect contentFrame = [[self.window contentView] frame]; @@ -162,8 +161,7 @@ static bool isMouseEvent(NSEvent *ev) - (void)detachFromPlatformWindow { - _platformWindow = 0; - _watcher.clear(); + self.platformWindow.clear(); [self.window.delegate release]; self.window.delegate = nil; } @@ -184,7 +182,7 @@ static bool isMouseEvent(NSEvent *ev) - (void)dealloc { _window = nil; - _platformWindow = 0; + self.platformWindow.clear(); [super dealloc]; } @@ -336,6 +334,18 @@ static bool isMouseEvent(NSEvent *ev) @end +void QCocoaWindowPointer::assign(QCocoaWindow *w) +{ + window = w; + watcher = &w->sentinel; +} + +void QCocoaWindowPointer::clear() +{ + window = Q_NULLPTR; + watcher.clear(); +} + const int QCocoaWindow::NoAlertRequest = -1; QCocoaWindow::QCocoaWindow(QWindow *tlw) @@ -343,7 +353,6 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_contentView(nil) , m_qtView(nil) , m_nsWindow(0) - , m_forwardWindow(0) , m_contentViewIsEmbedded(false) , m_contentViewIsToBeEmbedded(false) , m_parentCocoaWindow(0) @@ -1138,8 +1147,7 @@ bool QCocoaWindow::setKeyboardGrabEnabled(bool grab) if (grab && ![m_nsWindow isKeyWindow]) [m_nsWindow makeKeyWindow]; - else if (!grab && [m_nsWindow isKeyWindow]) - [m_nsWindow resignKeyWindow]; + return true; } @@ -1151,8 +1159,7 @@ bool QCocoaWindow::setMouseGrabEnabled(bool grab) if (grab && ![m_nsWindow isKeyWindow]) [m_nsWindow makeKeyWindow]; - else if (!grab && [m_nsWindow isKeyWindow]) - [m_nsWindow resignKeyWindow]; + return true; } @@ -1339,7 +1346,7 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow) if (oldParentCocoaWindow) { if (!m_isNSWindowChild || oldParentCocoaWindow != m_parentCocoaWindow) oldParentCocoaWindow->removeChildWindow(this); - m_forwardWindow = oldParentCocoaWindow; + m_forwardWindow.assign(oldParentCocoaWindow); } setNSWindow(m_nsWindow); diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 3115db2b836ed2e207087a9e5706c5a52743d041..5972cf95041ee2ab23733668283ec6e659d738a8 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -290,6 +290,7 @@ static bool _q_dontOverrideCtrlLMB = false; - (void)viewDidMoveToWindow { + m_backingStore = Q_NULLPTR; m_isMenuView = [self.window.className isEqualToString:@"NSCarbonMenuWindow"]; if (self.window) { // This is the case of QWidgetAction's generated QWidget inserted in an NSMenu. @@ -760,7 +761,7 @@ QT_WARNING_POP if (theEvent.type == NSLeftMouseDragged || theEvent.type == NSLeftMouseUp) targetView = m_platformWindow->m_forwardWindow->m_qtView; else - m_platformWindow->m_forwardWindow = 0; + m_platformWindow->m_forwardWindow.clear(); } // Popups implicitly grap mouse events; forward to the active popup if there is one diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp index d96c3964df93c5bafa90bc61c600f9912d9831ee..abff88b4bd8e0b3c958e65b9cbaf04e09311a49b 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp @@ -48,6 +48,7 @@ #include <QtCore/QJsonArray> #include <QtCore/QLoggingCategory> #include <QtGui/QPainter> +#include <QtGui/private/qguiapplication_p.h> #include <xf86drm.h> #include <xf86drmMode.h> @@ -69,13 +70,13 @@ QEglFSKmsGbmCursor::QEglFSKmsGbmCursor(QEglFSKmsGbmScreen *screen) , m_cursorSize(64, 64) // 64x64 is the old standard size, we now try to query the real size below , m_bo(Q_NULLPTR) , m_cursorImage(0, 0, 0, 0, 0, 0) - , m_visible(true) + , m_state(CursorPendingVisible) { QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR"); - if (!hideCursorVal.isEmpty()) - m_visible = hideCursorVal.toInt() == 0; - if (!m_visible) + if (!hideCursorVal.isEmpty() && hideCursorVal.toInt()) { + m_state = CursorDisabled; return; + } uint64_t width, height; if ((drmGetCap(m_screen->device()->fd(), DRM_CAP_CURSOR_WIDTH, &width) == 0) @@ -92,6 +93,12 @@ QEglFSKmsGbmCursor::QEglFSKmsGbmCursor(QEglFSKmsGbmScreen *screen) initCursorAtlas(); } + m_deviceListener = new QEglFSKmsGbmCursorDeviceListener(this); + connect(QGuiApplicationPrivate::inputDeviceManager(), &QInputDeviceManager::deviceListChanged, + m_deviceListener, &QEglFSKmsGbmCursorDeviceListener::onDeviceListChanged); + if (!m_deviceListener->hasMouse()) + m_state = CursorPendingHidden; + #ifndef QT_NO_CURSOR QCursor cursor(Qt::ArrowCursor); changeCursor(&cursor, 0); @@ -101,6 +108,8 @@ QEglFSKmsGbmCursor::QEglFSKmsGbmCursor(QEglFSKmsGbmScreen *screen) QEglFSKmsGbmCursor::~QEglFSKmsGbmCursor() { + delete m_deviceListener; + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen); drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); @@ -113,6 +122,31 @@ QEglFSKmsGbmCursor::~QEglFSKmsGbmCursor() } } +void QEglFSKmsGbmCursor::updateMouseStatus() +{ + const bool wasVisible = m_state == CursorVisible; + const bool visible = m_deviceListener->hasMouse(); + if (visible == wasVisible) + return; + + m_state = visible ? CursorPendingVisible : CursorPendingHidden; + +#ifndef QT_NO_CURSOR + changeCursor(nullptr, m_screen->topLevelAt(pos())); +#endif +} + +bool QEglFSKmsGbmCursorDeviceListener::hasMouse() const +{ + return QGuiApplicationPrivate::inputDeviceManager()->deviceCount(QInputDeviceManager::DeviceTypePointer) > 0; +} + +void QEglFSKmsGbmCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type) +{ + if (type == QInputDeviceManager::DeviceTypePointer) + m_cursor->updateMouseStatus(); +} + void QEglFSKmsGbmCursor::pointerEvent(const QMouseEvent &event) { setPos(event.screenPos().toPoint()); @@ -126,7 +160,15 @@ void QEglFSKmsGbmCursor::changeCursor(QCursor *windowCursor, QWindow *window) if (!m_bo) return; - if (!m_visible) + if (m_state == CursorPendingHidden) { + m_state = CursorHidden; + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { + QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen); + drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); + } + } + + if (m_state == CursorHidden || m_state == CursorDisabled) return; const Qt::CursorShape newShape = windowCursor ? windowCursor->shape() : Qt::ArrowCursor; @@ -166,6 +208,9 @@ void QEglFSKmsGbmCursor::changeCursor(QCursor *windowCursor, QWindow *window) uint32_t handle = gbm_bo_get_handle(m_bo).u32; + if (m_state == CursorPendingVisible) + m_state = CursorVisible; + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen); @@ -213,7 +258,7 @@ void QEglFSKmsGbmCursor::initCursorAtlas() drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0); } - m_visible = false; + m_state = CursorDisabled; return; } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h index c1e3706e91e886b6ae9c42ebd3f5046d6aa9bfbc..de13a058cf873049b668467616e0f809f5d2ec2d 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h @@ -43,12 +43,29 @@ #include <qpa/qplatformcursor.h> #include <QtCore/QList> #include <QtGui/QImage> +#include <QtGui/private/qinputdevicemanager_p.h> #include <gbm.h> QT_BEGIN_NAMESPACE class QEglFSKmsGbmScreen; +class QEglFSKmsGbmCursor; + +class QEglFSKmsGbmCursorDeviceListener : public QObject +{ + Q_OBJECT + +public: + QEglFSKmsGbmCursorDeviceListener(QEglFSKmsGbmCursor *cursor) : m_cursor(cursor) { } + bool hasMouse() const; + +public slots: + void onDeviceListChanged(QInputDeviceManager::DeviceType type); + +private: + QEglFSKmsGbmCursor *m_cursor; +}; class QEglFSKmsGbmCursor : public QPlatformCursor { @@ -66,15 +83,26 @@ public: QPoint pos() const Q_DECL_OVERRIDE; void setPos(const QPoint &pos) Q_DECL_OVERRIDE; + void updateMouseStatus(); + private: void initCursorAtlas(); + enum CursorState { + CursorDisabled, + CursorPendingHidden, + CursorHidden, + CursorPendingVisible, + CursorVisible + }; + QEglFSKmsGbmScreen *m_screen; QSize m_cursorSize; gbm_bo *m_bo; QPoint m_pos; QPlatformCursorImage m_cursorImage; - bool m_visible; + CursorState m_state; + QEglFSKmsGbmCursorDeviceListener *m_deviceListener; // cursor atlas information struct CursorAtlas { diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp index 229ac6bbd9051da31d09616c5380dc4bcb7747e8..6acb362bf0c22676e76c47ff49af941746c576a1 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp @@ -37,6 +37,7 @@ ** ****************************************************************************/ +#include "qeglfsglobal.h" #include <QtGui/QSurface> #include <QtPlatformSupport/private/qeglconvenience_p.h> #include <QtPlatformSupport/private/qeglpbuffer_p.h> diff --git a/src/plugins/platforms/eglfs/qeglfscontext.h b/src/plugins/platforms/eglfs/qeglfscontext.h index b861ae5329e98289072c00fbd6bd52a855e6a726..91c5a7910b9d98e7c5be77a5493ccd3a8da30de5 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.h +++ b/src/plugins/platforms/eglfs/qeglfscontext.h @@ -40,9 +40,9 @@ #ifndef QEGLFSCONTEXT_H #define QEGLFSCONTEXT_H +#include "qeglfsglobal.h" #include <QtPlatformSupport/private/qeglplatformcontext_p.h> #include <QtCore/QVariant> -#include "qeglfsglobal.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h index cbbf2551b70f6fd6d4bdfa4214578b6e9f782a1e..f1a5bde3310f960b3fa773a7eabf8d0e5da33ae4 100644 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h @@ -51,13 +51,12 @@ // We mean it. // +#include "qeglfsglobal.h" #include <qpa/qplatformintegration.h> #include <qpa/qplatformscreen.h> #include <QtCore/QString> #include <QtGui/QSurfaceFormat> #include <QtGui/QImage> -#include <EGL/egl.h> -#include "qeglfsglobal.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsglobal.h b/src/plugins/platforms/eglfs/qeglfsglobal.h index 8b6a391143ddd9c2dfe7b18629398d7c6ab23c07..d6aba565ce81b372ead290a4341de786bd7e6bfa 100644 --- a/src/plugins/platforms/eglfs/qeglfsglobal.h +++ b/src/plugins/platforms/eglfs/qeglfsglobal.h @@ -48,4 +48,17 @@ #define Q_EGLFS_EXPORT Q_DECL_IMPORT #endif +#include <EGL/egl.h> +#undef Status +#undef None +#undef Bool +#undef CursorShape +#undef KeyPress +#undef KeyRelease +#undef FocusIn +#undef FocusOut +#undef FontChange +#undef Expose +#undef Unsorted + #endif diff --git a/src/plugins/platforms/eglfs/qeglfshooks.h b/src/plugins/platforms/eglfs/qeglfshooks.h index 745c5d479c64b66c169f9fa5f43155207f6ee13b..cc6c325b58be4f3dc273b3b11efb3fac94e3ccd4 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks.h +++ b/src/plugins/platforms/eglfs/qeglfshooks.h @@ -40,8 +40,8 @@ #ifndef QEGLFSHOOKS_H #define QEGLFSHOOKS_H -#include "qeglfsdeviceintegration.h" #include "qeglfsglobal.h" +#include "qeglfsdeviceintegration.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 29e3c5e5601b8b4052b2e37619aec83006caaa8c..6f38a96f451f869bce3b09ba37d54b7f2ff7f5bb 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -86,8 +86,6 @@ #include <QtPlatformHeaders/qeglfsfunctions.h> -#include <EGL/egl.h> - static void initResources() { #ifndef QT_NO_CURSOR diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h index e06d7e887662dfdbcd110a66ed7f07ff52712738..678452a8db0d9dbe89812d3ec341ff0ecf553042 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsintegration.h @@ -40,12 +40,11 @@ #ifndef QEGLFSINTEGRATION_H #define QEGLFSINTEGRATION_H +#include "qeglfsglobal.h" #include <QtCore/QVariant> #include <qpa/qplatformintegration.h> #include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformscreen.h> -#include <EGL/egl.h> -#include "qeglfsglobal.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.h b/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.h index 6f808d8a102a62c8f514ce0e7fe3a52db63e2f76..673fa0d7297ea50121e3062b8b51bc010a611991 100644 --- a/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.h +++ b/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.h @@ -40,9 +40,8 @@ #ifndef QEGLFSOFFSCREENWINDOW_H #define QEGLFSOFFSCREENWINDOW_H -#include <EGL/egl.h> -#include <qpa/qplatformoffscreensurface.h> #include "qeglfsglobal.h" +#include <qpa/qplatformoffscreensurface.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h index b388885186be77e299161766fd2dbd50f6361cb4..57d68ca5720bda87787a46a93944236a9571dba1 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.h +++ b/src/plugins/platforms/eglfs/qeglfsscreen.h @@ -42,7 +42,6 @@ #include "qeglfsglobal.h" #include <QtCore/QPointer> -#include <EGL/egl.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h index 621890b06020012c29001cdfed4ffe4900e947c9..d607c8bd622e969140e6426dba67283b29512c2a 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.h +++ b/src/plugins/platforms/eglfs/qeglfswindow.h @@ -40,13 +40,12 @@ #ifndef QEGLFSWINDOW_H #define QEGLFSWINDOW_H +#include "qeglfsglobal.h" #include "qeglfsintegration.h" #include "qeglfsscreen.h" -#include "qeglfsglobal.h" #include <qpa/qplatformwindow.h> #include <QtPlatformSupport/private/qopenglcompositor_p.h> -#include <EGL/egl.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp index 321e124eee160407fbc7293809e51a874db85d3d..1fd2b84e3717006f977a02b1ada3c95222d920c3 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp @@ -412,9 +412,12 @@ QRegion QLinuxFbScreen::doRedraw() if (!mBlitter) mBlitter = new QPainter(&mFbScreenImage); - QVector<QRect> rects = touched.rects(); - for (int i = 0; i < rects.size(); i++) + const QVector<QRect> rects = touched.rects(); + mBlitter->setCompositionMode(QPainter::CompositionMode_Source); + + for (int i = 0; i < rects.size(); ++i) mBlitter->drawImage(rects[i], *mScreenImage, rects[i]); + return touched; } diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index 5fb06a6ed158de39bb20c959175e8ff692d20a69..0e2165cdcb4713630da4ff08b26397fc79cea0ae 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -504,7 +504,8 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accHitTest(long xLeft, long yT if (!accessible) return E_FAIL; - const QPoint pos = QHighDpi::fromNativeLocalPosition(QPoint(xLeft, yTop), accessible->window()); + const QPoint pos = QHighDpi::fromNativeLocalPosition(QPoint(xLeft, yTop), + QWindowsAccessibility::windowHelper(accessible)); QAccessibleInterface *child = accessible->childAt(pos.x(), pos.y()); if (child == 0) { // no child found, return this item if it contains the coordinates @@ -547,7 +548,8 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accLocation(long *pxLeft, long QAccessibleInterface *acc = childPointer(accessible, varID); if (!acc || !acc->isValid()) return E_FAIL; - const QRect rect = QHighDpi::toNativePixels(acc->rect(), accessible->window()); + const QRect rect = QHighDpi::toNativePixels(acc->rect(), + QWindowsAccessibility::windowHelper(accessible)); *pxLeft = rect.x(); *pyTop = rect.y(); diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json index f7a88446111b15634b6eb27b6fa2c15d5223beb1..1e00da52eb3f0a72cf51814b1c3de9fabf5a93c2 100644 --- a/src/plugins/platforms/windows/openglblacklists/default.json +++ b/src/plugins/platforms/windows/openglblacklists/default.json @@ -90,6 +90,18 @@ "features": [ "disable_angle" ] + }, + { + "id": 8, + "description": "Standard VGA: Insufficent support for OpenGL, D3D9 and D3D11", + "vendor_id": "0x0000", + "device_id": ["0x0000"], + "os": { + "type": "win" + }, + "features": [ + "disable_desktopgl", "disable_d3d11", "disable_d3d9" + ] } ] } diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index b524adb2cb317fa959057288915e56eda86f3bbf..7419118878f9fe5b5228798c8d6d9704fcf9cf25 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -146,7 +146,8 @@ struct QWindowsIntegrationPrivate # endif #endif #ifndef QT_NO_OPENGL - QSharedPointer<QWindowsStaticOpenGLContext> m_staticOpenGLContext; + QMutex m_staticContextLock; + QScopedPointer<QWindowsStaticOpenGLContext> m_staticOpenGLContext; #endif // QT_NO_OPENGL QScopedPointer<QPlatformInputContext> m_inputContext; #ifndef QT_NO_ACCESSIBILITY @@ -464,8 +465,9 @@ QWindowsStaticOpenGLContext *QWindowsIntegration::staticOpenGLContext() if (!integration) return 0; QWindowsIntegrationPrivate *d = integration->d.data(); + QMutexLocker lock(&d->m_staticContextLock); if (d->m_staticOpenGLContext.isNull()) - d->m_staticOpenGLContext = QSharedPointer<QWindowsStaticOpenGLContext>(QWindowsStaticOpenGLContext::create()); + d->m_staticOpenGLContext.reset(QWindowsStaticOpenGLContext::create()); return d->m_staticOpenGLContext.data(); } #endif // !QT_NO_OPENGL diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index f4dbd10a49416deb21fb3b8566386c2b86831573..48c53592d69370ff5708b2ad896be0b1c49ea1ae 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -126,6 +126,7 @@ contains(QT_CONFIG, freetype) { SOURCES += \ $$PWD/qwindowsfontdatabase_ft.cpp } else:contains(QT_CONFIG, system-freetype) { + CONFIG += qpa/basicunixfontdatabase include($$QT_SOURCE_TREE/src/platformsupport/fontdatabases/basic/basic.pri) HEADERS += \ $$PWD/qwindowsfontdatabase_ft.h diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index 3cae53d0a039715ad3417d77be995b6faaad1130..a910967f87c58fe773c44ca746a6a428e3cff816 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -110,9 +110,6 @@ QWinRTWindow::QWinRTWindow(QWindow *window) d->surface = EGL_NO_SURFACE; d->display = EGL_NO_DISPLAY; d->screen = static_cast<QWinRTScreen *>(screen()); - setWindowFlags(window->flags()); - setWindowState(window->windowState()); - setWindowTitle(window->title()); handleContentOrientationChange(window->contentOrientation()); d->surfaceFormat.setAlphaBufferSize(0); @@ -160,6 +157,10 @@ QWinRTWindow::QWinRTWindow(QWindow *window) }); Q_ASSERT_SUCCEEDED(hr); + setWindowFlags(window->flags()); + setWindowState(window->windowState()); + setWindowTitle(window->title()); + setGeometry(window->geometry()); } diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 87b4c7b91f215685ea6ab067ff55df394d4ccc8c..4b0e94eda03ae713ffd91e6a3dbb38efa2972aed 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1713,7 +1713,8 @@ void QXcbConnection::processXcbEvents() continue; } - if (compressEvent(event, i, eventqueue)) + if (Q_LIKELY(QCoreApplication::testAttribute(Qt::AA_CompressHighFrequencyEvents)) && + compressEvent(event, i, eventqueue)) continue; bool accepted = false; diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index b55fbd8f03ba677f4a4454be3569dacebb9f7d5e..fb006ec0f18963cb2672501ef97221f0d2e3250b 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -56,6 +56,7 @@ #include <qpa/qwindowsysteminterface.h> +#include <private/qguiapplication_p.h> #include <private/qshapedpixmapdndwindow_p.h> #include <private/qsimpledrag_p.h> #include <private/qhighdpiscaling_p.h> @@ -176,6 +177,17 @@ QMimeData *QXcbDrag::platformDropData() return dropData; } +bool QXcbDrag::eventFilter(QObject *o, QEvent *e) +{ + /* We are setting a mouse grab on the QShapedPixmapWindow in order not to + * lose the grab when the virtual desktop changes, but + * QBasicDrag::eventFilter() expects the events to be coming from the + * window where the drag was started. */ + if (initiatorWindow && o == shapedPixmapWindow()) + o = initiatorWindow.data(); + return QBasicDrag::eventFilter(o, e); +} + void QXcbDrag::startDrag() { // #fixme enableEventFilter(); @@ -200,6 +212,7 @@ void QXcbDrag::startDrag() setUseCompositing(current_virtual_desktop->compositingActive()); setScreen(current_virtual_desktop->screens().constFirst()->screen()); + initiatorWindow = QGuiApplicationPrivate::currentMouseWindow; QBasicDrag::startDrag(); if (connection()->mouseGrabber() == Q_NULLPTR) shapedPixmapWindow()->setMouseGrabEnabled(true); @@ -208,6 +221,7 @@ void QXcbDrag::startDrag() void QXcbDrag::endDrag() { QBasicDrag::endDrag(); + initiatorWindow.clear(); } static xcb_translate_coordinates_reply_t * @@ -821,7 +835,7 @@ void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event) DEBUG("xdndHandleStatus"); waiting_for_status = false; // ignore late status messages - if (event->data.data32[0] && event->data.data32[0] != current_proxy_target) + if (event->data.data32[0] && event->data.data32[0] != current_target) return; const bool dropPossible = event->data.data32[1]; diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h index 7eac6cbbe0b937d9050082da238e048d86ce4320..f65dbda05d1d98073d442be682e18f5d5dfd8fa7 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.h +++ b/src/plugins/platforms/xcb/qxcbdrag.h @@ -75,6 +75,7 @@ public: ~QXcbDrag(); virtual QMimeData *platformDropData() Q_DECL_OVERRIDE; + bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE; void startDrag() Q_DECL_OVERRIDE; void cancel() Q_DECL_OVERRIDE; @@ -112,6 +113,7 @@ private: Qt::DropAction toDropAction(xcb_atom_t atom) const; xcb_atom_t toXdndAction(Qt::DropAction a) const; + QPointer<QWindow> initiatorWindow; QPointer<QWindow> currentWindow; QPoint currentPosition; diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 703167c0cd2c4a15c8ddd1cede81b8757480196f..cdbf9b295e10cfb9c676a2c49b958fe3f9c4f601 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -125,6 +125,7 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char , m_defaultVisualId(UINT_MAX) { m_instance = this; + qApp->setAttribute(Qt::AA_CompressHighFrequencyEvents, true); qRegisterMetaType<QXcbWindow*>(); #ifdef XCB_USE_XLIB diff --git a/src/plugins/platforms/xcb/qxcbmime.cpp b/src/plugins/platforms/xcb/qxcbmime.cpp index a4a99ece64e62744d6f1ad73d0887e531ea353b5..825a8acd1f0f99d0d33877023b741025063a5b3c 100644 --- a/src/plugins/platforms/xcb/qxcbmime.cpp +++ b/src/plugins/platforms/xcb/qxcbmime.cpp @@ -117,17 +117,18 @@ bool QXcbMime::mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeDa QString atomName = mimeAtomToString(connection, a); if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) { *data = QInternalMimeData::renderDataHelper(atomName, mimeData); - if (atomName == QLatin1String("application/x-color")) + // mimeAtomToString() converts "text/x-moz-url" to "text/uri-list", + // so QXcbConnection::atomName() has to be used. + if (atomName == QLatin1String("text/uri-list") + && connection->atomName(a) == "text/x-moz-url") { + const QByteArray uri = data->split('\n').first(); + QString mozUri = QString::fromLatin1(uri, uri.size()); + mozUri += QLatin1Char('\n'); + *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), + mozUri.length() * 2); + } else if (atomName == QLatin1String("application/x-color")) *dataFormat = 16; ret = true; - } else if (atomName == QLatin1String("text/x-moz-url") && - QInternalMimeData::hasFormatHelper(QLatin1String("text/uri-list"), mimeData)) { - QByteArray uri = QInternalMimeData::renderDataHelper( - QLatin1String("text/uri-list"), mimeData).split('\n').first(); - QString mozUri = QString::fromLatin1(uri, uri.size()); - mozUri += QLatin1Char('\n'); - *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), mozUri.length() * 2); - ret = true; } else if ((a == XCB_ATOM_PIXMAP || a == XCB_ATOM_BITMAP) && mimeData->hasImage()) { ret = true; } @@ -188,17 +189,37 @@ QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, a == connection->atom(QXcbAtom::TEXT)) return QString::fromLatin1(data); } - - // special case for uri types - if (format == QLatin1String("text/uri-list")) { - if (atomName == QLatin1String("text/x-moz-url")) { - // we expect this as utf16 <url><space><title> - // the first part is a url that should only contain ascci char - // so it should be safe to check that the second char is 0 - // to verify that it is utf16 - if (data.size() > 1 && data.at(1) == 0) - return QString::fromRawData((const QChar *)data.constData(), - data.size() / 2).split(QLatin1Char('\n')).first().toLatin1(); + // If data contains UTF16 text, convert it to a string. + // Firefox uses UTF16 without BOM for text/x-moz-url, "text/html", + // Google Chrome uses UTF16 without BOM for "text/x-moz-url", + // UTF16 with BOM for "text/html". + if ((format == QLatin1String("text/html") || format == QLatin1String("text/uri-list")) + && data.size() > 1) { + const quint8 byte0 = data.at(0); + const quint8 byte1 = data.at(1); + if ((byte0 == 0xff && byte1 == 0xfe) || (byte0 == 0xfe && byte1 == 0xff) + || (byte0 != 0 && byte1 == 0) || (byte0 == 0 && byte1 != 0)) { + const QString str = QString::fromUtf16( + reinterpret_cast<const ushort *>(data.constData()), data.size() / 2); + if (!str.isNull()) { + if (format == QLatin1String("text/uri-list")) { + const QStringList urls = str.split(QLatin1Char('\n')); + QList<QVariant> list; + foreach (const QString &s, urls) { + const QUrl url(s.trimmed()); + if (url.isValid()) + list.append(url); + } + // We expect "text/x-moz-url" as <url><space><title>. + // The atomName variable is not used because mimeAtomToString() + // converts "text/x-moz-url" to "text/uri-list". + if (!list.isEmpty() && connection->atomName(a) == "text/x-moz-url") + return list.first(); + return list; + } else { + return str; + } + } } } diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 2c0f1f26b02ed51519e7e33f8945120561c346a4..82ef8cc4df99989f9e87a59f729a8899e08b19d2 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2336,9 +2336,14 @@ void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, i QPoint local(event_x, event_y); QPoint global(root_x, root_y); - // "mousePressWindow" can be NULL i.e. if a window will be grabbed or umnapped, so set it again here - if (connection()->buttons() != Qt::NoButton && connection()->mousePressWindow() == Q_NULLPTR) + // "mousePressWindow" can be NULL i.e. if a window will be grabbed or unmapped, so set it again here. + // Unset "mousePressWindow" when mouse button isn't pressed - in some cases the release event won't arrive. + const bool isMouseButtonPressed = (connection()->buttons() != Qt::NoButton); + const bool hasMousePressWindow = (connection()->mousePressWindow() != Q_NULLPTR); + if (isMouseButtonPressed && !hasMousePressWindow) connection()->setMousePressWindow(this); + else if (hasMousePressWindow && !isMouseButtonPressed) + connection()->setMousePressWindow(Q_NULLPTR); handleMouseEvent(timestamp, local, global, modifiers, source); } diff --git a/src/printsupport/doc/qtprintsupport.qdocconf b/src/printsupport/doc/qtprintsupport.qdocconf index d8fbc23c0a16a3db6ec9ac409e726d6bdcc62dc2..fbb6f8d1a9847592eb63ff441524e76767af10bc 100644 --- a/src/printsupport/doc/qtprintsupport.qdocconf +++ b/src/printsupport/doc/qtprintsupport.qdocconf @@ -4,7 +4,7 @@ project = QtPrintSupport description = Qt Print Support Reference Documentation version = $QT_VERSION -examplesinstallpath = qtbase/printsupport +examplesinstallpath = printsupport qhp.projects = QtPrintSupport diff --git a/src/sql/doc/qtsql.qdocconf b/src/sql/doc/qtsql.qdocconf index ceaa75f45537a8b36b250619b593cab4095507f2..5a224adeb9667e189e236b32856f4581198f8698 100644 --- a/src/sql/doc/qtsql.qdocconf +++ b/src/sql/doc/qtsql.qdocconf @@ -4,7 +4,7 @@ project = QtSql description = Qt SQL Reference Documentation version = $QT_VERSION -examplesinstallpath = qtbase/sql +examplesinstallpath = sql qhp.projects = QtSql diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 0bc86494f95504419c0845c2030a463817bc92ff..9932fb75e3ea7a29d8dbeee1fc102a694564ee52 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -500,7 +500,7 @@ QVariant QSqlTableModel::headerData(int section, Qt::Orientation orientation, in \since 5.0 Returns \c true if the model contains modified values that have not been - committed to the datase, otherwise false. + committed to the database, otherwise false. */ bool QSqlTableModel::isDirty() const { diff --git a/src/src.pro b/src/src.pro index 4a165a2dab4e0557435490d72bfd6fc4ac7e984a..71347dc009c2117693aad793ca67f32968efc5aa 100644 --- a/src/src.pro +++ b/src/src.pro @@ -129,7 +129,12 @@ src_plugins.depends = src_sql src_xml src_network src_android.subdir = $$PWD/android # this order is important -contains(QT_CONFIG, zlib)|cross_compile: SUBDIRS += src_qtzlib +contains(QT_CONFIG, zlib)|cross_compile { + SUBDIRS += src_qtzlib + contains(QT_CONFIG, zlib) { + src_3rdparty_freetype.depends += src_corelib + } +} SUBDIRS += src_tools_bootstrap src_tools_moc src_tools_rcc !contains(QT_DISABLED_FEATURES, regularexpression):pcre { SUBDIRS += src_3rdparty_pcre @@ -140,7 +145,8 @@ TOOLS = src_tools_moc src_tools_rcc src_tools_qlalr win32:SUBDIRS += src_winmain SUBDIRS += src_network src_sql src_xml src_testlib contains(QT_CONFIG, dbus) { - force_bootstrap: SUBDIRS += src_tools_bootstrap_dbus + force_bootstrap|contains(QT_CONFIG, private_tests): \ + SUBDIRS += src_tools_bootstrap_dbus SUBDIRS += src_dbus src_tools_qdbusxml2cpp src_tools_qdbuscpp2xml TOOLS += src_tools_qdbusxml2cpp src_tools_qdbuscpp2xml contains(QT_CONFIG, accessibility-atspi-bridge): \ diff --git a/src/testlib/doc/qttestlib.qdocconf b/src/testlib/doc/qttestlib.qdocconf index 72db51b925459661e91532b2529c833190914618..0fafc733b18cdce3acb7a9cbacab2c9928f7b716 100644 --- a/src/testlib/doc/qttestlib.qdocconf +++ b/src/testlib/doc/qttestlib.qdocconf @@ -4,7 +4,7 @@ project = QtTestLib description = Qt Test Reference Documentation version = $QT_VERSION -examplesinstallpath = qtbase/testlib +examplesinstallpath = testlib qhp.projects = QtTestLib diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index a27f7820f9254aa5d23a3b188f90e7aae1beefef..83ecaab8dfc8f336a1099e8efaeecbf70b8ac82b 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -244,7 +244,7 @@ namespace QTest inline typename QtPrivate::QEnableIf<QtPrivate::IsQEnumHelper<T>::Value, char*>::Type toString(T e) { QMetaEnum me = QMetaEnum::fromType<T>(); - return qstrdup(me.key(int(e))); // int cast is necessary to support enum classes + return qstrdup(me.valueToKey(int(e))); // int cast is necessary to support enum classes } template <typename T> // Fallback diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 5fbabe8fe49afa8d442c1789be555b352ac8c2a1..a43105297f9abd0415b1a3f5fce6ab7077c24ebe 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -134,8 +134,12 @@ macx { ../../corelib/io/qstandardpaths_win.cpp } -if(contains(QT_CONFIG, zlib)|cross_compile):include(../../3rdparty/zlib.pri) -else:include(../../3rdparty/zlib_dependency.pri) +contains(QT_CONFIG, zlib)|cross_compile { + include(../../3rdparty/zlib.pri) +} else { + CONFIG += no_core_dep + include(../../3rdparty/zlib_dependency.pri) +} win32:LIBS += -luser32 -lole32 -ladvapi32 -lshell32 diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index eb365b293c85177ca4da893c200800486b342f08..f2efcadad769c4be3e71d1caf1991d400313f1c7 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -373,8 +373,8 @@ bool Moc::parseFunction(FunctionDef *def, bool inMacro) def->isVirtual = false; def->isStatic = false; //skip modifiers and attributes - while (test(INLINE) || (test(STATIC) && (def->isStatic = true)) || - (test(VIRTUAL) && (def->isVirtual = true)) //mark as virtual + while (test(INLINE) || (test(STATIC) && (def->isStatic = true) == true) || + (test(VIRTUAL) && (def->isVirtual = true) == true) //mark as virtual || testFunctionAttribute(def) || testFunctionRevision(def)) {} bool templateFunction = (lookup() == TEMPLATE); def->type = parseType(); @@ -467,8 +467,8 @@ bool Moc::parseMaybeFunction(const ClassDef *cdef, FunctionDef *def) def->isVirtual = false; def->isStatic = false; //skip modifiers and attributes - while (test(EXPLICIT) || test(INLINE) || (test(STATIC) && (def->isStatic = true)) || - (test(VIRTUAL) && (def->isVirtual = true)) //mark as virtual + while (test(EXPLICIT) || test(INLINE) || (test(STATIC) && (def->isStatic = true) == true) || + (test(VIRTUAL) && (def->isVirtual = true) == true) //mark as virtual || testFunctionAttribute(def) || testFunctionRevision(def)) {} bool tilde = test(TILDE); def->type = parseType(); diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index 59611ca5978bfc9c15e86c6741aae2e9e3fb3919..6ae785f4173cd31b93bc12f02d1299cd1e299f45 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE static QByteArray cleaned(const QByteArray &input) { QByteArray result; - result.reserve(input.size()); + result.resize(input.size()); const char *data = input.constData(); const char *end = input.constData() + input.size(); char *output = result.data(); @@ -73,13 +73,15 @@ static QByteArray cleaned(const QByteArray &input) if (data != end && (*(data + 1) == '\n' || (*data) == '\r')) { ++newlines; data += 1; - if (*data != '\r') + if (data != end && *data != '\r') data += 1; continue; } } else if (*data == '\r' && *(data + 1) == '\n') { // reduce \r\n to \n ++data; } + if (data == end) + break; char ch = *data; if (ch == '\r') // os9: replace \r with \n diff --git a/src/widgets/accessible/qaccessiblemenu.cpp b/src/widgets/accessible/qaccessiblemenu.cpp index 5b10c6d6c6ecd0b4f0fe0c2ed294c658e6b020b7..4a684e01f9635d0ee368f19db752c9b0dcaa9c88 100644 --- a/src/widgets/accessible/qaccessiblemenu.cpp +++ b/src/widgets/accessible/qaccessiblemenu.cpp @@ -231,6 +231,20 @@ QObject *QAccessibleMenuItem::object() const return m_action; } +/*! \reimp */ +QWindow *QAccessibleMenuItem::window() const +{ + QWindow *result = Q_NULLPTR; + if (!m_owner.isNull()) { + result = m_owner->windowHandle(); + if (!result) { + if (const QWidget *nativeParent = m_owner->nativeParentWidget()) + result = nativeParent->windowHandle(); + } + } + return result; +} + QRect QAccessibleMenuItem::rect() const { QRect rect; diff --git a/src/widgets/accessible/qaccessiblemenu_p.h b/src/widgets/accessible/qaccessiblemenu_p.h index e9dc851ab3615b479bde6104120653f7642e987a..5a5a4a3222190aa2a40d29b7ca8481dc0778f9be 100644 --- a/src/widgets/accessible/qaccessiblemenu_p.h +++ b/src/widgets/accessible/qaccessiblemenu_p.h @@ -114,6 +114,8 @@ public: QAccessibleInterface *parent() const Q_DECL_OVERRIDE; QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; QObject * object() const Q_DECL_OVERRIDE; + QWindow *window() const Q_DECL_OVERRIDE; + QRect rect() const Q_DECL_OVERRIDE; QAccessible::Role role() const Q_DECL_OVERRIDE; void setText(QAccessible::Text t, const QString & text) Q_DECL_OVERRIDE; diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index 901fd7e2017f741d5e6b224888e73e62d5397c7c..5096c1ff37fdaafa744782d94834a7eb96440306 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -210,8 +210,14 @@ bool QAccessibleWidget::isValid() const /*! \reimp */ QWindow *QAccessibleWidget::window() const { - Q_ASSERT(widget()); - return widget()->windowHandle(); + const QWidget *w = widget(); + Q_ASSERT(w); + QWindow *result = w->windowHandle(); + if (!result) { + if (const QWidget *nativeParent = w->nativeParentWidget()) + result = nativeParent->windowHandle(); + } + return result; } /*! diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 98f1f4870d9609eb2336d5578f8668a4b42c7962..04ef82f49d359a0656ae90aec96a8a075c8f14c7 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -174,8 +174,6 @@ private: namespace { -struct QWellArrayData; - class QWellArray : public QWidget { Q_OBJECT @@ -195,8 +193,6 @@ public: QSize sizeHint() const Q_DECL_OVERRIDE; - virtual void setCellBrush(int row, int col, const QBrush &); - inline int cellWidth() const { return cellw; } @@ -263,7 +259,6 @@ private: int curCol; int selRow; int selCol; - QWellArrayData *d; }; void QWellArray::paintEvent(QPaintEvent *e) @@ -313,15 +308,10 @@ void QWellArray::paintEvent(QPaintEvent *e) } } -struct QWellArrayData { - QBrush *brush; -}; - QWellArray::QWellArray(int rows, int cols, QWidget *parent) : QWidget(parent) ,nrows(rows), ncols(cols) { - d = 0; setFocusPolicy(Qt::StrongFocus); cellw = 28; cellh = 24; @@ -370,14 +360,12 @@ void QWellArray::paintCell(QPainter* p, int row, int col, const QRect &rect) */ void QWellArray::paintCellContents(QPainter *p, int row, int col, const QRect &r) { - if (d) { - p->fillRect(r, d->brush[row*numCols()+col]); - } else { - p->fillRect(r, Qt::white); - p->setPen(Qt::black); - p->drawLine(r.topLeft(), r.bottomRight()); - p->drawLine(r.topRight(), r.bottomLeft()); - } + Q_UNUSED(row); + Q_UNUSED(col); + p->fillRect(r, Qt::white); + p->setPen(Qt::black); + p->drawLine(r.topLeft(), r.bottomRight()); + p->drawLine(r.topRight(), r.bottomLeft()); } void QWellArray::mousePressEvent(QMouseEvent *e) @@ -453,17 +441,6 @@ void QWellArray::focusInEvent(QFocusEvent*) emit currentChanged(curRow, curCol); } -void QWellArray::setCellBrush(int row, int col, const QBrush &b) -{ - if (!d) { - d = new QWellArrayData; - int i = numRows()*numCols(); - d->brush = new QBrush[i]; - } - if (row >= 0 && row < numRows() && col >= 0 && col < numCols()) - d->brush[row*numCols()+col] = b; -} - /*!\reimp */ diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index f639be809c3705d8e6a10e89fc9037c9d67e0111..81c8fbe229ec7c68e1ef8025550e35ff06512af5 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -372,6 +372,9 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS ) return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); QModelIndex index = QModelIndex(); // start with "My Computer" + QString elementPath; + QChar separator = QLatin1Char('/'); + QString trailingSeparator; #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) if (absolutePath.startsWith(QLatin1String("//"))) { // UNC path QString host = QLatin1String("\\\\") + pathElements.constFirst(); @@ -379,6 +382,8 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS absolutePath.append(QLatin1Char('/')); if (longPath.endsWith(QLatin1Char('/')) && !absolutePath.endsWith(QLatin1Char('/'))) absolutePath.append(QLatin1Char('/')); + if (absolutePath.endsWith(QLatin1Char('/'))) + trailingSeparator = QLatin1String("\\"); int r = 0; QFileSystemModelPrivate::QFileSystemNode *rootNode = const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); if (!root.children.contains(host.toLower())) { @@ -395,11 +400,10 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS r = translateVisibleLocation(rootNode, r); index = q->index(r, 0, QModelIndex()); pathElements.pop_front(); - } else -#endif - -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) - { + separator = QLatin1Char('\\'); + elementPath = host; + elementPath.append(separator); + } else { if (!pathElements.at(0).contains(QLatin1Char(':'))) { QString rootPath = QDir(longPath).rootPath(); pathElements.prepend(rootPath); @@ -417,6 +421,11 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS for (int i = 0; i < pathElements.count(); ++i) { QString element = pathElements.at(i); + if (i != 0) + elementPath.append(separator); + elementPath.append(element); + if (i == pathElements.count() - 1) + elementPath.append(trailingSeparator); #ifdef Q_OS_WIN // On Windows, "filename " and "filename" are equivalent and // "filename . " and "filename" are equivalent @@ -448,7 +457,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS if (!alreadyExisted) { // Someone might call ::index("file://cookie/monster/doesn't/like/veggies"), // a path that doesn't exists, I.E. don't blindly create directories. - QFileInfo info(absolutePath); + QFileInfo info(elementPath); if (!info.exists()) return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); QFileSystemModelPrivate *p = const_cast<QFileSystemModelPrivate*>(this); diff --git a/src/widgets/doc/qtwidgets.qdocconf b/src/widgets/doc/qtwidgets.qdocconf index 75bbb99579bb8aecef37071db7c8e6c0c1f2905f..d0cf9671b128de5d96caef54e8b2bfc5c3cd3e69 100644 --- a/src/widgets/doc/qtwidgets.qdocconf +++ b/src/widgets/doc/qtwidgets.qdocconf @@ -4,7 +4,7 @@ project = QtWidgets description = Qt Widgets Reference Documentation version = $QT_VERSION -examplesinstallpath = qtbase/widgets +examplesinstallpath = widgets qhp.projects = QtWidgets diff --git a/src/widgets/doc/src/widgets-and-layouts/widgets.qdoc b/src/widgets/doc/src/widgets-and-layouts/widgets.qdoc index abd6ddd5fb0d2c5a98978886855493070c7c9627..1e99030e7a83fc5cd62f0fc87c12e9e204cb09be 100644 --- a/src/widgets/doc/src/widgets-and-layouts/widgets.qdoc +++ b/src/widgets/doc/src/widgets-and-layouts/widgets.qdoc @@ -43,11 +43,11 @@ \table \row - \li \image gtk-label.png + \li \image fusion-label.png \li \image windowsvista-pushbutton.png \li \image macintosh-progressbar.png \row - \li \image gtk-combobox.png + \li \image fusion-combobox.png \li \image windowsvista-radiobutton.png \li \image macintosh-lineedit.png \endtable @@ -69,7 +69,7 @@ \table \row \li \image windowsxp-treeview.png - \li \image gtk-calendarwidget.png + \li \image fusion-calendarwidget.png \li \image qundoview.png \endtable diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index e045d60fc888c178095bddc17f8aade775b93409..eebd0de9bbe815e3f21ffb092afa5e5c9cb23e7f 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -3248,13 +3248,12 @@ void QTableViewPrivate::selectRow(int row, bool anchor) command |= QItemSelectionModel::Current; } - QModelIndex tl = model->index(qMin(rowSectionAnchor, row), logicalColumn(0), root); - QModelIndex br = model->index(qMax(rowSectionAnchor, row), logicalColumn(model->columnCount(root) - 1), root); - if ((verticalHeader->sectionsMoved() && tl.row() != br.row()) - || horizontalHeader->sectionsMoved()) { - q->setSelection(q->visualRect(tl)|q->visualRect(br), command); + QModelIndex upper = model->index(qMin(rowSectionAnchor, row), column, root); + QModelIndex lower = model->index(qMax(rowSectionAnchor, row), column, root); + if ((verticalHeader->sectionsMoved() && upper.row() != lower.row())) { + q->setSelection(q->visualRect(upper) | q->visualRect(lower), command | QItemSelectionModel::Rows); } else { - selectionModel->select(QItemSelection(tl, br), command); + selectionModel->select(QItemSelection(upper, lower), command | QItemSelectionModel::Rows); } } } @@ -3288,14 +3287,12 @@ void QTableViewPrivate::selectColumn(int column, bool anchor) command |= QItemSelectionModel::Current; } - QModelIndex tl = model->index(logicalRow(0), qMin(columnSectionAnchor, column), root); - QModelIndex br = model->index(logicalRow(model->rowCount(root) - 1), - qMax(columnSectionAnchor, column), root); - if ((horizontalHeader->sectionsMoved() && tl.column() != br.column()) - || verticalHeader->sectionsMoved()) { - q->setSelection(q->visualRect(tl)|q->visualRect(br), command); + QModelIndex left = model->index(row, qMin(columnSectionAnchor, column), root); + QModelIndex right = model->index(row, qMax(columnSectionAnchor, column), root); + if ((horizontalHeader->sectionsMoved() && left.column() != right.column())) { + q->setSelection(q->visualRect(left) | q->visualRect(right), command | QItemSelectionModel::Columns); } else { - selectionModel->select(QItemSelection(tl, br), command); + selectionModel->select(QItemSelection(left, right), command | QItemSelectionModel::Columns); } } } diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 936da0414c648c24144fd5da9f190348d293a524..86b3282124c0a5c0ab29d631830e198ca4a7f003 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -2251,10 +2251,10 @@ void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous) QApplication::setActiveWindow(tlw); // QTBUG-37126, Active X controls may set the focus on native child widgets. if (wnd && tlw && wnd != tlw->windowHandle()) { - if (QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(wnd)) { - if (widgetWindow->widget()->inherits("QAxHostWidget")) - widgetWindow->widget()->setFocus(Qt::ActiveWindowFocusReason); - } + if (QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(wnd)) + if (QWidget *widget = widgetWindow->widget()) + if (widget->inherits("QAxHostWidget")) + widget->setFocus(Qt::ActiveWindowFocusReason); } } diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp index 8af3516d4bcd6c6b4cd35414efbe375d7a838461..df72c6c4d239ac7b93592e5d7bca7adcc954946d 100644 --- a/src/widgets/kernel/qgesturemanager.cpp +++ b/src/widgets/kernel/qgesturemanager.cpp @@ -552,7 +552,7 @@ bool QGestureManager::filterEvent(QObject *receiver, QEvent *event) // filter method. QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(receiver); - if (widgetWindow) + if (widgetWindow && widgetWindow->widget()) return filterEvent(widgetWindow->widget(), event); QGesture *state = qobject_cast<QGesture *>(receiver); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 8d5f275d738fc30a2c006a98c0aaeb7abc7a71ac..35443829441dfef0d7ea1869555faa8e3381ec6e 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -12385,6 +12385,53 @@ static inline bool canMapPosition(QWindow *window) return window->handle() && !qt_window_private(window)->resizeEventPending; } +#ifndef QT_NO_GRAPHICSVIEW +static inline QGraphicsProxyWidget *graphicsProxyWidget(const QWidget *w) +{ + QGraphicsProxyWidget *result = Q_NULLPTR; + const QWidgetPrivate *d = qt_widget_private(const_cast<QWidget *>(w)); + if (d->extra) + result = d->extra->proxyWidget; + return result; +} +#endif // !QT_NO_GRAPHICSVIEW + +struct MapToGlobalTransformResult { + QTransform transform; + QWindow *window; +}; + +static MapToGlobalTransformResult mapToGlobalTransform(const QWidget *w) +{ + MapToGlobalTransformResult result; + result.window = Q_NULLPTR; + for ( ; w ; w = w->parentWidget()) { +#ifndef QT_NO_GRAPHICSVIEW + if (QGraphicsProxyWidget *qgpw = graphicsProxyWidget(w)) { + if (const QGraphicsScene *scene = qgpw->scene()) { + const QList <QGraphicsView *> views = scene->views(); + if (!views.isEmpty()) { + result.transform *= qgpw->sceneTransform(); + result.transform *= views.first()->viewportTransform(); + w = views.first()->viewport(); + } + } + } +#endif // !QT_NO_GRAPHICSVIEW + QWindow *window = w->windowHandle(); + if (window && canMapPosition(window)) { + result.window = window; + break; + } + + const QPoint topLeft = w->geometry().topLeft(); + result.transform.translate(topLeft.x(), topLeft.y()); + if (w->isWindow()) + break; + } + return result; +} + /*! \fn QPoint QWidget::mapToGlobal(const QPoint &pos) const @@ -12396,29 +12443,9 @@ static inline bool canMapPosition(QWindow *window) */ QPoint QWidget::mapToGlobal(const QPoint &pos) const { -#ifndef QT_NO_GRAPHICSVIEW - Q_D(const QWidget); - if (d->extra && d->extra->proxyWidget && d->extra->proxyWidget->scene()) { - const QList <QGraphicsView *> views = d->extra->proxyWidget->scene()->views(); - if (!views.isEmpty()) { - const QPointF scenePos = d->extra->proxyWidget->mapToScene(pos); - const QPoint viewPortPos = views.first()->mapFromScene(scenePos); - return views.first()->viewport()->mapToGlobal(viewPortPos); - } - } -#endif // !QT_NO_GRAPHICSVIEW - int x = pos.x(), y = pos.y(); - const QWidget *w = this; - while (w) { - QWindow *window = w->windowHandle(); - if (window && canMapPosition(window)) - return window->mapToGlobal(QPoint(x, y)); - - x += w->data->crect.x(); - y += w->data->crect.y(); - w = w->isWindow() ? 0 : w->parentWidget(); - } - return QPoint(x, y); + const MapToGlobalTransformResult t = mapToGlobalTransform(this); + const QPoint g = t.transform.map(pos); + return t.window ? t.window->mapToGlobal(g) : g; } /*! @@ -12431,29 +12458,9 @@ QPoint QWidget::mapToGlobal(const QPoint &pos) const */ QPoint QWidget::mapFromGlobal(const QPoint &pos) const { -#ifndef QT_NO_GRAPHICSVIEW - Q_D(const QWidget); - if (d->extra && d->extra->proxyWidget && d->extra->proxyWidget->scene()) { - const QList <QGraphicsView *> views = d->extra->proxyWidget->scene()->views(); - if (!views.isEmpty()) { - const QPoint viewPortPos = views.first()->viewport()->mapFromGlobal(pos); - const QPointF scenePos = views.first()->mapToScene(viewPortPos); - return d->extra->proxyWidget->mapFromScene(scenePos).toPoint(); - } - } -#endif // !QT_NO_GRAPHICSVIEW - int x = pos.x(), y = pos.y(); - const QWidget *w = this; - while (w) { - QWindow *window = w->windowHandle(); - if (window && canMapPosition(window)) - return window->mapFromGlobal(QPoint(x, y)); - - x -= w->data->crect.x(); - y -= w->data->crect.y(); - w = w->isWindow() ? 0 : w->parentWidget(); - } - return QPoint(x, y); + const MapToGlobalTransformResult t = mapToGlobalTransform(this); + const QPoint windowLocal = t.window ? t.window->mapFromGlobal(pos) : pos; + return t.transform.inverted().map(windowLocal); } QWidget *qt_pressGrab = 0; diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 843b89b6e42758f784d53cd6c1d3e1b9d63b3dc4..675d54f6b4bd2e62fa23eb9bd704f4391489f8ca 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -93,7 +93,7 @@ QRectF QWidgetWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const { Q_Q(const QWidgetWindow); const QWidget *widget = q->widget(); - if (!widget->isWindow() || !widget->hasHeightForWidth()) + if (!widget || !widget->isWindow() || !widget->hasHeightForWidth()) return QRect(); const QSize oldSize = rect.size().toSize(); const QSize newSize = QLayout::closestAcceptableSize(widget, oldSize); @@ -129,7 +129,7 @@ QWidgetWindow::QWidgetWindow(QWidget *widget) && !QApplication::testAttribute(Qt::AA_ForceRasterWidgets)) { setSurfaceType(QSurface::RasterGLSurface); } - connect(m_widget, &QObject::objectNameChanged, this, &QWidgetWindow::updateObjectName); + connect(widget, &QObject::objectNameChanged, this, &QWidgetWindow::updateObjectName); connect(this, SIGNAL(screenChanged(QScreen*)), this, SLOT(handleScreenChange())); } @@ -148,16 +148,18 @@ QAccessibleInterface *QWidgetWindow::accessibleRoot() const QObject *QWidgetWindow::focusObject() const { - QWidget *widget = m_widget->focusWidget(); + QWidget *windowWidget = m_widget; + if (!windowWidget) + return Q_NULLPTR; + + QWidget *widget = windowWidget->focusWidget(); if (!widget) - widget = m_widget; + widget = windowWidget; - if (widget) { - QObject *focusObj = QWidgetPrivate::get(widget)->focusObject(); - if (focusObj) - return focusObj; - } + QObject *focusObj = QWidgetPrivate::get(widget)->focusObject(); + if (focusObj) + return focusObj; return widget; } @@ -180,6 +182,9 @@ static inline bool shouldBePropagatedToWidget(QEvent *event) bool QWidgetWindow::event(QEvent *event) { + if (!m_widget) + return QWindow::event(event); + if (m_widget->testAttribute(Qt::WA_DontShowOnScreen)) { // \a event is uninteresting for QWidgetWindow, the event was probably // generated before WA_DontShowOnScreen was set @@ -207,7 +212,7 @@ bool QWidgetWindow::event(QEvent *event) #ifndef QT_NO_ACCESSIBILITY QAccessible::State state; state.active = true; - QAccessibleStateChangeEvent ev(widget(), state); + QAccessibleStateChangeEvent ev(m_widget, state); QAccessible::updateAccessibility(&ev); #endif return false; } @@ -381,7 +386,7 @@ void QWidgetWindow::handleEnterLeaveEvent(QEvent *event) } else { const QEnterEvent *ee = static_cast<QEnterEvent *>(event); QWidget *child = m_widget->childAt(ee->pos()); - QWidget *receiver = child ? child : m_widget; + QWidget *receiver = child ? child : m_widget.data(); QApplicationPrivate::dispatchEnterLeave(receiver, 0, ee->screenPos()); qt_last_mouse_receiver = receiver; } diff --git a/src/widgets/kernel/qwidgetwindow_p.h b/src/widgets/kernel/qwidgetwindow_p.h index d20e7cb15e249ca891b3d0bbb5535f1bd4671cb0..a0d79b2b720a0f6c826ef031a57169739851605f 100644 --- a/src/widgets/kernel/qwidgetwindow_p.h +++ b/src/widgets/kernel/qwidgetwindow_p.h @@ -125,7 +125,7 @@ private: }; QWidget *getFocusWidget(FocusWidgets fw); - QWidget *m_widget; + QPointer<QWidget> m_widget; QPointer<QWidget> m_implicit_mouse_grabber; #ifndef QT_NO_DRAGANDDROP QPointer<QWidget> m_dragTarget; diff --git a/src/widgets/util/qundostack.cpp b/src/widgets/util/qundostack.cpp index 1a3ff5879333f0b857bb5465e32dfc560680cd63..307debc03f61e3dbe433ac9a9c101250406def6c 100644 --- a/src/widgets/util/qundostack.cpp +++ b/src/widgets/util/qundostack.cpp @@ -629,6 +629,8 @@ void QUndoStack::push(QUndoCommand *cmd) Marks the stack as clean and emits cleanChanged() if the stack was not already clean. + This is typically called when a document is saved, for example. + Whenever the stack returns to this state through the use of undo/redo commands, it emits the signal cleanChanged(). This signal is also emitted when the stack leaves the clean state. diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 7ccf28034b688b8ed81aa571ab38b98ff9ba97ec..56965923b719beb2c0d5159c7f98f3f3d14110a4 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -2188,7 +2188,6 @@ void QLineEdit::changeEvent(QEvent *ev) d->control->setPasswordCharacter(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this)); d->control->setPasswordMaskDelay(style()->styleHint(QStyle::SH_LineEdit_PasswordMaskDelay, &opt, this)); } - d->m_iconSize = QSize(); update(); break; case QEvent::LayoutDirectionChange: diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index 3d8a854753376bfc6cfd6df64247a4183897bffb..7da1d911ee91327c1cf68668c4289cf4c96cd425 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -320,6 +320,12 @@ QLineEditIconButton::QLineEditIconButton(QWidget *parent) setFocusPolicy(Qt::NoFocus); } +QLineEditPrivate *QLineEditIconButton::lineEditPrivate() const +{ + QLineEdit *le = qobject_cast<QLineEdit *>(parentWidget()); + return le ? static_cast<QLineEditPrivate *>(qt_widget_private(le)) : Q_NULLPTR; +} + void QLineEditIconButton::paintEvent(QPaintEvent *) { QPainter painter(this); @@ -331,7 +337,9 @@ void QLineEditIconButton::paintEvent(QPaintEvent *) QIcon::Mode state = QIcon::Disabled; if (isEnabled()) state = isDown() ? QIcon::Selected : QIcon::Normal; - const QSize iconSize(IconButtonSize, IconButtonSize); + const QLineEditPrivate *lep = lineEditPrivate(); + const int iconWidth = lep ? lep->sideWidgetParameters().iconSize : 16; + const QSize iconSize(iconWidth, iconWidth); const QPixmap iconPixmap = icon().pixmap(window, iconSize, state, QIcon::Off); QRect pixmapRect = QRect(QPoint(0, 0), iconSize); pixmapRect.moveCenter(rect().center()); @@ -346,8 +354,8 @@ void QLineEditIconButton::actionEvent(QActionEvent *e) const QAction *action = e->action(); if (isVisibleTo(parentWidget()) != action->isVisible()) { setVisible(action->isVisible()); - if (QLineEdit *le = qobject_cast<QLineEdit *>(parentWidget())) - static_cast<QLineEditPrivate *>(qt_widget_private(le))->positionSideWidgets(); + if (QLineEditPrivate *lep = lineEditPrivate()) + lep->positionSideWidgets(); } } break; @@ -413,11 +421,15 @@ void QLineEditPrivate::_q_clearButtonClicked() } } -QSize QLineEditPrivate::iconSize() const +QLineEditPrivate::SideWidgetParameters QLineEditPrivate::sideWidgetParameters() const { - if (!m_iconSize.isValid()) // This might require style-specific handling (pixel metric). - m_iconSize = QSize(QLineEditIconButton::IconButtonSize + 6, QLineEditIconButton::IconButtonSize + 2); - return m_iconSize; + Q_Q(const QLineEdit); + SideWidgetParameters result; + result.iconSize = q->height() < 34 ? 16 : 32; + result.margin = result.iconSize / 4; + result.widgetWidth = result.iconSize + 6; + result.widgetHeight = result.iconSize + 2; + return result; } QIcon QLineEditPrivate::clearButtonIcon() const @@ -443,15 +455,16 @@ void QLineEditPrivate::positionSideWidgets() Q_Q(QLineEdit); if (hasSideWidgets()) { const QRect contentRect = q->rect(); - const QSize iconSize = QLineEditPrivate::iconSize(); - const int delta = QLineEditIconButton::IconMargin + iconSize.width(); - QRect widgetGeometry(QPoint(QLineEditIconButton::IconMargin, (contentRect.height() - iconSize.height()) / 2), iconSize); + const SideWidgetParameters p = sideWidgetParameters(); + const int delta = p.margin + p.widgetWidth; + QRect widgetGeometry(QPoint(p.margin, (contentRect.height() - p.widgetHeight) / 2), + QSize(p.widgetWidth, p.widgetHeight)); for (const SideWidgetEntry &e : leftSideWidgetList()) { e.widget->setGeometry(widgetGeometry); if (e.action->isVisible()) widgetGeometry.moveLeft(widgetGeometry.left() + delta); } - widgetGeometry.moveLeft(contentRect.width() - iconSize.width() - QLineEditIconButton::IconMargin); + widgetGeometry.moveLeft(contentRect.width() - p.widgetWidth - p.margin); for (const SideWidgetEntry &e : rightSideWidgetList()) { e.widget->setGeometry(widgetGeometry); if (e.action->isVisible()) @@ -539,18 +552,26 @@ static bool isSideWidgetVisible(const QLineEditPrivate::SideWidgetEntry &e) int QLineEditPrivate::effectiveLeftTextMargin() const { - const auto &list = leftSideWidgetList(); - return leftTextMargin + (QLineEditIconButton::IconMargin + iconSize().width()) - * int(std::count_if(list.begin(), list.end(), - isSideWidgetVisible)); + int result = leftTextMargin; + if (!leftSideWidgetList().empty()) { + const SideWidgetParameters p = sideWidgetParameters(); + result += (p.margin + p.widgetWidth) + * int(std::count_if(leftSideWidgetList().begin(), leftSideWidgetList().end(), + isSideWidgetVisible)); + } + return result; } int QLineEditPrivate::effectiveRightTextMargin() const { - const auto &list = rightSideWidgetList(); - return rightTextMargin + (QLineEditIconButton::IconMargin + iconSize().width()) - * int(std::count_if(list.begin(), list.end(), - isSideWidgetVisible)); + int result = rightTextMargin; + if (!rightSideWidgetList().empty()) { + const SideWidgetParameters p = sideWidgetParameters(); + result += (p.margin + p.widgetWidth) + * int(std::count_if(rightSideWidgetList().begin(), rightSideWidgetList().end(), + isSideWidgetVisible)); + } + return result; } diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h index 12a4299204203441dfba1a4c9a796a058bb174b5..a14cd663983685171ab12ea76c0e6c15791ce62c 100644 --- a/src/widgets/widgets/qlineedit_p.h +++ b/src/widgets/widgets/qlineedit_p.h @@ -71,6 +71,8 @@ QT_BEGIN_NAMESPACE +class QLineEditPrivate; + // QLineEditIconButton: This is a simple helper class that represents clickable icons that fade in with text class Q_AUTOTEST_EXPORT QLineEditIconButton : public QToolButton @@ -78,8 +80,6 @@ class Q_AUTOTEST_EXPORT QLineEditIconButton : public QToolButton Q_OBJECT Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity) public: - enum { IconMargin = 4, IconButtonSize = 16 }; - explicit QLineEditIconButton(QWidget *parent = 0); qreal opacity() const { return m_opacity; } @@ -99,6 +99,7 @@ private: #ifndef QT_NO_ANIMATION void startOpacityAnimation(qreal endValue); #endif + QLineEditPrivate *lineEditPrivate() const; qreal m_opacity; }; @@ -122,6 +123,13 @@ public: }; typedef std::vector<SideWidgetEntry> SideWidgetEntryList; + struct SideWidgetParameters { + int iconSize; + int widgetWidth; + int widgetHeight; + int margin; + }; + QLineEditPrivate() : control(0), frame(1), contextMenuEnabled(1), cursorVisible(0), dragEnabled(0), clickCausedFocus(0), hscroll(0), vscroll(0), @@ -212,7 +220,7 @@ public: QWidget *addAction(QAction *newAction, QAction *before, QLineEdit::ActionPosition, int flags = 0); void removeAction(QAction *action); - QSize iconSize() const; + SideWidgetParameters sideWidgetParameters() const; QIcon clearButtonIcon() const; void setClearButtonEnabled(bool enabled); void positionSideWidgets(); @@ -233,7 +241,6 @@ private: SideWidgetEntryList leadingSideWidgets; SideWidgetEntryList trailingSideWidgets; int lastTextSize; - mutable QSize m_iconSize; }; Q_DECLARE_TYPEINFO(QLineEditPrivate::SideWidgetEntry, Q_PRIMITIVE_TYPE); diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 85d0c54357e5f99523cfe5bbf76517e6f0c0354a..bf523a3a702ff7798b1eb678408ec5459dedee3e 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -712,7 +712,6 @@ void QMenuBarPrivate::init() } #endif q->setBackgroundRole(QPalette::Button); - oldWindow = oldParent = 0; handleReparent(); q->setMouseTracking(q->style()->styleHint(QStyle::SH_MenuBar_MouseTracking, 0, q)); @@ -1343,30 +1342,41 @@ void QMenuBarPrivate::handleReparent() { Q_Q(QMenuBar); QWidget *newParent = q->parentWidget(); - //Note: if parent is reparented, then window may change even if parent doesn't - // we need to install an event filter on parent, and remove the old one - - if (oldParent != newParent) { - if (oldParent) - oldParent->removeEventFilter(q); - if (newParent) - newParent->installEventFilter(q); + //Note: if parent is reparented, then window may change even if parent doesn't. + // We need to install an avent filter on each parent up to the parent that is + // also a window (for shortcuts) + QWidget *newWindow = newParent ? newParent->window() : Q_NULLPTR; + + QVector<QPointer<QWidget> > newParents; + // Remove event filters on ex-parents, keep them on still-parents + // The parents are always ordered in the vector + foreach (const QPointer<QWidget> &w, oldParents) { + if (w) { + if (newParent == w) { + newParents.append(w); + if (newParent != newWindow) //stop at the window + newParent = newParent->parentWidget(); + } else { + w->removeEventFilter(q); + } + } } - //we also need event filter on top-level (for shortcuts) - QWidget *newWindow = newParent ? newParent->window() : 0; - - if (oldWindow != newWindow) { - if (oldParent && oldParent != oldWindow) - oldWindow->removeEventFilter(q); - - if (newParent && newParent != newWindow) - newWindow->installEventFilter(q); + // At this point, newParent is the next one to be added to newParents + while (newParent && newParent != newWindow) { + //install event filters all the way up to (excluding) the window + newParents.append(newParent); + newParent->installEventFilter(q); + newParent = newParent->parentWidget(); } - oldParent = newParent; - oldWindow = newWindow; + if (newParent && newWindow) { + // Install the event filter on the window + newParents.append(newParent); + newParent->installEventFilter(q); + } + oldParents = newParents; if (platformMenuBar) { if (newWindow) { @@ -1478,10 +1488,9 @@ bool QMenuBar::event(QEvent *e) bool QMenuBar::eventFilter(QObject *object, QEvent *event) { Q_D(QMenuBar); - if (object == parent() && object) { - if (event->type() == QEvent::ParentChange) //GrandparentChange + if (object && (event->type() == QEvent::ParentChange)) //GrandparentChange d->handleReparent(); - } + if (object == d->leftWidget || object == d->rightWidget) { switch (event->type()) { case QEvent::ShowToParent: diff --git a/src/widgets/widgets/qmenubar_p.h b/src/widgets/widgets/qmenubar_p.h index 05b1878c2090a8df98060c33b3f653fb5218cb65..c88e4af8368d25a2ecd3debca5d66c28fea258a5 100644 --- a/src/widgets/widgets/qmenubar_p.h +++ b/src/widgets/widgets/qmenubar_p.h @@ -134,8 +134,7 @@ public: // reparenting void handleReparent(); - QWidget *oldParent; - QWidget *oldWindow; + QVector<QPointer<QWidget> > oldParents; QList<QAction*> hiddenActions; //default action diff --git a/src/winmain/winmain.pro b/src/winmain/winmain.pro index 4dab828eae9b372a458f1aea61f33b795ffa536b..b4977653ce63305867def3ee95677b8f08e56fae 100644 --- a/src/winmain/winmain.pro +++ b/src/winmain/winmain.pro @@ -10,7 +10,7 @@ QT = core DEFINES += QT_NO_FOREACH -contains(QT_CONFIG, build_all):CONFIG += build_all +contains(QT_CONFIG, debug_and_release): CONFIG += build_all win32-msvc*:QMAKE_CFLAGS_DEBUG -= -Zi win32-msvc*:QMAKE_CXXFLAGS_DEBUG -= -Zi diff --git a/src/xml/doc/qtxml.qdocconf b/src/xml/doc/qtxml.qdocconf index b31c2a18d2982ece2129d3f83500642647848e7a..a23915487f07e0c178845bc441271278a859b8fe 100644 --- a/src/xml/doc/qtxml.qdocconf +++ b/src/xml/doc/qtxml.qdocconf @@ -4,7 +4,7 @@ project = QtXml description = Qt XML Reference Documentation version = $QT_VERSION -examplesinstallpath = qtbase/xml +examplesinstallpath = xml qhp.projects = QtXml diff --git a/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp b/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp index 802bbe9963f66f9e1785010a5adf8dc9f3936ed7..8b1aa105de020456af27f9eb428862da89f86f73 100644 --- a/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp +++ b/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp @@ -27,14 +27,18 @@ ****************************************************************************/ #include <QtTest/QtTest> - #include <QStorageInfo> +#include <stdarg.h> + +#include "../../../../manual/qstorageinfo/printvolumes.cpp" + class tst_QStorageInfo : public QObject { Q_OBJECT private slots: void defaultValues(); + void dump(); void operatorEqual(); #ifndef Q_OS_WINRT void operatorNotEqual(); @@ -61,6 +65,33 @@ void tst_QStorageInfo::defaultValues() QCOMPARE(storage.bytesAvailable(), -1); } +static int qInfoPrinter(const char *format, ...) +{ + static char buf[1024]; + static size_t bufuse = 0; + + va_list ap; + va_start(ap, format); // use variable arg list + int n = qvsnprintf(buf + bufuse, sizeof(buf) - bufuse, format, ap); + va_end(ap); + + bufuse += n; + if (bufuse >= sizeof(buf) - 1 || format[strlen(format) - 1] == '\n') { + // flush + QtMessageHandler qt_message_print = qInstallMessageHandler(0); + qInstallMessageHandler(qt_message_print); // restore the handler + qt_message_print(QtInfoMsg, QMessageLogContext(), QString::fromLocal8Bit(buf)); + bufuse = 0; + } + + return 1; +} + +void tst_QStorageInfo::dump() +{ + printVolumes(QStorageInfo::mountedVolumes(), qInfoPrinter); +} + void tst_QStorageInfo::operatorEqual() { { @@ -157,6 +188,7 @@ void tst_QStorageInfo::tempFile() #endif qint64 free = storage1.bytesFree(); + QVERIFY(free != -1); file.write(QByteArray(1024*1024, '1')); file.flush(); @@ -180,6 +212,7 @@ void tst_QStorageInfo::caching() qint64 free = storage1.bytesFree(); QStorageInfo storage2(storage1); QCOMPARE(free, storage2.bytesFree()); + QVERIFY(free != -1); file.write(QByteArray(1024*1024, '\0')); file.flush(); diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 7f6e26eecb12879c87a2fcf5d109fecb09677d21..262d8ad44b5529c6318837b32bf656af823f937b 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -4659,6 +4659,16 @@ template<typename Enum> void testVariant(Enum value, bool *ok) QVERIFY(var2.convert(QMetaType::Int)); QCOMPARE(var2.value<int>(), static_cast<int>(value)); + if (static_cast<qint64>(value) <= INT_MAX) { + int intValue = static_cast<int>(value); + QVariant intVar = intValue; + QVERIFY(intVar.canConvert<Enum>()); + QCOMPARE(intVar.value<Enum>(), value); + } + qint64 longValue = static_cast<qint64>(value); + QVERIFY(QVariant(longValue).canConvert<Enum>()); + QCOMPARE(QVariant(longValue).value<Enum>(), value); + *ok = true; } diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 90e86dca4e4f86d7096b9adaa7d7d27852b27814..9dd8b05796892a973cb340c9f5df1e86b822e975 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -88,7 +88,7 @@ public: bool isStatic() const { return d->ref.isStatic(); } bool isShared() const { return d->ref.isShared(); } bool isSharedWith(const SimpleVector &other) const { return d == other.d; } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) bool isSharable() const { return d->ref.isSharable(); } void setSharable(bool sharable) { d.setSharable(sharable); } #endif diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 0732a550639bb26bcadd14e5ba99b74caa1851bd..0c41f663571954ee925925f9fce4d562075f6220 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -39,7 +39,7 @@ struct SharedNullVerifier { Q_ASSERT(QArrayData::shared_null[0].ref.isStatic()); Q_ASSERT(QArrayData::shared_null[0].ref.isShared()); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) Q_ASSERT(QArrayData::shared_null[0].ref.isSharable()); #endif } @@ -96,7 +96,7 @@ void tst_QArrayData::referenceCounting() QCOMPARE(array.ref.atomic.load(), 1); QVERIFY(!array.ref.isStatic()); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QVERIFY(array.ref.isSharable()); #endif @@ -118,7 +118,7 @@ void tst_QArrayData::referenceCounting() // Now would be a good time to free/release allocated data } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) { // Reference counting initialized to 0 (non-sharable) QArrayData array = { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, 0 }; @@ -146,7 +146,7 @@ void tst_QArrayData::referenceCounting() QCOMPARE(array.ref.atomic.load(), -1); QVERIFY(array.ref.isStatic()); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QVERIFY(array.ref.isSharable()); #endif @@ -173,7 +173,7 @@ void tst_QArrayData::sharedNullEmpty() QCOMPARE(null->ref.atomic.load(), -1); QCOMPARE(empty->ref.atomic.load(), -1); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QVERIFY(null->ref.isSharable()); QVERIFY(empty->ref.isSharable()); #endif @@ -304,7 +304,7 @@ void tst_QArrayData::simpleVector() QVERIFY(!v7.isShared()); QVERIFY(!v8.isShared()); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QVERIFY(v1.isSharable()); QVERIFY(v2.isSharable()); QVERIFY(v3.isSharable()); @@ -497,7 +497,7 @@ void tst_QArrayData::simpleVector() for (int i = 0; i < 120; ++i) QCOMPARE(v1[i], v8[i % 10]); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) { v7.setSharable(true); QVERIFY(v7.isSharable()); @@ -667,7 +667,7 @@ void tst_QArrayData::allocate_data() QArrayData *shared_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0); QVERIFY(shared_empty); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QArrayData *unsharable_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, QArrayData::Unsharable); QVERIFY(unsharable_empty); #endif @@ -681,7 +681,7 @@ void tst_QArrayData::allocate_data() } options[] = { { "Default", QArrayData::Default, false, true, shared_empty }, { "Reserved", QArrayData::CapacityReserved, true, true, shared_empty }, -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) { "Reserved | Unsharable", QArrayData::CapacityReserved | QArrayData::Unsharable, true, false, unsharable_empty }, @@ -731,7 +731,7 @@ void tst_QArrayData::allocate() else QCOMPARE(data->alloc, uint(capacity)); QCOMPARE(data->capacityReserved, uint(isCapacityReserved)); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QFETCH(bool, isSharable); QCOMPARE(data->ref.isSharable(), isSharable); #endif @@ -1311,7 +1311,7 @@ static inline bool arrayIsFilledWith(const QArrayDataPointer<int> &array, void tst_QArrayData::setSharable_data() { -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QTest::addColumn<QArrayDataPointer<int> >("array"); QTest::addColumn<size_t>("size"); QTest::addColumn<size_t>("capacity"); @@ -1357,7 +1357,7 @@ void tst_QArrayData::setSharable_data() void tst_QArrayData::setSharable() { -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QFETCH(QArrayDataPointer<int>, array); QFETCH(size_t, size); QFETCH(size_t, capacity); @@ -1487,7 +1487,7 @@ void fromRawData_impl() QVERIFY((const T *)raw.constBegin() != array); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) { // Immutable, unsharable SimpleVector<T> raw = SimpleVector<T>::fromRawData(array, @@ -1573,7 +1573,7 @@ void tst_QArrayData::literals() QVERIFY(v.isStatic()); #endif -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QVERIFY(v.isSharable()); #endif QCOMPARE((void*)(const char*)(v.constBegin() + v.size()), (void*)(const char*)v.constEnd()); @@ -1624,7 +1624,7 @@ void tst_QArrayData::variadicLiterals() QVERIFY(v.isStatic()); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QVERIFY(v.isSharable()); #endif QCOMPARE((const int *)(v.constBegin() + v.size()), (const int *)v.constEnd()); diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index 4336d02b2c09856876a1dd3bb2c14b7a6ef975e3..06ff09dc6c31bd340b52dd975d4f561bd3ef1c30 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -1188,7 +1188,7 @@ void tst_QHash::noNeedlessRehashes() void tst_QHash::const_shared_null() { QHash<int, QString> hash2; -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QHash<int, QString> hash1; hash1.setSharable(false); QVERIFY(hash1.isDetached()); diff --git a/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp b/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp index 4c4cb4879bfbbc135d0675916705466b4ab7af17..f17d6695f07c8042c14ad5e0cc5774ba0ca2e5b3 100644 --- a/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp +++ b/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp @@ -1022,7 +1022,7 @@ template<typename T> void tst_QLinkedList::constSharedNull() const { QLinkedList<T> list2; -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QLinkedList<T> list1; list1.setSharable(false); QVERIFY(list1.isDetached()); @@ -1054,7 +1054,7 @@ void tst_QLinkedList::constSharedNullComplex() const void tst_QLinkedList::setSharableInt() const { -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QLinkedList<int> orglist; orglist << 0 << 1 << 2 << 3 << 4 << 5; int size = 6; diff --git a/tests/auto/corelib/tools/qlist/tst_qlist.cpp b/tests/auto/corelib/tools/qlist/tst_qlist.cpp index bae8ece303acde1d349e523fc070ef8ee5d4a474..b3f8130d27985e8300751caee1582452849c874b 100644 --- a/tests/auto/corelib/tools/qlist/tst_qlist.cpp +++ b/tests/auto/corelib/tools/qlist/tst_qlist.cpp @@ -1887,7 +1887,7 @@ template<typename T> void tst_QList::constSharedNull() const { QList<T> list2; -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QList<T> list1; list1.setSharable(false); QVERIFY(list1.isDetached()); @@ -1921,7 +1921,7 @@ void tst_QList::constSharedNullComplex() const template <class T> void generateSetSharableData() { -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QTest::addColumn<QList<T> >("list"); QTest::addColumn<int>("size"); @@ -1933,7 +1933,7 @@ void generateSetSharableData() template <class T> void runSetSharableTest() { -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QFETCH(QList<T>, list); QFETCH(int, size); diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp index 0898c10ea686a98caf04d9e3d57a7887c357f78d..8aa7a3e51884700fa0dc688e3dd499f4743831c9 100644 --- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp +++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp @@ -1007,7 +1007,7 @@ void tst_QMap::qmultimap_specific() void tst_QMap::const_shared_null() { QMap<int, QString> map2; -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QMap<int, QString> map1; map1.setSharable(false); QVERIFY(map1.isDetached()); @@ -1104,7 +1104,7 @@ const T &const_(const T &t) void tst_QMap::setSharable() { -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QMap<int, QString> map; map.insert(1, "um"); diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index eb37d6b8e64b0d0d9cf474520025d007278a5892..825cb05d74ebe037034b8c58e751c28469fbd05d 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -426,7 +426,7 @@ void tst_QVector::copyConstructor() const QVector<T> v2(v1); QCOMPARE(v1, v2); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section { QVector<T> v1; @@ -590,7 +590,7 @@ void tst_QVector::append() const QVERIFY(v.size() == 3); QCOMPARE(v.at(v.size() - 1), SimpleValue<T>::at(0)); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section { QVector<T> v(2); @@ -926,7 +926,7 @@ void tst_QVector::eraseEmpty() const v.erase(v.begin(), v.end()); QCOMPARE(v.size(), 0); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section { QVector<T> v; @@ -965,7 +965,7 @@ void tst_QVector::eraseEmptyReserved() const v.erase(v.begin(), v.end()); QCOMPARE(v.size(), 0); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section { QVector<T> v; @@ -1081,7 +1081,7 @@ void tst_QVector::erase(bool shared) const if (shared) QCOMPARE(SimpleValue<T>::vector(12), *svc.copy); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section { QVector<T> v = SimpleValue<T>::vector(10); @@ -1168,7 +1168,7 @@ template<typename T> void tst_QVector::eraseReserved() const v.erase(v.begin() + 1, v.end() - 1); QCOMPARE(v.size(), 2); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section { QVector<T> v(10); @@ -1903,7 +1903,7 @@ void tst_QVector::resizePOD_data() const QTest::newRow("nonEmpty") << nonEmpty << 10; QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section QVector<int> nullNotShared; QVector<int> emptyNotShared(0, 5); @@ -1978,7 +1978,7 @@ void tst_QVector::resizeComplexMovable_data() const QTest::newRow("nonEmpty") << nonEmpty << 10; QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section QVector<Movable> nullNotShared; QVector<Movable> emptyNotShared(0, 'Q'); @@ -2057,7 +2057,7 @@ void tst_QVector::resizeComplex_data() const QTest::newRow("nonEmpty") << nonEmpty << 10; QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section QVector<Custom> nullNotShared; QVector<Custom> emptyNotShared(0, '0'); @@ -2498,7 +2498,7 @@ void tst_QVector::initializeListCustom() void tst_QVector::const_shared_null() { QVector<int> v2; -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section QVector<int> v1; v1.setSharable(false); @@ -2509,7 +2509,7 @@ void tst_QVector::const_shared_null() QVERIFY(!v2.isDetached()); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section template<typename T> void tst_QVector::setSharable_data() const diff --git a/tests/auto/dbus/dbus.pro b/tests/auto/dbus/dbus.pro index 67cbc4bfef3a81f9e322fd7c82cbb7a93a0def3d..c5cddee5f5cf8b3749a6860139c8e9db10de993f 100644 --- a/tests/auto/dbus/dbus.pro +++ b/tests/auto/dbus/dbus.pro @@ -11,6 +11,7 @@ SUBDIRS+=\ qdbusconnection_no_app \ qdbusconnection_no_bus \ qdbusconnection_no_libdbus \ + qdbusconnection_spyhook \ qdbuscontext \ qdbusinterface \ qdbuslocalcalls \ diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp index 0163f44a36f2d53b93be4fca379edbaa58f67244..851ef6cc1f4c89ea43dc39d9fdefbb06c7340512 100644 --- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp +++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp @@ -50,6 +50,31 @@ void MyObjectWithoutInterface::method(const QDBusMessage &msg) //qDebug() << msg; } +int tst_QDBusConnection::hookCallCount; +tst_QDBusConnection::tst_QDBusConnection() +{ +#ifdef HAS_HOOKSETUPFUNCTION +# define QCOMPARE_HOOKCOUNT(n) QCOMPARE(hookCallCount, n); hookCallCount = 0 +# define QVERIFY_HOOKCALLED() QCOMPARE(hookCallCount, 1); hookCallCount = 0 + hookSetupFunction(); +#else +# define QCOMPARE_HOOKCOUNT(n) qt_noop() +# define QVERIFY_HOOKCALLED() qt_noop() +#endif +} + +// called before each testcase +void tst_QDBusConnection::init() +{ + hookCallCount = 0; +} + +void tst_QDBusConnection::cleanup() +{ + QVERIFY2(!hookCallCount, "Unchecked call"); +} + + void tst_QDBusConnection::noConnection() { QDBusConnection con = QDBusConnection::connectToBus("unix:path=/dev/null", "testconnection"); @@ -354,9 +379,11 @@ void tst_QDBusConnection::registerObject() QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj)); QVERIFY(callMethod(con, path)); QCOMPARE(obj.path, path); + QVERIFY_HOOKCALLED(); } // make sure it's gone QVERIFY(!callMethod(con, path)); + QVERIFY_HOOKCALLED(); } void tst_QDBusConnection::registerObjectWithInterface_data() @@ -388,9 +415,11 @@ void tst_QDBusConnection::registerObjectWithInterface() QVERIFY(callMethod(con, path, interface)); QCOMPARE(obj.path, path); QCOMPARE(obj.interface, interface); + QVERIFY_HOOKCALLED(); } // make sure it's gone QVERIFY(!callMethod(con, path, interface)); + QVERIFY_HOOKCALLED(); } void tst_QDBusConnection::registerObjectPeer_data() @@ -427,6 +456,7 @@ void tst_QDBusConnection::registerObjectPeer() MyObject obj; QVERIFY(callMethodPeer(con, path)); QCOMPARE(obj.path, path); + QVERIFY_HOOKCALLED(); } QDBusConnection::connectToPeer(server.address(), "afterFoo"); @@ -436,6 +466,7 @@ void tst_QDBusConnection::registerObjectPeer() QDBusConnection con("foo"); QVERIFY(con.isConnected()); QVERIFY(callMethodPeer(con, path)); + QVERIFY_HOOKCALLED(); } server.unregisterObject(); @@ -444,6 +475,7 @@ void tst_QDBusConnection::registerObjectPeer() QDBusConnection con("foo"); QVERIFY(con.isConnected()); QVERIFY(!callMethodPeer(con, path)); + QVERIFY_HOOKCALLED(); } server.registerObject(); @@ -452,6 +484,7 @@ void tst_QDBusConnection::registerObjectPeer() QDBusConnection con("foo"); QVERIFY(con.isConnected()); QVERIFY(callMethodPeer(con, path)); + QVERIFY_HOOKCALLED(); } QDBusConnection::disconnectFromPeer("foo"); @@ -473,10 +506,15 @@ void tst_QDBusConnection::registerObject2() // make sure nothing is using our paths: QVERIFY(!callMethod(con, "/")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p2")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/q")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/q/r")); + QVERIFY_HOOKCALLED(); { // register one object at root: @@ -484,76 +522,99 @@ void tst_QDBusConnection::registerObject2() QVERIFY(con.registerObject("/", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(callMethod(con, "/")); QCOMPARE(obj.path, QString("/")); + QVERIFY_HOOKCALLED(); } // make sure it's gone QVERIFY(!callMethod(con, "/")); + QVERIFY_HOOKCALLED(); { // register one at an element: MyObject obj; QVERIFY(con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(!callMethod(con, "/")); + QVERIFY_HOOKCALLED(); QVERIFY(callMethod(con, "/p1")); QCOMPARE(obj.path, QString("/p1")); + QVERIFY_HOOKCALLED(); // re-register it somewhere else QVERIFY(con.registerObject("/p2", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(callMethod(con, "/p1")); QCOMPARE(obj.path, QString("/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(callMethod(con, "/p2")); QCOMPARE(obj.path, QString("/p2")); + QVERIFY_HOOKCALLED(); } // make sure it's gone QVERIFY(!callMethod(con, "/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p2")); + QVERIFY_HOOKCALLED(); { // register at a deep path MyObject obj; QVERIFY(con.registerObject("/p1/q/r", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(!callMethod(con, "/")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/q")); + QVERIFY_HOOKCALLED(); QVERIFY(callMethod(con, "/p1/q/r")); QCOMPARE(obj.path, QString("/p1/q/r")); + QVERIFY_HOOKCALLED(); } + // make sure it's gone QVERIFY(!callMethod(con, "/p1/q/r")); + QVERIFY_HOOKCALLED(); { MyObject obj; QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(callMethod(con, "/p1/q2")); QCOMPARE(obj.path, QString("/p1/q2")); + QVERIFY_HOOKCALLED(); // try unregistering con.unregisterObject("/p1/q2"); QVERIFY(!callMethod(con, "/p1/q2")); + QVERIFY_HOOKCALLED(); // register it again QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(callMethod(con, "/p1/q2")); QCOMPARE(obj.path, QString("/p1/q2")); + QVERIFY_HOOKCALLED(); // now try removing things around it: con.unregisterObject("/p2"); QVERIFY(callMethod(con, "/p1/q2")); // unrelated object shouldn't affect + QVERIFY_HOOKCALLED(); con.unregisterObject("/p1"); QVERIFY(callMethod(con, "/p1/q2")); // unregistering just the parent shouldn't affect it + QVERIFY_HOOKCALLED(); con.unregisterObject("/p1/q2/r"); QVERIFY(callMethod(con, "/p1/q2")); // unregistering non-existing child shouldn't affect it either + QVERIFY_HOOKCALLED(); con.unregisterObject("/p1/q"); QVERIFY(callMethod(con, "/p1/q2")); // unregistering sibling (before) shouldn't affect + QVERIFY_HOOKCALLED(); con.unregisterObject("/p1/r"); QVERIFY(callMethod(con, "/p1/q2")); // unregistering sibling (after) shouldn't affect + QVERIFY_HOOKCALLED(); // now remove it: con.unregisterObject("/p1", QDBusConnection::UnregisterTree); QVERIFY(!callMethod(con, "/p1/q2")); // we removed the full tree + QVERIFY_HOOKCALLED(); } } @@ -572,10 +633,15 @@ void tst_QDBusConnection::registerObjectPeer2() // make sure nothing is using our paths: QVERIFY(!callMethodPeer(srv_con, "/")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p2")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/q")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/q/r")); + QVERIFY_HOOKCALLED(); { // register one object at root: @@ -583,76 +649,101 @@ void tst_QDBusConnection::registerObjectPeer2() QVERIFY(con.registerObject("/", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(callMethodPeer(srv_con, "/")); QCOMPARE(obj.path, QString("/")); + QVERIFY_HOOKCALLED(); } + // make sure it's gone QVERIFY(!callMethodPeer(srv_con, "/")); + QVERIFY_HOOKCALLED(); { // register one at an element: MyObject obj; QVERIFY(con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(!callMethodPeer(srv_con, "/")); + QVERIFY_HOOKCALLED(); QVERIFY(callMethodPeer(srv_con, "/p1")); QCOMPARE(obj.path, QString("/p1")); + QVERIFY_HOOKCALLED(); // re-register it somewhere else QVERIFY(con.registerObject("/p2", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(callMethodPeer(srv_con, "/p1")); QCOMPARE(obj.path, QString("/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(callMethodPeer(srv_con, "/p2")); QCOMPARE(obj.path, QString("/p2")); + QVERIFY_HOOKCALLED(); } + // make sure it's gone QVERIFY(!callMethodPeer(srv_con, "/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p2")); + QVERIFY_HOOKCALLED(); { // register at a deep path MyObject obj; QVERIFY(con.registerObject("/p1/q/r", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(!callMethodPeer(srv_con, "/")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/q")); + QVERIFY_HOOKCALLED(); QVERIFY(callMethodPeer(srv_con, "/p1/q/r")); QCOMPARE(obj.path, QString("/p1/q/r")); + QVERIFY_HOOKCALLED(); } + // make sure it's gone QVERIFY(!callMethodPeer(srv_con, "/p1/q/r")); + QVERIFY_HOOKCALLED(); { MyObject obj; QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(callMethodPeer(srv_con, "/p1/q2")); QCOMPARE(obj.path, QString("/p1/q2")); + QVERIFY_HOOKCALLED(); // try unregistering con.unregisterObject("/p1/q2"); QVERIFY(!callMethodPeer(srv_con, "/p1/q2")); + QVERIFY_HOOKCALLED(); // register it again QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(callMethodPeer(srv_con, "/p1/q2")); QCOMPARE(obj.path, QString("/p1/q2")); + QVERIFY_HOOKCALLED(); // now try removing things around it: con.unregisterObject("/p2"); QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unrelated object shouldn't affect + QVERIFY_HOOKCALLED(); con.unregisterObject("/p1"); QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unregistering just the parent shouldn't affect it + QVERIFY_HOOKCALLED(); con.unregisterObject("/p1/q2/r"); QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unregistering non-existing child shouldn't affect it either + QVERIFY_HOOKCALLED(); con.unregisterObject("/p1/q"); QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unregistering sibling (before) shouldn't affect + QVERIFY_HOOKCALLED(); con.unregisterObject("/p1/r"); QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unregistering sibling (after) shouldn't affect + QVERIFY_HOOKCALLED(); // now remove it: con.unregisterObject("/p1", QDBusConnection::UnregisterTree); QVERIFY(!callMethodPeer(srv_con, "/p1/q2")); // we removed the full tree + QVERIFY_HOOKCALLED(); } QDBusConnection::disconnectFromPeer("foo"); @@ -664,6 +755,7 @@ void tst_QDBusConnection::registerQObjectChildren() // make sure no one is there QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(!callMethod(con, "/p1")); + QVERIFY_HOOKCALLED(); { MyObject obj, *a, *b, *c, *cc; @@ -686,32 +778,47 @@ void tst_QDBusConnection::registerQObjectChildren() // make calls QVERIFY(callMethod(con, "/p1")); QCOMPARE(obj.callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(callMethod(con, "/p1/a")); QCOMPARE(a->callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(callMethod(con, "/p1/b")); QCOMPARE(b->callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(callMethod(con, "/p1/c")); QCOMPARE(c->callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(callMethod(con, "/p1/c/cc")); QCOMPARE(cc->callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/d")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/c/abc")); + QVERIFY_HOOKCALLED(); // pull an object, see if it goes away: delete b; QVERIFY(!callMethod(con, "/p1/b")); + QVERIFY_HOOKCALLED(); delete c; QVERIFY(!callMethod(con, "/p1/c")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/c/cc")); + QVERIFY_HOOKCALLED(); } QVERIFY(!callMethod(con, "/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/a")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/b")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/c")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/c/cc")); + QVERIFY_HOOKCALLED(); } void tst_QDBusConnection::registerQObjectChildrenPeer() @@ -729,6 +836,7 @@ void tst_QDBusConnection::registerQObjectChildrenPeer() QDBusConnection srv_con = server.connection(); QVERIFY(!callMethodPeer(srv_con, "/p1")); + QVERIFY_HOOKCALLED(); { MyObject obj, *a, *b, *c, *cc; @@ -751,32 +859,47 @@ void tst_QDBusConnection::registerQObjectChildrenPeer() // make calls QVERIFY(callMethodPeer(srv_con, "/p1")); QCOMPARE(obj.callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(callMethodPeer(srv_con, "/p1/a")); QCOMPARE(a->callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(callMethodPeer(srv_con, "/p1/b")); QCOMPARE(b->callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(callMethodPeer(srv_con, "/p1/c")); QCOMPARE(c->callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(callMethodPeer(srv_con, "/p1/c/cc")); QCOMPARE(cc->callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/d")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/c/abc")); + QVERIFY_HOOKCALLED(); // pull an object, see if it goes away: delete b; QVERIFY(!callMethodPeer(srv_con, "/p1/b")); + QVERIFY_HOOKCALLED(); delete c; QVERIFY(!callMethodPeer(srv_con, "/p1/c")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/c/cc")); + QVERIFY_HOOKCALLED(); } QVERIFY(!callMethodPeer(srv_con, "/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/a")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/b")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/c")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/c/cc")); + QVERIFY_HOOKCALLED(); QDBusConnection::disconnectFromPeer("foo"); } @@ -822,20 +945,25 @@ void tst_QDBusConnection::callSelf() QVERIFY(connection.registerService(serviceName())); QDBusInterface interface(serviceName(), "/test"); QVERIFY(interface.isValid()); + QVERIFY_HOOKCALLED(); interface.call(QDBus::Block, "test0"); QCOMPARE(testObject.func, QString("test0")); + QVERIFY_HOOKCALLED(); interface.call(QDBus::Block, "test1", 42); QCOMPARE(testObject.func, QString("test1 42")); + QVERIFY_HOOKCALLED(); QDBusMessage reply = interface.call(QDBus::Block, "test2"); QCOMPARE(testObject.func, QString("test2")); QCOMPARE(reply.arguments().value(0).toInt(), 43); + QVERIFY_HOOKCALLED(); QDBusMessage msg = QDBusMessage::createMethodCall(serviceName(), "/test", QString(), "test3"); msg << 44; reply = connection.call(msg); QCOMPARE(reply.arguments().value(0).toInt(), 45); + QVERIFY_HOOKCALLED(); } void tst_QDBusConnection::callSelfByAnotherName_data() @@ -903,12 +1031,14 @@ void tst_QDBusConnection::callSelfByAnotherName() QDBusMessage reply = con.call(msg, QDBus::Block, 1000); QCOMPARE(reply.type(), QDBusMessage::ReplyMessage); + QVERIFY_HOOKCALLED(); } void tst_QDBusConnection::multipleInterfacesInQObject() { QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(!callMethod(con, "/p1")); + QVERIFY_HOOKCALLED(); MyObject obj; con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots); @@ -919,6 +1049,7 @@ void tst_QDBusConnection::multipleInterfacesInQObject() QDBusMessage reply = con.call(msg, QDBus::Block); QCOMPARE(reply.type(), QDBusMessage::ReplyMessage); QCOMPARE(reply.arguments().count(), 0); + QVERIFY_HOOKCALLED(); } void tst_QDBusConnection::slotsWithLessParameters() @@ -976,6 +1107,7 @@ void tst_QDBusConnection::nestedCallWithCallback() QTestEventLoop::instance().enterLoop(15); QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(signalsReceived, 1); + QCOMPARE_HOOKCOUNT(2); } void tst_QDBusConnection::serviceRegistrationRaceCondition() @@ -1140,6 +1272,7 @@ void tst_QDBusConnection::callVirtualObject() QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY_HOOKCALLED(); QCOMPARE(obj.callCount, 1); QCOMPARE(obj.lastMessage.service(), con2.baseService()); @@ -1157,6 +1290,7 @@ void tst_QDBusConnection::callVirtualObject() QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY_HOOKCALLED(); QCOMPARE(obj.callCount, 2); QCOMPARE(obj.lastMessage.service(), con2.baseService()); @@ -1174,6 +1308,7 @@ void tst_QDBusConnection::callVirtualObject() QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY_HOOKCALLED(); QTest::qWait(100); QVERIFY(errorReply.isError()); QCOMPARE(errorReply.reply().errorName(), QString("org.freedesktop.DBus.Error.UnknownObject")); @@ -1202,6 +1337,7 @@ void tst_QDBusConnection::callVirtualObjectLocal() QCOMPARE(obj.lastMessage.interface(), QString()); QCOMPARE(obj.lastMessage.path(), path); QCOMPARE(obj.replyArguments, reply.arguments()); + QVERIFY_HOOKCALLED(); obj.replyArguments << QString("alien abduction"); QDBusMessage subPathMessage = QDBusMessage::createMethodCall(con.baseService(), childPath, QString(), "hello"); @@ -1211,6 +1347,7 @@ void tst_QDBusConnection::callVirtualObjectLocal() QCOMPARE(obj.lastMessage.interface(), QString()); QCOMPARE(obj.lastMessage.path(), childPath); QCOMPARE(obj.replyArguments, subPathReply.arguments()); + QVERIFY_HOOKCALLED(); } void tst_QDBusConnection::pendingCallWhenDisconnected() diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h index 0402889c6ec9369ef177f6ce2cbe4ced05fb5bee..b9eb0d9db73fc72fdbde456b390c69fa14f766eb 100644 --- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h +++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h @@ -74,11 +74,18 @@ class tst_QDBusConnection: public QObject Q_OBJECT int signalsReceived; +public: + static int hookCallCount; + tst_QDBusConnection(); + public slots: void oneSlot() { ++signalsReceived; } void exitLoop() { ++signalsReceived; QTestEventLoop::instance().exitLoop(); } void secondCallWithCallback(); + void init(); + void cleanup(); + private slots: void noConnection(); void connectToBus(); diff --git a/tests/auto/dbus/qdbusconnection_spyhook/qdbusconnection_spyhook.pro b/tests/auto/dbus/qdbusconnection_spyhook/qdbusconnection_spyhook.pro new file mode 100644 index 0000000000000000000000000000000000000000..020d30380d8edf6fb235e25b6dab2c4bc231e82c --- /dev/null +++ b/tests/auto/dbus/qdbusconnection_spyhook/qdbusconnection_spyhook.pro @@ -0,0 +1,7 @@ +CONFIG += testcase +TARGET = tst_qdbusconnection_spyhook +QT = core dbus testlib +SOURCES += tst_qdbusconnection_spyhook.cpp +HEADERS += ../qdbusconnection/tst_qdbusconnection.h +DEFINES += SRCDIR=\\\"$$PWD/\\\" tst_QDBusConnection=tst_QDBusConnection_SpyHook +include(../dbus-testcase.pri) diff --git a/tests/auto/dbus/qdbusconnection_spyhook/tst_qdbusconnection_spyhook.cpp b/tests/auto/dbus/qdbusconnection_spyhook/tst_qdbusconnection_spyhook.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fa1c19920aa688c1d45a66f5e402ddd5a541531b --- /dev/null +++ b/tests/auto/dbus/qdbusconnection_spyhook/tst_qdbusconnection_spyhook.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Intel Corporation. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtDBus/QDBusMessage> + +#define HAS_HOOKSETUPFUNCTION 1 +static void hookSetupFunction(); + +// Ugly hack, look away +#include "../qdbusconnection/tst_qdbusconnection.cpp" + +QT_BEGIN_NAMESPACE +extern Q_DBUS_EXPORT void qDBusAddSpyHook(void (*Hook)(const QDBusMessage&)); +QT_END_NAMESPACE + +static void hookFunction(const QDBusMessage &) +{ +// qDebug() << "hook called"; + ++tst_QDBusConnection::hookCallCount; +} + +static void hookSetupFunction() +{ + QT_PREPEND_NAMESPACE(qDBusAddSpyHook)(hookFunction); +} + +QTEST_MAIN(tst_QDBusConnection_SpyHook) diff --git a/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp index 799ae3379d9e7959d989cb07422aaf41a51f6c09..5494959aaf9b2450ea2529acbda4d06054f31f53 100644 --- a/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp +++ b/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp @@ -402,6 +402,7 @@ public: VirtualObject() :success(true) {} QString introspect(const QString &path) const { + Q_ASSERT(QThread::currentThread() == thread()); if (path == "/some/path/superNode") return "zitroneneis"; if (path == "/some/path/superNode/foo") @@ -412,6 +413,7 @@ public: } bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection) { + Q_ASSERT(QThread::currentThread() == thread()); ++callCount; lastMessage = message; diff --git a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp index c614110b667b2a659a07f40c408cacb7a9c2a0cd..c5117228d3b5a5522d649169c5677461c75eaaca 100644 --- a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp @@ -37,6 +37,11 @@ #include <QtDBus/private/qdbusconnection_p.h> #include <QtDBus/private/qdbus_symbols_p.h> +#ifndef DBUS_TYPE_UNIX_FD +# define DBUS_TYPE_UNIX_FD int('h') +# define DBUS_TYPE_UNIX_FD_AS_STRING "h" +#endif + static const char serviceName[] = "org.qtproject.autotests.qpong"; static const char objectPath[] = "/org/qtproject/qpong"; static const char *interfaceName = serviceName; @@ -1084,9 +1089,6 @@ static bool canSendUnixFd(DBusConnection *connection) can_send_type = (can_send_type_t)qdbus_resolve_conditionally("dbus_connection_can_send_type"); #endif -#ifndef DBUS_TYPE_UNIX_FD -# define DBUS_TYPE_UNIX_FD int('h') -#endif return can_send_type && can_send_type(connection, DBUS_TYPE_UNIX_FD); } diff --git a/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp b/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp index ac9dadee47ced2227fda6a5feeaef46605611af5..2dbb078ae0c4a3a610fc56f93e53a5c9b5f4887e 100644 --- a/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp +++ b/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp @@ -50,6 +50,8 @@ private slots: void nextImageDelay(); void pngCompression_data(); void pngCompression(); + void write_data(); + void write(); private: QString m_IconPath; @@ -296,6 +298,51 @@ void tst_QIcoImageFormat::pngCompression() QCOMPARE(image.height(), height); } +void tst_QIcoImageFormat::write_data() +{ + QTest::addColumn<QSize>("inSize"); + QTest::addColumn<QSize>("outSize"); + + QTest::newRow("64x64") << QSize(64, 64) << QSize(64, 64); + QTest::newRow("128x200") << QSize(128, 200) << QSize(128, 200); + QTest::newRow("256x256") << QSize(256, 256) << QSize(256, 256); + QTest::newRow("400x400") << QSize(400, 400) << QSize(256, 256); +} + +void tst_QIcoImageFormat::write() +{ + QFETCH(QSize, inSize); + QFETCH(QSize, outSize); + + QImage inImg; + { + QImageReader reader(m_IconPath + "/valid/Qt.ico"); + reader.jumpToImage(4); + reader.setScaledSize(inSize); + inImg = reader.read(); + QVERIFY(!inImg.isNull()); + QCOMPARE(inImg.size(), inSize); + } + + QBuffer buf; + { + buf.open(QIODevice::WriteOnly); + QImageWriter writer(&buf, "ico"); + QVERIFY(writer.write(inImg)); + buf.close(); + } + { + buf.open(QIODevice::ReadOnly); + QImageReader reader(&buf); + QVERIFY(reader.canRead()); + QCOMPARE(reader.format(), QByteArray("ico")); + QImage outImg = reader.read(); + QVERIFY(!outImg.isNull()); + QCOMPARE(outImg.size(), outSize); + buf.close(); + } +} + QTEST_MAIN(tst_QIcoImageFormat) #include "tst_qicoimageformat.moc" diff --git a/tests/auto/gui/image/qicon/tst_qicon.cpp b/tests/auto/gui/image/qicon/tst_qicon.cpp index 3c4610a892abe97d10f00deee9e3af17d05c478b..a0914b7700fd16810fbf56cae7e3434fd8b0b43c 100644 --- a/tests/auto/gui/image/qicon/tst_qicon.cpp +++ b/tests/auto/gui/image/qicon/tst_qicon.cpp @@ -717,6 +717,7 @@ void tst_QIcon::fromThemeCache() QIcon::setThemeSearchPaths(QStringList()); QSKIP("gtk-update-icon-cache not run (binary not found)"); } +#ifndef QT_NO_PROCESS QProcess process; process.start(gtkUpdateIconCache, QStringList() << QStringLiteral("-f") << QStringLiteral("-t") << (dir.path() + QLatin1String("/testcache"))); @@ -726,6 +727,7 @@ void tst_QIcon::fromThemeCache() QVERIFY(process.waitForFinished()); QCOMPARE(process.exitStatus(), QProcess::NormalExit); QCOMPARE(process.exitCode(), 0); +#endif // QT_NO_PROCESS QVERIFY(QFileInfo(cacheName).lastModified() >= QFileInfo(dir.path() + QLatin1String("/testcache/16x16/actions")).lastModified()); QIcon::setThemeSearchPaths(QStringList() << dir.path()); // reload themes QVERIFY(!QIcon::fromTheme("button-open").isNull()); diff --git a/tests/auto/gui/image/qimagewriter/images/App.ico b/tests/auto/gui/image/qimagewriter/images/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..03b80a68f886fbc78e6fe34c59a3d4631ead2ef7 Binary files /dev/null and b/tests/auto/gui/image/qimagewriter/images/App.ico differ diff --git a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp index c12c8a9cf49a27277e013356d3723c8254e1e68d..4bf79cab055920a2975d68304b521c18691a69a0 100644 --- a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp +++ b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp @@ -179,6 +179,7 @@ void tst_QImageWriter::writeImage_data() QTest::newRow("PBM: ship63") << QString("ship63.pbm") << true << QByteArray("pbm"); QTest::newRow("XBM: gnus") << QString("gnus.xbm") << false << QByteArray("xbm"); QTest::newRow("JPEG: beavis") << QString("beavis.jpg") << true << QByteArray("jpeg"); + QTest::newRow("ICO: App") << QString("App.ico") << true << QByteArray("ico"); } void tst_QImageWriter::writeImage() @@ -240,7 +241,7 @@ void tst_QImageWriter::writeImage2_data() QTest::addColumn<QImage>("image"); const QStringList formats = QStringList() << "bmp" << "xpm" << "png" - << "ppm"; //<< "jpeg"; + << "ppm" << "ico"; //<< "jpeg"; QImage image0(70, 70, QImage::Format_ARGB32); image0.fill(QColor(Qt::red).rgb()); diff --git a/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp b/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp index 6c4399e96e4b113bb7d1bf0a90b346acd0485ee0..55053842dcbb95d3ddb3bfb4403732810f9b915f 100644 --- a/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp +++ b/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp @@ -47,6 +47,8 @@ private Q_SLOTS: void ntlmAuth_data(); void ntlmAuth(); + + void equalityOperators(); }; tst_QAuthenticator::tst_QAuthenticator() @@ -147,6 +149,20 @@ void tst_QAuthenticator::ntlmAuth() QVERIFY(priv->calculateResponse("GET", "/").startsWith("NTLM ")); } +void tst_QAuthenticator::equalityOperators() +{ + QAuthenticator s1, s2; + QVERIFY(s2 == s1); + QVERIFY(s1 == s2); + QVERIFY(!(s1 != s2)); + QVERIFY(!(s2 != s1)); + s1.setUser("User"); + QVERIFY(!(s2 == s1)); + QVERIFY(!(s1 == s2)); + QVERIFY(s1 != s2); + QVERIFY(s2 != s1); +} + QTEST_MAIN(tst_QAuthenticator); #include "tst_qauthenticator.moc" diff --git a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp index 204758f68aca47c5a626fb368ec3c52eb5b20ad2..c3229b495e36e2f75f25ac2832263ff6b939a4e4 100644 --- a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp +++ b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp @@ -158,8 +158,9 @@ void tst_Cmptest::compare_unregistered_enums() void tst_Cmptest::compare_registered_enums() { - QCOMPARE(Qt::ArrowCursor, Qt::ArrowCursor); - QCOMPARE(Qt::ArrowCursor, Qt::BusyCursor); + // use an enum that doesn't start at 0 + QCOMPARE(Qt::Monday, Qt::Monday); + QCOMPARE(Qt::Monday, Qt::Sunday); } void tst_Cmptest::compare_class_enums() diff --git a/tests/auto/testlib/selftests/expected_cmptest.lightxml b/tests/auto/testlib/selftests/expected_cmptest.lightxml index 440429e430bb769054b5b4494c6fa66c27f9c0aa..dc4a8a290e417424f54568bad97034426f7738b7 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.lightxml +++ b/tests/auto/testlib/selftests/expected_cmptest.lightxml @@ -16,8 +16,8 @@ <TestFunction name="compare_registered_enums"> <Incident type="fail" file="tst_cmptest.cpp" line="162"> <Description><![CDATA[Compared values are not the same - Actual (Qt::ArrowCursor): ArrowCursor - Expected (Qt::BusyCursor) : BusyCursor]]></Description> + Actual (Qt::Monday): Monday + Expected (Qt::Sunday): Sunday]]></Description> </Incident> <Duration msecs="0"/> </TestFunction> diff --git a/tests/auto/testlib/selftests/expected_cmptest.teamcity b/tests/auto/testlib/selftests/expected_cmptest.teamcity index dea19b60b4c1cfbc5685159d1dc35d6b9252ce72..8bcbfc50a9267cd42a77e372dc31498e4050a955 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.teamcity +++ b/tests/auto/testlib/selftests/expected_cmptest.teamcity @@ -5,7 +5,7 @@ ##teamcity[testFailed name='compare_unregistered_enums()' message='Failure! |[Loc: tst_cmptest.cpp(156)|]' details='Compared values are not the same'] ##teamcity[testFinished name='compare_unregistered_enums()'] ##teamcity[testStarted name='compare_registered_enums()'] -##teamcity[testFailed name='compare_registered_enums()' message='Failure! |[Loc: tst_cmptest.cpp(162)|]' details='Compared values are not the same|n Actual (Qt::ArrowCursor): ArrowCursor|n Expected (Qt::BusyCursor) : BusyCursor'] +##teamcity[testFailed name='compare_registered_enums()' message='Failure! |[Loc: tst_cmptest.cpp(162)|]' details='Compared values are not the same|n Actual (Qt::Monday): Monday|n Expected (Qt::Sunday): Sunday'] ##teamcity[testFinished name='compare_registered_enums()'] ##teamcity[testStarted name='compare_class_enums()'] ##teamcity[testFailed name='compare_class_enums()' message='Failure! |[Loc: tst_cmptest.cpp(168)|]' details='Compared values are not the same|n Actual (MyClassEnum::MyClassEnumValue1): MyClassEnumValue1|n Expected (MyClassEnum::MyClassEnumValue2): MyClassEnumValue2'] diff --git a/tests/auto/testlib/selftests/expected_cmptest.txt b/tests/auto/testlib/selftests/expected_cmptest.txt index 100fd5e8ef4ea58fbc99e657bf24ba069fbe930e..276383ce9dd52696224d3e34c6aec1f5e8492d9c 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.txt +++ b/tests/auto/testlib/selftests/expected_cmptest.txt @@ -4,8 +4,8 @@ PASS : tst_Cmptest::initTestCase() FAIL! : tst_Cmptest::compare_unregistered_enums() Compared values are not the same Loc: [tst_cmptest.cpp(156)] FAIL! : tst_Cmptest::compare_registered_enums() Compared values are not the same - Actual (Qt::ArrowCursor): ArrowCursor - Expected (Qt::BusyCursor) : BusyCursor + Actual (Qt::Monday): Monday + Expected (Qt::Sunday): Sunday Loc: [tst_cmptest.cpp(162)] FAIL! : tst_Cmptest::compare_class_enums() Compared values are not the same Actual (MyClassEnum::MyClassEnumValue1): MyClassEnumValue1 diff --git a/tests/auto/testlib/selftests/expected_cmptest.xml b/tests/auto/testlib/selftests/expected_cmptest.xml index f45d9ba1daa9dfcff3c1cebf801ff235481d10b9..ba5bd3dba63f888a9ffbedb18ac7f0911c9b848c 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.xml +++ b/tests/auto/testlib/selftests/expected_cmptest.xml @@ -18,8 +18,8 @@ <TestFunction name="compare_registered_enums"> <Incident type="fail" file="tst_cmptest.cpp" line="162"> <Description><![CDATA[Compared values are not the same - Actual (Qt::ArrowCursor): ArrowCursor - Expected (Qt::BusyCursor) : BusyCursor]]></Description> + Actual (Qt::Monday): Monday + Expected (Qt::Sunday): Sunday]]></Description> </Incident> <Duration msecs="0"/> </TestFunction> diff --git a/tests/auto/testlib/selftests/expected_cmptest.xunitxml b/tests/auto/testlib/selftests/expected_cmptest.xunitxml index ec2c3f023c39c49296837ef23b20ceefce2a2499..0b43fba654fef2c2cb212cbe99d03e78bc53d1c4 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.xunitxml +++ b/tests/auto/testlib/selftests/expected_cmptest.xunitxml @@ -11,8 +11,8 @@ </testcase> <testcase result="fail" name="compare_registered_enums"> <failure message="Compared values are not the same - Actual (Qt::ArrowCursor): ArrowCursor - Expected (Qt::BusyCursor) : BusyCursor" result="fail"/> + Actual (Qt::Monday): Monday + Expected (Qt::Sunday): Sunday" result="fail"/> </testcase> <testcase result="fail" name="compare_class_enums"> <failure message="Compared values are not the same diff --git a/tests/auto/tools/moc/backslash-newlines.h b/tests/auto/tools/moc/backslash-newlines.h index 20e9571c00fa786863cba1304b96a7f50a9304a5..081d80dc7ab2fa2fb0a2c6b33e5f37ce3e24c1d5 100644 --- a/tests/auto/tools/moc/backslash-newlines.h +++ b/tests/auto/tools/moc/backslash-newlines.h @@ -52,3 +52,5 @@ public slots: #undef value #endif // BACKSLASH_NEWLINES_H + +// ends with \\\r should not make moc crash (QTBUG-53441) (no new lines on purpose!!) \ \ No newline at end of file diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp index ef549d252b8ce284ebc642bcb6a88cdb460f9955..51ac2f0615733df20dbd60ccb989a12c93caedd3 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp @@ -550,6 +550,22 @@ void tst_QFiledialog::completer() if (expectedFile.startsWith(input, caseSensitivity)) ++expected; } + // The temporary dir may create a node in QFileSystemModel + // which will bypass filters. If the path to the temporary + // dir contains an element which should be a subdirectory + // of x dir, but which is not listed, then take it into + // accont. + if (!tempDir.isNull()) { + QString xPath = x.absolutePath(); + if (!xPath.endsWith(QLatin1Char('/'))) + xPath.append(QLatin1Char('/')); + QString tmpPath = tempDir->path(); + if (tmpPath.startsWith(xPath)) { + QString bypassedDirName = tmpPath.mid(xPath.size()).section(QLatin1Char('/'), 0, 0); + if (!expectedFiles.contains(bypassedDirName)) + ++expected; + } + } } QTRY_COMPARE(cModel->rowCount(), expected); diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp index 7939d88c73ba70887c08b1cfccc262807ce66d37..ff840a9e5af220737776890e0d467288754186d6 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -121,6 +121,8 @@ private slots: void doNotUnwatchOnFailedRmdir(); void specialFiles(); + void fileInfo(); + protected: bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &intial_dirs = QStringList()); @@ -1142,6 +1144,25 @@ void tst_QFileSystemModel::specialFiles() QTRY_VERIFY(!fileListUnderIndex(&model, rootIndex).contains(testFileName)); } +void tst_QFileSystemModel::fileInfo() +{ + QFileSystemModel model; + QModelIndex idx; + + QVERIFY(model.fileInfo(idx).filePath().isEmpty()); + + const QString dirPath = flatDirTestPath; + QDir dir(dirPath); + const QString subdir = QStringLiteral("subdir"); + QVERIFY(dir.mkdir(subdir)); + const QString subdirPath = dir.absoluteFilePath(subdir); + + idx = model.setRootPath(subdirPath); + QCOMPARE(model.fileInfo(idx), QFileInfo(subdirPath)); + idx = model.setRootPath(dirPath); + QCOMPARE(model.fileInfo(idx), QFileInfo(dirPath)); +} + QTEST_MAIN(tst_QFileSystemModel) #include "tst_qfilesystemmodel.moc" diff --git a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp index 6b964bc776aa5a532c04d8b892eb2a8cdbe14e12..a5aaf628557205cfdde1254ec949f36f98239edd 100644 --- a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp +++ b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp @@ -188,11 +188,14 @@ void tst_QFontDialog::task256466_wrongStyle() for (int i = 0; i < familyList->model()->rowCount(); ++i) { QModelIndex currentFamily = familyList->model()->index(i, 0); familyList->setCurrentIndex(currentFamily); + int expectedSize = sizeList->currentIndex().data().toInt(); const QFont current = dialog.currentFont(), expected = fdb.font(currentFamily.data().toString(), - styleList->currentIndex().data().toString(), sizeList->currentIndex().data().toInt()); + styleList->currentIndex().data().toString(), expectedSize); QCOMPARE(current.family(), expected.family()); QCOMPARE(current.style(), expected.style()); + if (expectedSize == 0 && !QFontDatabase().isScalable(current.family(), current.styleName())) + QEXPECT_FAIL("", "QTBUG-53299: Smooth sizes for unscalable font contains unsupported size", Continue); QCOMPARE(current.pointSizeF(), expected.pointSizeF()); } } diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index c93fc1288f4795fcd90530f3a6745f07a63ea28e..8253a44b217e18da887f4545f1332263c35348bd 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -3672,16 +3672,19 @@ static QByteArray msgPointMismatch(const QPoint &actual, const QPoint &expected) void tst_QGraphicsProxyWidget::mapToGlobal() // QTBUG-41135 { const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry(); - const QSize size = availableGeometry.size() / 5; + const QSize size = availableGeometry.size() / 4; QGraphicsScene scene; QGraphicsView view(&scene); + view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); view.setTransform(QTransform::fromScale(2, 2)); // QTBUG-50136, use transform. view.setWindowTitle(QTest::currentTestFunction()); view.resize(size); view.move(availableGeometry.bottomRight() - QPoint(size.width(), size.height()) - QPoint(100, 100)); - QWidget *embeddedWidget = new QWidget; - embeddedWidget->setFixedSize(size / 2); - QWidget *childWidget = new QWidget(embeddedWidget); + QWidget *embeddedWidget = new QGroupBox(QLatin1String("Embedded")); + embeddedWidget->setStyleSheet(QLatin1String("background-color: \"yellow\"; ")); + embeddedWidget->setFixedSize((size - QSize(10, 10)) / 2); + QWidget *childWidget = new QGroupBox(QLatin1String("Child"), embeddedWidget); childWidget->setStyleSheet(QLatin1String("background-color: \"red\"; ")); childWidget->resize(embeddedWidget->size() / 2); childWidget->move(embeddedWidget->width() / 4, embeddedWidget->height() / 4); // center in embeddedWidget @@ -3695,18 +3698,16 @@ void tst_QGraphicsProxyWidget::mapToGlobal() // QTBUG-41135 // This should be equivalent to the view center give or take rounding // errors due to odd window margins const QPoint viewCenter = view.geometry().center(); - QVERIFY2((viewCenter - embeddedCenterGlobal).manhattanLength() <= 2, + QVERIFY2((viewCenter - embeddedCenterGlobal).manhattanLength() <= 3, msgPointMismatch(embeddedCenterGlobal, viewCenter).constData()); - // Same test with child centered on embeddedWidget. The correct - // mapping is not implemented yet, but at least make sure + // Same test with child centered on embeddedWidget. Also make sure // the roundtrip maptoGlobal()/mapFromGlobal() returns the same // point since that is important for mouse event handling (QTBUG-50030, // QTBUG-50136). const QPoint childCenter = childWidget->rect().center(); const QPoint childCenterGlobal = childWidget->mapToGlobal(childCenter); QCOMPARE(childWidget->mapFromGlobal(childCenterGlobal), childCenter); - QEXPECT_FAIL("", "Not implemented for child widgets of embedded widgets", Continue); QVERIFY2((viewCenter - childCenterGlobal).manhattanLength() <= 4, msgPointMismatch(childCenterGlobal, viewCenter).constData()); } diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index f935d6eecf15888b026b0d4200fa22eeff19582b..725804480498043884adbd026911c10398d2e4a7 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -190,6 +190,7 @@ private slots: void taskQTBUG_8777_scrollToSpans(); void taskQTBUG_10169_sizeHintForRow(); void taskQTBUG_30653_doItemsLayout(); + void taskQTBUG_50171_selectRowAfterSwapColumns(); #ifndef QT_NO_WHEELEVENT void mouseWheel_data(); @@ -4488,5 +4489,40 @@ void tst_QTableView::taskQTBUG_7232_AllowUserToControlSingleStep() QCOMPARE(hStep1, t.horizontalScrollBar()->singleStep()); } +void tst_QTableView::taskQTBUG_50171_selectRowAfterSwapColumns() +{ + { + QtTestTableView tableView; + QtTestTableModel model(2, 3); + tableView.setModel(&model); + + tableView.horizontalHeader()->swapSections(1, 2); + tableView.horizontalHeader()->hideSection(0); + tableView.selectRow(1); + + QItemSelectionModel* tableSelectionModel = tableView.selectionModel(); + QCOMPARE(tableSelectionModel->isRowSelected(1, QModelIndex()), true); + QCOMPARE(tableSelectionModel->isSelected(tableView.model()->index(0, 0)), false); + QCOMPARE(tableSelectionModel->isSelected(tableView.model()->index(0, 1)), false); + QCOMPARE(tableSelectionModel->isSelected(tableView.model()->index(0, 2)), false); + } + + { + QtTestTableView tableView; + QtTestTableModel model(3, 2); + tableView.setModel(&model); + + tableView.verticalHeader()->swapSections(1, 2); + tableView.verticalHeader()->hideSection(0); + tableView.selectColumn(1); + + QItemSelectionModel* sModel = tableView.selectionModel(); + QCOMPARE(sModel->isColumnSelected(1, QModelIndex()), true); + QCOMPARE(sModel->isSelected(tableView.model()->index(0, 0)), false); + QCOMPARE(sModel->isSelected(tableView.model()->index(1, 0)), false); + QCOMPARE(sModel->isSelected(tableView.model()->index(2, 0)), false); + } +} + QTEST_MAIN(tst_QTableView) #include "tst_qtableview.moc" diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index 0a344cd52de4543ca365e0af2c322a768aed7f93..98a4caf49ea8f7bdde428eb10549a556247523e8 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -1,10 +1,8 @@ # OSX QTBUG-25300 QTBUG-45502 [normalGeometry] ubuntu-14.04 -osx [saveRestoreGeometry] ubuntu-14.04 -osx [restoreVersion1Geometry] ubuntu-14.04 osx @@ -21,20 +19,12 @@ ubuntu-14.04 ubuntu-14.04 [largerThanScreen_QTBUG30142] ubuntu-14.04 -[windowState] -osx [showMaximized] osx [setGeometry] osx -[stackUnder] -osx [raise] osx -[widgetAt] -osx -[sheetOpacity] -osx [resizeEvent] osx [setWindowGeometry] @@ -51,12 +41,6 @@ osx osx [render_systemClip] osx -[update] -osx -[doubleRepaint] -osx -[childAt_unifiedToolBar] -osx [showMinimizedKeepsFocus] osx-10.10 [moveWindowInShowEvent:1] diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index f2eaf6174ede90965fbbf8b34a99a007eb38ad4b..958bef3e6e48955febd25741d84b74a44d7c9b21 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -264,7 +264,6 @@ private slots: void widgetAt(); #ifdef Q_OS_OSX - void sheetOpacity(); void setMask(); #endif void optimizedResizeMove(); @@ -430,7 +429,6 @@ private slots: void movedAndResizedAttributes(); void childAt(); #ifdef Q_OS_OSX - void childAt_unifiedToolBar(); void taskQTBUG_11373(); #endif void taskQTBUG_17333_ResizeInfiniteRecursion(); @@ -1872,6 +1870,10 @@ void tst_QWidget::activation() void tst_QWidget::windowState() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + if (m_platform == QStringLiteral("xcb")) QSKIP("X11: Many window managers do not support window state properly, which causes this test to fail."); if (m_platform == QStringLiteral("wayland")) @@ -2083,6 +2085,10 @@ void tst_QWidget::showMaximized() void tst_QWidget::showFullScreen() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + if (m_platform == QStringLiteral("wayland")) QSKIP("Wayland: This fails. Figure out why."); QWidget plain; @@ -2442,6 +2448,10 @@ void tst_QWidget::reparent() // Qt/Embedded does it differently. void tst_QWidget::icon() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + QPixmap p(20,20); p.fill(Qt::red); testWidget->setWindowIcon(p); @@ -2493,6 +2503,10 @@ void tst_QWidget::hideWhenFocusWidgetIsChild() void tst_QWidget::normalGeometry() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + if (m_platform == QStringLiteral("wayland")) QSKIP("Wayland: This fails. Figure out why."); QWidget parent; @@ -2843,8 +2857,6 @@ void tst_QWidget::raise() } } -// Cocoa has no Z-Order for views, we hack it, but it results in paint events. -#ifndef QT_OS_MAC void tst_QWidget::lower() { QScopedPointer<QWidget> parent(new QWidget); @@ -2906,12 +2918,13 @@ void tst_QWidget::lower() list2 << child4 << child1 << child2 << child3; QCOMPARE(parent->children(), list2); } -#endif -// Cocoa has no Z-Order for views, we hack it, but it results in paint events. -#ifndef QT_OS_MAC void tst_QWidget::stackUnder() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974: Cocoa has no Z-Order for views, we hack it, but it results in paint events."); +#endif + QScopedPointer<QWidget> parent(new QWidget); parent->setObjectName(QLatin1String("stackUnder")); parent->setWindowTitle(parent->objectName()); @@ -2992,7 +3005,6 @@ void tst_QWidget::stackUnder() child->reset(); } } -#endif void drawPolygon(QPaintDevice *dev, int w, int h) { @@ -3081,6 +3093,10 @@ void tst_QWidget::testContentsPropagation() void tst_QWidget::saveRestoreGeometry() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + if (m_platform == QStringLiteral("wayland")) QSKIP("Wayland: This fails. Figure out why."); const QPoint position = m_availableTopLeft + QPoint(100, 100); @@ -3306,6 +3322,10 @@ void tst_QWidget::restoreVersion1Geometry() void tst_QWidget::widgetAt() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + if (m_platform == QStringLiteral("wayland")) QSKIP("Wayland: This fails. Figure out why."); Q_CHECK_PAINTEVENTS @@ -3519,17 +3539,6 @@ void tst_QWidget::testDeletionInEventHandlers() } #ifdef Q_OS_OSX -void tst_QWidget::sheetOpacity() -{ - QWidget tmpWindow; - QWidget sheet(&tmpWindow, Qt::Sheet); - tmpWindow.show(); - sheet.show(); - QCOMPARE(int(sheet.windowOpacity() * 255), 242); // 95% - sheet.setParent(0, Qt::Dialog); - QCOMPARE(int(sheet.windowOpacity() * 255), 255); -} - class MaskedPainter : public QWidget { public: @@ -4171,6 +4180,10 @@ void tst_QWidget::showHideEventWhileMinimize() void tst_QWidget::update() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + QTest::qWait(10); // Wait for the initStuff to do it's stuff. Q_CHECK_PAINTEVENTS @@ -5160,10 +5173,13 @@ void tst_QWidget::showAndMoveChild() VERIFY_COLOR(parent, QRegion(parent.rect()) - child.geometry(), Qt::red); } -// Cocoa only has rect granularity. -#ifndef QT_OS_MAC + void tst_QWidget::subtractOpaqueSiblings() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974: Cocoa only has rect granularity."); +#endif + QWidget w; w.setGeometry(50, 50, 300, 300); @@ -5196,7 +5212,6 @@ void tst_QWidget::subtractOpaqueSiblings() QRegion(medium->geometry().translated(large->pos())) - tall->geometry()); } -#endif void tst_QWidget::deleteStyle() { @@ -5238,6 +5253,10 @@ public slots: void tst_QWidget::multipleToplevelFocusCheck() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + if (m_platform == QStringLiteral("wayland")) QSKIP("Wayland: This fails. Figure out why."); TopLevelFocusCheck w1; @@ -7911,6 +7930,10 @@ void tst_QWidget::sendUpdateRequestImmediately() void tst_QWidget::doubleRepaint() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + #if defined(Q_OS_OSX) if (!macHasAccessToWindowsServer()) QSKIP("Not having window server access causes the wrong number of repaints to be issues"); @@ -9427,10 +9450,6 @@ void tst_QWidget::taskQTBUG_7532_tabOrderWithFocusProxy() void tst_QWidget::movedAndResizedAttributes() { -#if defined (Q_OS_OSX) - QEXPECT_FAIL("", "FixMe, QTBUG-8941 and QTBUG-8977", Abort); - QVERIFY(false); -#else // Use Qt::Tool as fully decorated windows have a minimum width of 160 on QWidget w(0, Qt::Tool); w.show(); @@ -9476,7 +9495,6 @@ void tst_QWidget::movedAndResizedAttributes() w.resize(100, 100); QVERIFY(w.testAttribute(Qt::WA_Moved)); QVERIFY(w.testAttribute(Qt::WA_Resized)); -#endif } void tst_QWidget::childAt() @@ -9535,46 +9553,11 @@ void tst_QWidget::childAt() } #ifdef Q_OS_OSX -void tst_QWidget::childAt_unifiedToolBar() -{ - QLabel *label = new QLabel(QLatin1String("foo")); - QToolBar *toolBar = new QToolBar; - toolBar->addWidget(new QLabel("dummy")); - toolBar->addWidget(label); - - QMainWindow mainWindow; - mainWindow.addToolBar(toolBar); - mainWindow.show(); - - // Calculate the top-left corner of the tool bar and the label (in mainWindow's coordinates). - QPoint labelTopLeft = label->mapTo(&mainWindow, QPoint()); - QPoint toolBarTopLeft = toolBar->mapTo(&mainWindow, QPoint()); - - QCOMPARE(mainWindow.childAt(toolBarTopLeft), static_cast<QWidget *>(toolBar)); - QCOMPARE(mainWindow.childAt(labelTopLeft), static_cast<QWidget *>(label)); - - // Enable unified tool bars. - mainWindow.setUnifiedTitleAndToolBarOnMac(true); - QTest::qWait(50); - - // The tool bar is now in the "non-client" area of QMainWindow, i.e. - // outside the mainWindow's rect(), and since mapTo et al. doesn't work - // in that case (see commit 35667fd45ada49269a5987c235fdedfc43e92bb8), - // we use mapToGlobal/mapFromGlobal to re-calculate the corners. - QPoint oldToolBarTopLeft = toolBarTopLeft; - toolBarTopLeft = mainWindow.mapFromGlobal(toolBar->mapToGlobal(QPoint())); - QVERIFY2(toolBarTopLeft != oldToolBarTopLeft, - msgComparisonFailed(toolBarTopLeft, "!=", oldToolBarTopLeft)); - QVERIFY2(toolBarTopLeft.y() < 0, - msgComparisonFailed(toolBarTopLeft.y(), "<", 0)); - labelTopLeft = mainWindow.mapFromGlobal(label->mapToGlobal(QPoint())); - - QCOMPARE(mainWindow.childAt(toolBarTopLeft), static_cast<QWidget *>(toolBar)); - QCOMPARE(mainWindow.childAt(labelTopLeft), static_cast<QWidget *>(label)); -} void tst_QWidget::taskQTBUG_11373() { + QSKIP("QTBUG-52974"); + QScopedPointer<QMainWindow> myWindow(new QMainWindow); QWidget * center = new QWidget(); myWindow -> setCentralWidget(center); @@ -9590,6 +9573,7 @@ void tst_QWidget::taskQTBUG_11373() // The drawer should still not be visible, since we haven't shown it. QCOMPARE(drawer->isVisible(), false); } + #endif void tst_QWidget::taskQTBUG_17333_ResizeInfiniteRecursion() @@ -10437,6 +10421,9 @@ public: // when mousing over it. void tst_QWidget::taskQTBUG_27643_enterEvents() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974: this test can crash!"); +#endif // Move the mouse cursor to a safe location so it won't interfere QCursor::setPos(m_safeCursorPos); diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index d568cf63d46523cfbaf91b9f5ebc6824f3bbbe10..809fa56a61b864a6355bb6718a38d7a22393fac0 100644 --- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp @@ -494,7 +494,7 @@ void tst_QMdiArea::subWindowActivated2() mdiArea.show(); mdiArea.activateWindow(); QVERIFY(QTest::qWaitForWindowActive(&mdiArea)); - QTRY_COMPARE(spy.count(), 1); + QTRY_VERIFY(!spy.isEmpty()); // Normally 1, but 2 events might be received on some X11 window managers QVERIFY(mdiArea.currentSubWindow()); QTRY_COMPARE(mdiArea.activeSubWindow(), activeSubWindow); spy.clear(); diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp index 3bcdea31370faeb59e8b8df2af34a6c6e519c92e..4b4bec99201031b576628fee22ef5421b0821b49 100644 --- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp @@ -127,10 +127,12 @@ private slots: void closeOnSecondClickAndOpenOnThirdClick(); void cornerWidgets_data(); void cornerWidgets(); + void taskQTBUG53205_crashReparentNested(); protected slots: void onSimpleActivated( QAction*); void onComplexActionTriggered(); + void slotForTaskQTBUG53205(); private: TestMenu initSimpleMenuBar(QMenuBar *mb); @@ -143,6 +145,7 @@ private: QAction* m_lastSimpleAcceleratorId; int m_simpleActivatedCount; int m_complexTriggerCount[int('k')]; + QMenuBar* taskQTBUG53205MenuBar; }; // Testing get/set functions @@ -1438,5 +1441,61 @@ void tst_QMenuBar::cornerWidgets() delete cornerLabel; } + +void tst_QMenuBar::taskQTBUG53205_crashReparentNested() +{ + // This test was largely inspired by the test case submitted for the bug + QMainWindow mainWindow; + mainWindow.resize(300, 200); + centerOnScreen(&mainWindow); + const TestMenu testMenus = initWindowWithComplexMenuBar(mainWindow); + QApplication::setActiveWindow(&mainWindow); + + // they can't be windows + QWidget hiddenParent(&mainWindow, 0); + //this one is going to be moved around + QWidget movingParent(&hiddenParent, 0); + + //set up the container widget + QWidget containerWidget(&movingParent,0); + + //set the new parent, a window + QScopedPointer<QWidget> windowedParent; + windowedParent.reset(new QWidget(Q_NULLPTR, Qt::WindowFlags())); + windowedParent->setGeometry(400, 10, 300, 300); + + windowedParent->show(); + QVERIFY(QTest::qWaitForWindowExposed(windowedParent.data())); + + //set the "container", can't be a window + QWidget containedWidget(&containerWidget, 0); + + taskQTBUG53205MenuBar = new QMenuBar(&containedWidget); + + connect(testMenus.actions[0], &QAction::triggered, this, &tst_QMenuBar::slotForTaskQTBUG53205); + //now, move things around + //from : QMainWindow<-hiddenParent<-movingParent<-containerWidget<-containedWidget<-menuBar + //to windowedParent<-movingParent<-containerWidget<-containedWidget<-menuBar + movingParent.setParent(windowedParent.data(),0); + // this resets the parenting and the menu bar's window + taskQTBUG53205MenuBar->setParent(Q_NULLPTR); + taskQTBUG53205MenuBar->setParent(&containedWidget); + //from windowedParent<-movingParent<-containerWidget<-containedWidget<-menuBar + //to : QMainWindow<-hiddenParent<-movingParent<-containerWidget<-containedWidget<-menuBar + movingParent.setParent(&hiddenParent,0); + windowedParent.reset(); //make the old window invalid + // trigger the aciton, reset the menu bar's window, this used to crash here. + testMenus.actions[0]->trigger(); +} + +void tst_QMenuBar::slotForTaskQTBUG53205() +{ + QWidget *parent = taskQTBUG53205MenuBar->parentWidget(); + taskQTBUG53205MenuBar->setParent(Q_NULLPTR); + taskQTBUG53205MenuBar->setParent(parent); +} + + + QTEST_MAIN(tst_QMenuBar) #include "tst_qmenubar.moc" diff --git a/tests/baselineserver/src/baselineserver.pro b/tests/baselineserver/src/baselineserver.pro index 519cacea9cf5afe41d4106b39b708d4eb1281478..a77014c1e60838d613df28c77e342709451330f0 100644 --- a/tests/baselineserver/src/baselineserver.pro +++ b/tests/baselineserver/src/baselineserver.pro @@ -1,9 +1,3 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2010-08-11T11:51:09 -# -#------------------------------------------------- - QT += core network # gui needed for QImage diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index bec098d462635d462aabaf469baee1ae9f9663ef..8e77a321dd76e2935e8eecd7e1b73a1b31ab3b4d 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -24,6 +24,7 @@ qnetworkaccessmanager/qget \ qnetworkconfigurationmanager \ qnetworkconfiguration \ qnetworkreply \ +qstorageinfo \ qscreen \ qssloptions \ qsslsocket \ diff --git a/tests/manual/qcursor/allcursors/allcursors.pro b/tests/manual/qcursor/allcursors/allcursors.pro index b9f6a0c98dc1be50e0c16d19ec4ed0ed969bd121..abfb08e78619ef2e2a7a06574932e293a9e9ee39 100644 --- a/tests/manual/qcursor/allcursors/allcursors.pro +++ b/tests/manual/qcursor/allcursors/allcursors.pro @@ -1,9 +1,3 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2009-08-05T17:13:23 -# -#------------------------------------------------- - TARGET = tst_allcursors TEMPLATE = app QT = core gui widgets diff --git a/tests/manual/qcursor/grab_override/grab_override.pro b/tests/manual/qcursor/grab_override/grab_override.pro index d84e2ee2b85b62944a856180d4f29259faf3b8d8..1254e5ee367a6fd089f616275b3cbe8232c3a747 100644 --- a/tests/manual/qcursor/grab_override/grab_override.pro +++ b/tests/manual/qcursor/grab_override/grab_override.pro @@ -1,9 +1,3 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2009-08-05T17:13:23 -# -#------------------------------------------------- - TARGET = t_cursors TEMPLATE = app QT = core gui widgets diff --git a/tests/manual/qstorageinfo/main.cpp b/tests/manual/qstorageinfo/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..61cdd5592209055fc1551d2ca4ccd3c9da0a6a87 --- /dev/null +++ b/tests/manual/qstorageinfo/main.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Intel Corporation +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QCoreApplication> + +#include <stdio.h> + +#include "printvolumes.cpp" + +int main(int argc, char *argv[]) +{ + QCoreApplication a(argc, argv); + + QList<QStorageInfo> volumes; + QStringList args = a.arguments(); + args.takeFirst(); // skip application name + + foreach (const QString &path, args) { + QStorageInfo info(path); + if (!info.isValid()) { + // no error string... + fprintf(stderr, "Could not get info on %s\n", qPrintable(path)); + return 1; + } + volumes << info; + } + + if (volumes.isEmpty()) + volumes = QStorageInfo::mountedVolumes(); + + printVolumes(volumes, printf); + + return 0; +} diff --git a/tests/manual/qstorageinfo/printvolumes.cpp b/tests/manual/qstorageinfo/printvolumes.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1b1660b433059a82ba1878c34e601f9bedf50361 --- /dev/null +++ b/tests/manual/qstorageinfo/printvolumes.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Intel Corporation +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QStorageInfo> + +void printVolumes(const QList<QStorageInfo> &volumes, int (*printer)(const char *, ...)) +{ + // Sample output: + // Filesystem (Type) Size Available BSize Label Mounted on + // /dev/sda2 (ext4) RO 388480 171218 1024 /boot + // /dev/mapper/system-root (btrfs) RW + // 214958080 39088272 4096 / + // /dev/disk1s2 (hfs) RW 488050672 419909696 4096 Macintosh HD2 /Volumes/Macintosh HD2 + + printf("Filesystem (Type) Size Available BSize Label Mounted on\n"); + foreach (const QStorageInfo &info, volumes) { + QByteArray fsAndType = info.device(); + if (info.fileSystemType() != fsAndType) + fsAndType += " (" + info.fileSystemType() + ')'; + + printf("%-19s R%c ", fsAndType.constData(), info.isReadOnly() ? 'O' : 'W'); + if (fsAndType.size() > 19) + printf("\n%23s", ""); + + printf("%10llu %10llu %5u ", info.bytesTotal() / 1024, info.bytesFree() / 1024, info.blockSize()); + printf("%-16s %s\n", qPrintable(info.name()), qPrintable(info.rootPath())); + } +} diff --git a/tests/manual/qstorageinfo/qstorageinfo.pro b/tests/manual/qstorageinfo/qstorageinfo.pro new file mode 100644 index 0000000000000000000000000000000000000000..25acd24c806b53e33c40af719e7b58edb7c6b31c --- /dev/null +++ b/tests/manual/qstorageinfo/qstorageinfo.pro @@ -0,0 +1,4 @@ +QT = core +CONFIG += console +CONFIG -= app_bundle +SOURCES += main.cpp diff --git a/tests/manual/qtbug-8933/qtbug-8933.pro b/tests/manual/qtbug-8933/qtbug-8933.pro index 4600d47cac19cef012a61e5f02f1f7e895d8198e..a206939b48f562fef26a9ebd2b8befffbbacfcfe 100644 --- a/tests/manual/qtbug-8933/qtbug-8933.pro +++ b/tests/manual/qtbug-8933/qtbug-8933.pro @@ -1,9 +1,3 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2010-03-16T14:40:16 -# -#------------------------------------------------- - TARGET = qtbug-8933 TEMPLATE = app QT += widgets diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 6c3e20577bdbb656bd7ccc82341d10e687179291..e3eb5220becc4f915ac057d67905dac4676bb410 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -257,6 +257,7 @@ Configure::Configure(int& argc, char** argv) : verbose(0) dictionary[ "LIBPNG" ] = "auto"; dictionary[ "DOUBLECONVERSION" ] = "auto"; dictionary[ "FREETYPE" ] = "yes"; + dictionary[ "FREETYPE_FROM" ] = "default"; dictionary[ "HARFBUZZ" ] = "qt"; dictionary[ "ACCESSIBILITY" ] = "yes"; @@ -628,12 +629,16 @@ void Configure::parseCmdLine() dictionary[ "DOUBLECONVERSION" ] = "system"; // Text Rendering -------------------------------------------- - else if (configCmdLine.at(i) == "-no-freetype") + else if (configCmdLine.at(i) == "-no-freetype") { dictionary[ "FREETYPE" ] = "no"; - else if (configCmdLine.at(i) == "-qt-freetype") + dictionary[ "FREETYPE_FROM" ] = "commandline"; + } else if (configCmdLine.at(i) == "-qt-freetype") { dictionary[ "FREETYPE" ] = "yes"; - else if (configCmdLine.at(i) == "-system-freetype") + dictionary[ "FREETYPE_FROM" ] = "commandline"; + } else if (configCmdLine.at(i) == "-system-freetype") { dictionary[ "FREETYPE" ] = "system"; + dictionary[ "FREETYPE_FROM" ] = "commandline"; + } else if (configCmdLine.at(i) == "-no-harfbuzz") dictionary[ "HARFBUZZ" ] = "no"; @@ -2498,6 +2503,9 @@ void Configure::autoDetection() if (dictionary["FONT_CONFIG"] == "auto") dictionary["FONT_CONFIG"] = checkAvailability("FONT_CONFIG") ? "yes" : "no"; + if ((dictionary["FONT_CONFIG"] == "yes") && (dictionary["FREETYPE_FROM"] == "default")) + dictionary["FREETYPE"] = "system"; + if (dictionary["DOUBLECONVERSION"] == "auto") dictionary["DOUBLECONVERSION"] = checkAvailability("DOUBLECONVERSION") ? "system" : "qt"; @@ -2634,6 +2642,22 @@ bool Configure::verifyConfiguration() } } + if ((dictionary["FONT_CONFIG"] == "yes") && (dictionary["FREETYPE_FROM"] == "commandline")) { + if (dictionary["FREETYPE"] == "yes") { + cout << "WARNING: Bundled FreeType can't be used." + " FontConfig use requires system FreeType." << endl; + dictionary["FREETYPE"] = "system"; + dictionary["FREETYPE_FROM"] = "override"; + prompt = true; + } else if (dictionary["FREETYPE"] == "no") { + cout << "WARNING: FreeType can't be disabled." + " FontConfig use requires system FreeType." << endl; + dictionary["FREETYPE"] = "system"; + dictionary["FREETYPE_FROM"] = "override"; + prompt = true; + } + } + if (prompt) promptKeyPress();