diff options
470 files changed, 5677 insertions, 3267 deletions
diff --git a/.qmake.conf b/.qmake.conf index 732b5da262..53993bd4fe 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -5,4 +5,4 @@ CONFIG += warning_clean QT_SOURCE_TREE = $$PWD QT_BUILD_TREE = $$shadowed($$PWD) -MODULE_VERSION = 5.6.0 +MODULE_VERSION = 5.6.1 diff --git a/config.tests/unix/alsa/alsatest.cpp b/config.tests/unix/alsa/alsatest.cpp index cab6533977..0b45819b61 100644 --- a/config.tests/unix/alsa/alsatest.cpp +++ b/config.tests/unix/alsa/alsatest.cpp @@ -32,7 +32,7 @@ ****************************************************************************/ #include <alsa/asoundlib.h> -#if(!(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 10)) +#if SND_LIB_VERSION < 0x1000a // 1.0.10 #error "Alsa version found too old, require >= 1.0.10" #endif diff --git a/config.tests/unix/journald/journald.pro b/config.tests/unix/journald/journald.pro index 2bb50ceb71..ea765642e6 100644 --- a/config.tests/unix/journald/journald.pro +++ b/config.tests/unix/journald/journald.pro @@ -1,6 +1,10 @@ SOURCES = journald.c CONFIG += link_pkgconfig -PKGCONFIG_PRIVATE += libsystemd-journal + +packagesExist(libsystemd): \ + PKGCONFIG_PRIVATE += libsystemd +else: \ + PKGCONFIG_PRIVATE += libsystemd-journal CONFIG -= qt diff --git a/config.tests/unix/libdl/libdl.cpp b/config.tests/unix/libdl/libdl.cpp new file mode 100644 index 0000000000..28a82330f2 --- /dev/null +++ b/config.tests/unix/libdl/libdl.cpp @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the config.tests 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 <dlfcn.h> + +int main(int, char **) +{ + dlopen(0, 0); +} diff --git a/config.tests/unix/libdl/libdl.pro b/config.tests/unix/libdl/libdl.pro new file mode 100644 index 0000000000..00d4c47c6c --- /dev/null +++ b/config.tests/unix/libdl/libdl.pro @@ -0,0 +1,3 @@ +SOURCES = libdl.cpp +CONFIG -= qt dylib +LIBS += -ldl @@ -4734,6 +4734,12 @@ if [ "$CFG_LIBPNG" = "auto" ]; then fi fi +# detect dl +if ! compileTest unix/libdl "libdl"; then + QMakeVar add DEFINES QT_NO_DYNAMIC_LIBRARY + QMAKE_CONFIG="$QMAKE_CONFIG no-libdl" +fi + if [ "$CFG_EGLFS" = "yes" ]; then if [ "$CFG_EGL" = "no" ]; then echo "The EGLFS plugin requires EGL support and cannot be built" @@ -6433,9 +6439,9 @@ fi [ "$CFG_SYSTEM_PROXIES" = "yes" ] && QT_CONFIG="$QT_CONFIG system-proxies" [ "$CFG_DIRECTWRITE" = "yes" ] && QT_CONFIG="$QT_CONFIG directwrite" -[ '!' -z "$DEFINES" ] && QMakeVar add DEFINES "$DEFINES" -[ '!' -z "$INCLUDES" ] && QMakeVar add INCLUDEPATH "$INCLUDES" -[ '!' -z "$L_FLAGS" ] && QMakeVar add LIBS "$L_FLAGS" +[ '!' -z "$DEFINES" ] && QMakeVar add EXTRA_DEFINES "$DEFINES" +[ '!' -z "$INCLUDES" ] && QMakeVar add EXTRA_INCLUDEPATH "$INCLUDES" +[ '!' -z "$L_FLAGS" ] && QMakeVar add EXTRA_LIBS "$L_FLAGS" if [ -z "`getXQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then if [ -n "$RPATH_FLAGS" ]; then @@ -6451,7 +6457,7 @@ if [ -z "`getXQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then else if [ -n "$RPATH_FLAGS" ]; then # add the user defined rpaths - QMakeVar add QMAKE_RPATHDIR "$RPATH_FLAGS" + QMakeVar add EXTRA_RPATHS "$RPATH_FLAGS" fi fi if [ "$CFG_RPATH" = "yes" ]; then @@ -7042,9 +7048,6 @@ if [ -n "$CFG_SYSROOT" ] && [ "$CFG_GCC_SYSROOT" = "yes" ]; then echo "}" echo fi -if [ -n "$RPATH_FLAGS" ]; then - echo "QMAKE_RPATHDIR += $RPATH_FLAGS" -fi echo "QT_COMPILER_STDCXX = $CFG_STDCXX_DEFAULT" if [ -n "$QT_GCC_MAJOR_VERSION" ]; then echo "QT_GCC_MAJOR_VERSION = $QT_GCC_MAJOR_VERSION" diff --git a/doc/global/manifest-meta.qdocconf b/doc/global/manifest-meta.qdocconf index c45470838a..f535f5e290 100644 --- a/doc/global/manifest-meta.qdocconf +++ b/doc/global/manifest-meta.qdocconf @@ -55,9 +55,7 @@ manifestmeta.highlighted.names = "QtQuick/Qt Quick Demo - Same Game" \ "QtMultimedia/QML Video Shader Effects Example" \ "QtCanvas3D/Planets Example" \ "QtCanvas3D/Interactive Mobile Phone Example" \ - "QtLocation/Map Viewer (QML)" \ - "QtWebEngine/WebEngine Quick Nano Browser" \ - "QtWebEngine/Markdown Editor Example" + "QtLocation/Map Viewer (QML)" manifestmeta.highlighted.attributes = isHighlighted:true diff --git a/doc/global/qt-cpp-defines.qdocconf b/doc/global/qt-cpp-defines.qdocconf index 967bbb8ede..54d2cbbe4e 100644 --- a/doc/global/qt-cpp-defines.qdocconf +++ b/doc/global/qt-cpp-defines.qdocconf @@ -161,3 +161,7 @@ Cpp.ignoredirectives += \ QT_WARNING_DISABLE_MSVC \ Q_ATTRIBUTE_FORMAT_PRINTF \ Q_MV_IOS + +# Qt 6: Remove +falsehoods += \ + "QT_VERSION >= QT_VERSION_CHECK\\(6,0,0\\)" diff --git a/examples/corelib/ipc/sharedmemory/qt.png b/examples/corelib/ipc/sharedmemory/qt.png Binary files differindex 60ef558efe..4f68e162de 100644 --- a/examples/corelib/ipc/sharedmemory/qt.png +++ b/examples/corelib/ipc/sharedmemory/qt.png diff --git a/examples/network/torrent/mainwindow.cpp b/examples/network/torrent/mainwindow.cpp index 2b87f71294..bfe221c129 100644 --- a/examples/network/torrent/mainwindow.cpp +++ b/examples/network/torrent/mainwindow.cpp @@ -702,7 +702,7 @@ void TorrentView::dragMoveEvent(QDragMoveEvent *event) { // Accept file actions with a '.torrent' extension. QUrl url(event->mimeData()->text()); - if (url.isValid() && url.scheme().toLower() == "file" + if (url.isValid() && url.scheme() == "file" && url.path().toLower().endsWith(".torrent")) event->acceptProposedAction(); } diff --git a/examples/opengl/qopenglwidget/qt.png b/examples/opengl/qopenglwidget/qt.png Binary files differindex 79e383cf50..4f68e162de 100644 --- a/examples/opengl/qopenglwidget/qt.png +++ b/examples/opengl/qopenglwidget/qt.png diff --git a/examples/widgets/dialogs/standarddialogs/dialog.cpp b/examples/widgets/dialogs/standarddialogs/dialog.cpp index b28cf0f934..462ba211c0 100644 --- a/examples/widgets/dialogs/standarddialogs/dialog.cpp +++ b/examples/widgets/dialogs/standarddialogs/dialog.cpp @@ -103,7 +103,6 @@ Dialog::Dialog(QWidget *parent) QHBoxLayout *horizontalLayout = new QHBoxLayout(this); QGroupBox *groupBox = new QGroupBox(QGuiApplication::applicationDisplayName(), this); horizontalLayout->addWidget(groupBox); - horizontalLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::Ignored)); verticalLayout = new QVBoxLayout(groupBox); } else { verticalLayout = new QVBoxLayout(this); diff --git a/examples/widgets/itemviews/pixelator/images/qt.png b/examples/widgets/itemviews/pixelator/images/qt.png Binary files differindex a2c9c77c16..dd197cb59c 100644 --- a/examples/widgets/itemviews/pixelator/images/qt.png +++ b/examples/widgets/itemviews/pixelator/images/qt.png diff --git a/examples/widgets/mainwindows/mainwindow/qt.png b/examples/widgets/mainwindows/mainwindow/qt.png Binary files differindex 48fa9fc2ef..4f68e162de 100644 --- a/examples/widgets/mainwindows/mainwindow/qt.png +++ b/examples/widgets/mainwindows/mainwindow/qt.png diff --git a/mkspecs/common/wince/qplatformdefs.h b/mkspecs/common/wince/qplatformdefs.h index a351c886ba..4faa344e55 100644 --- a/mkspecs/common/wince/qplatformdefs.h +++ b/mkspecs/common/wince/qplatformdefs.h @@ -52,7 +52,6 @@ #include <tchar.h> #include <stdio.h> #include <stdlib.h> -#include <windows.h> #ifdef QT_LARGEFILE_SUPPORT #define QT_STATBUF struct _stati64 // non-ANSI defs diff --git a/mkspecs/features/benchmark.prf b/mkspecs/features/benchmark.prf new file mode 100644 index 0000000000..bfae922700 --- /dev/null +++ b/mkspecs/features/benchmark.prf @@ -0,0 +1 @@ +load(testcase) diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf index cd8d8859aa..561c8f4858 100644 --- a/mkspecs/features/default_post.prf +++ b/mkspecs/features/default_post.prf @@ -95,7 +95,10 @@ breakpad { !isEmpty(QMAKE_STRIP):QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)$$quote($$QMAKE_STRIP $$DEBUGFILENAME) } -c++11|c++14|c++1z { +# Disable special compiler flags for host builds (needs to be changed for 5.7 +# to fall back to c++11 because since 5.7 c++11 is required everywhere, +# including host builds). +if(!host_build|!cross_compile):if(c++11|c++14|c++1z) { c++1z: cxxstd = CXX1Z else: c++14: cxxstd = CXX14 else: cxxstd = CXX11 diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index f62b6bb139..5cc176c2ae 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -160,21 +160,8 @@ qt_module_deps = $$resolve_depends(qt_module_deps, "QT.") contains(qt_module_deps, core) { relative_qt_rpath:!isEmpty(QMAKE_REL_RPATH_BASE):contains(INSTALLS, target):\ isEmpty(target.files):isEmpty(target.commands):isEmpty(target.extra) { - mac { - if(equals(TEMPLATE, app):app_bundle)|\ - if(equals(TEMPLATE, lib):plugin:plugin_bundle) { - ios: binpath = $$target.path/$${TARGET}.app - else: binpath = $$target.path/$${TARGET}.app/Contents/MacOS - } else: equals(TEMPLATE, lib):!plugin:lib_bundle { - binpath = $$target.path/$${TARGET}.framework/Versions/Current - } else { - binpath = $$target.path - } - } else { - binpath = $$target.path - } # NOT the /dev property, as INSTALLS use host paths - QMAKE_RPATHDIR += $$relative_path($$[QT_INSTALL_LIBS], $$binpath) + QMAKE_RPATHDIR += $$relative_path($$[QT_INSTALL_LIBS], $$qtRelativeRPathBase()) } else { QMAKE_RPATHDIR += $$[QT_INSTALL_LIBS/dev] } diff --git a/mkspecs/features/qt_build_config.prf b/mkspecs/features/qt_build_config.prf index 518fd93f04..2d437e7f91 100644 --- a/mkspecs/features/qt_build_config.prf +++ b/mkspecs/features/qt_build_config.prf @@ -52,6 +52,9 @@ QMAKE_DIR_REPLACE_SANE = PRECOMPILED_DIR OBJECTS_DIR MOC_DIR RCC_DIR UI_DIR unset(modpath) } +# Apply extra compiler flags passed via configure last. +CONFIG = qt_build_extra $$CONFIG + # Don't actually try to install anything in non-prefix builds. # This is much easier and safer than making every single INSTALLS # assignment conditional. @@ -72,6 +75,10 @@ CONFIG += \ # However, testcases should be still built with exceptions. exceptions_off testcase_exceptions +# Under Windows, this is neither necessary (transitive deps are automatically +# resolved), nor functional (.res files end up in .prl files and break things). +unix: CONFIG += explicitlib + defineTest(qtBuildPart) { bp = $$eval($$upper($$section(_QMAKE_CONF_, /, -2, -2))_BUILD_PARTS) diff --git a/mkspecs/features/qt_build_extra.prf b/mkspecs/features/qt_build_extra.prf new file mode 100644 index 0000000000..378f5bbd7c --- /dev/null +++ b/mkspecs/features/qt_build_extra.prf @@ -0,0 +1,40 @@ +# +# W A R N I N G +# ------------- +# +# This file is not part of the Qt API. It exists purely as an +# implementation detail. It may change from version to version +# without notice, or even be removed. +# +# We mean it. +# + +equals(TEMPLATE, subdirs): return() + +# It's likely that these extra flags will be wrong for host builds, +# and the bootstrapped tools usually don't need them anyway. +host_build:force_bootstrap: return() + +# The headersclean check needs defines and includes even for +# header-only modules. +DEFINES += $$EXTRA_DEFINES +INCLUDEPATH += $$EXTRA_INCLUDEPATH + +# The other flags are relevant only for actual libraries. +equals(TEMPLATE, aux): return() + +LIBS += $$EXTRA_LIBS + +# Static libs need no rpaths +static: return() + +for (rp, EXTRA_RPATHS) { + absrp = $$absolute_path($$rp, $$[QT_INSTALL_LIBS]) + !isEqual(absrp, $$rp) { + isEmpty(QMAKE_REL_RPATH_BASE)|!contains(INSTALLS, target): \ + rp = $$absrp + else: \ + rp = $$relative_path($$absrp, $$qtRelativeRPathBase()) + } + QMAKE_RPATHDIR += $$rp +} diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf index 38602f642d..e70d3bf172 100644 --- a/mkspecs/features/qt_common.prf +++ b/mkspecs/features/qt_common.prf @@ -69,9 +69,9 @@ warnings_are_errors:warning_clean { QMAKE_CXXFLAGS_WARN_ON += -Werror -ww177,1224,1478,1881 $$WERROR } } else:gcc:!clang:!intel_icc { - # GCC 4.6-4.9, 5.x + # GCC 4.6-4.9, 5.x, ... ver = $${QT_GCC_MAJOR_VERSION}.$${QT_GCC_MINOR_VERSION} - contains(ver, "(4\\.[6789]|5\\..)") { + contains(ver, "(4\\.[6789]|[5-9]\\..)") { QMAKE_CXXFLAGS_WARN_ON += -Werror -Wno-error=cpp -Wno-error=deprecated-declarations $$WERROR # GCC prints this bogus warning, after it has inlined a lot of code diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index b2c2507807..86396958f1 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -32,6 +32,19 @@ defineReplace(qt5LibraryTarget) { return($$LIBRARY_NAME) } +defineReplace(qtRelativeRPathBase) { + darwin { + if(equals(TEMPLATE, app):app_bundle)|\ + if(equals(TEMPLATE, lib):plugin:plugin_bundle) { + ios: return($$target.path/$${TARGET}.app) + return($$target.path/$${TARGET}.app/Contents/MacOS) + } + equals(TEMPLATE, lib):!plugin:lib_bundle: \ + return($$target.path/$${TARGET}.framework/Versions/Current) + } + return($$target.path) +} + defineTest(qtAddLibrary) { warning("qtAddLibrary() is deprecated. Use QT+= instead.") diff --git a/mkspecs/features/qt_helper_lib.prf b/mkspecs/features/qt_helper_lib.prf index 70a17995cf..ebc629f57f 100644 --- a/mkspecs/features/qt_helper_lib.prf +++ b/mkspecs/features/qt_helper_lib.prf @@ -14,6 +14,9 @@ load(qt_build_paths) TEMPLATE = lib CONFIG -= qt +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 diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index bb28af975f..aefd3aee1c 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -116,7 +116,6 @@ lib_bundle { QMAKE_BUNDLE_EXTENSION = .framework QMAKE_INFO_PLIST = $$QMAKESPEC/Info.plist.lib } - CONFIG -= qt_install_headers #no need to install these as well !debug_and_release|!build_all|CONFIG(release, debug|release) { FRAMEWORK_HEADERS.version = Versions FRAMEWORK_HEADERS.files = $$SYNCQT.HEADER_FILES $$SYNCQT.HEADER_CLASSES diff --git a/mkspecs/features/qt_module_headers.prf b/mkspecs/features/qt_module_headers.prf index eb1db08405..094c854ef0 100644 --- a/mkspecs/features/qt_module_headers.prf +++ b/mkspecs/features/qt_module_headers.prf @@ -99,7 +99,8 @@ git_build: \ else: \ INC_PATH = $$MODULE_BASE_INDIR include($$INC_PATH/include/$$MODULE_INCNAME/headers.pri, "", true) -CONFIG += qt_install_headers +!lib_bundle: \ # Headers are embedded into the bundle, so don't install them separately. + CONFIG += qt_install_headers alien_syncqt: return() diff --git a/mkspecs/features/qt_module_pris.prf b/mkspecs/features/qt_module_pris.prf index 8b717c98f4..9c45350543 100644 --- a/mkspecs/features/qt_module_pris.prf +++ b/mkspecs/features/qt_module_pris.prf @@ -42,8 +42,11 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri module_libs = "\$\$QT_MODULE_HOST_LIB_BASE" else: \ module_libs = "\$\$QT_MODULE_LIB_BASE" - !isEmpty(QT_PRIVATE): \ - module_rundep = "QT.$${MODULE_ID}.run_depends = $$replace(QT_PRIVATE, -private$, _private)" + # In addition to the library's private deps, the private module's deps + # are logically runtime deps of the public module. + runtime_deps = $$QT_PRIVATE $$QT_FOR_PRIVATE + !isEmpty(runtime_deps): \ + module_rundep = "QT.$${MODULE_ID}.run_depends = $$replace(runtime_deps, -private$, _private)" else: \ module_rundep = module_build_type = v2 diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf index 5ad372f976..0bf0ed7b94 100644 --- a/mkspecs/features/testcase.prf +++ b/mkspecs/features/testcase.prf @@ -6,13 +6,16 @@ have_target { # qt_build_config tells us to re-enable exceptions here. testcase_exceptions: CONFIG += exceptions -check.files = -check.path = . +benchmark: type = benchmark +else: type = check + +$${type}.files = +$${type}.path = . # Add environment for non-installed builds. Do this first, so the # 'make' variable expansions don't end up in a batch file/script. QT_TOOL_NAME = target -qtAddTargetEnv(check.commands, QT) +qtAddTargetEnv($${type}.commands, QT) # If the test ends up in a different directory, we should cd to that directory. TESTRUN_CWD = $$DESTDIR @@ -27,44 +30,44 @@ debug_and_release:debug_and_release_target { } # Allow for a custom test runner script -check.commands += $(TESTRUNNER) +$${type}.commands += $(TESTRUNNER) unix { isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = . app_bundle: \ - check.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET).app/Contents/MacOS/$(QMAKE_TARGET) + $${type}.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET).app/Contents/MacOS/$(QMAKE_TARGET) else: \ - check.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET) + $${type}.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET) } else { # Windows !isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = $${TEST_TARGET_DIR}$${QMAKE_DIR_SEP} - check.commands += $${TEST_TARGET_DIR}$(TARGET) + $${type}.commands += $${TEST_TARGET_DIR}$(TARGET) } # Allow for custom arguments to tests -check.commands += $(TESTARGS) +$${type}.commands += $(TESTARGS) !isEmpty(TESTRUN_CWD):!contains(TESTRUN_CWD, ^\\./?): \ - check.commands = cd $$shell_path($$TESTRUN_CWD) && $$check.commands + $${type}.commands = cd $$shell_path($$TESTRUN_CWD) && $$eval($${type}.commands) # If the test is marked as insignificant, discard the exit code -insignificant_test:check.commands = -$${check.commands} +insignificant_test: $${type}.commands = -$$eval($${type}.commands) -QMAKE_EXTRA_TARGETS *= check +QMAKE_EXTRA_TARGETS *= $${type} isEmpty(BUILDS)|build_pass { - check.depends = first + $${type}.depends = first } else { # For exclusive builds, only run the test once. - check.CONFIG = recursive - check.target = check_all - check.recurse_target = check - check.commands = - - check_first.depends = $$eval($$first(BUILDS).target)-check - check_first.target = check - QMAKE_EXTRA_TARGETS += check_first + $${type}.CONFIG = recursive + $${type}.target = $${type}_all + $${type}.recurse_target = $${type} + $${type}.commands = + + $${type}_first.depends = $$eval($$first(BUILDS).target)-$${type} + $${type}_first.target = $${type} + QMAKE_EXTRA_TARGETS += $${type}_first } !no_testcase_installs:!contains(INSTALLS, target) { diff --git a/mkspecs/features/testcase_targets.prf b/mkspecs/features/testcase_targets.prf index e9b107735a..16ec6a9f0d 100644 --- a/mkspecs/features/testcase_targets.prf +++ b/mkspecs/features/testcase_targets.prf @@ -7,3 +7,13 @@ check.depends = first # `make check' implies build QMAKE_EXTRA_TARGETS += check } + +# ... and the same for benchmarks, too. +!contains(QMAKE_EXTRA_TARGETS, benchmark) { + contains(TEMPLATE, subdirs): \ + prepareRecursiveTarget(benchmark) + else: \ + benchmark.depends = first # `make benchmark' implies build + QMAKE_EXTRA_TARGETS += benchmark +} + diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf index 61963c7b0d..f6828f68ea 100644 --- a/mkspecs/win32-g++/qmake.conf +++ b/mkspecs/win32-g++/qmake.conf @@ -31,6 +31,7 @@ QMAKE_CFLAGS_DEPS = -M QMAKE_CFLAGS_WARN_ON = -Wall -Wextra QMAKE_CFLAGS_WARN_OFF = -w QMAKE_CFLAGS_RELEASE = -O2 +QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -O2 -g QMAKE_CFLAGS_DEBUG = -g QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses QMAKE_CFLAGS_SPLIT_SECTIONS = -ffunction-sections @@ -104,7 +105,7 @@ QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2 QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain QMAKE_IDL = midl -QMAKE_LIB = $${CROSS_COMPILE}ar -ru +QMAKE_LIB = $${CROSS_COMPILE}ar -rc QMAKE_RC = $${CROSS_COMPILE}windres QMAKE_STRIP = $${CROSS_COMPILE}strip diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index ef9aa9a2e6..cf0c4a81a3 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -103,19 +103,6 @@ struct ProjectBuilderSubDirs { bool ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) { - if(project->isActiveConfig("generate_pbxbuild_makefile")) { - QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"), - FileFixifyToIndir); - QFile mkwrapf(mkwrap); - if(mkwrapf.open(QIODevice::WriteOnly | QIODevice::Text)) { - debug_msg(1, "pbuilder: Creating file: %s", mkwrap.toLatin1().constData()); - QTextStream mkwrapt(&mkwrapf); - writingUnixMakefileGenerator = true; - UnixMakefileGenerator::writeSubDirs(mkwrapt); - writingUnixMakefileGenerator = false; - } - } - //HEADER const int pbVersion = pbuilderVersion(); t << "// !$*UTF8*$!\n" @@ -1494,21 +1481,21 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if (plist_in_file.open(QIODevice::ReadOnly)) { QTextStream plist_in(&plist_in_file); QString plist_in_text = plist_in.readAll(); - plist_in_text.replace("@ICON@", + plist_in_text.replace(QLatin1String("@ICON@"), (project->isEmpty("ICON") ? QString("") : project->first("ICON").toQString().section(Option::dir_sep, -1))); if (project->first("TEMPLATE") == "app") { - plist_in_text.replace("@EXECUTABLE@", project->first("QMAKE_ORIG_TARGET").toQString()); + plist_in_text.replace(QLatin1String("@EXECUTABLE@"), project->first("QMAKE_ORIG_TARGET").toQString()); } else { - plist_in_text.replace("@LIBRARY@", project->first("QMAKE_ORIG_TARGET").toQString()); + plist_in_text.replace(QLatin1String("@LIBRARY@"), project->first("QMAKE_ORIG_TARGET").toQString()); } QString bundlePrefix = project->first("QMAKE_TARGET_BUNDLE_PREFIX").toQString(); if (bundlePrefix.isEmpty()) bundlePrefix = "com.yourcompany"; - plist_in_text.replace("@BUNDLEIDENTIFIER@", bundlePrefix + '.' + QLatin1String("${PRODUCT_NAME:rfc1034identifier}")); + plist_in_text.replace(QLatin1String("@BUNDLEIDENTIFIER@"), bundlePrefix + '.' + QLatin1String("${PRODUCT_NAME:rfc1034identifier}")); if (!project->values("VERSION").isEmpty()) { - plist_in_text.replace("@SHORT_VERSION@", project->first("VER_MAJ") + "." + project->first("VER_MIN")); + plist_in_text.replace(QLatin1String("@SHORT_VERSION@"), project->first("VER_MAJ") + "." + project->first("VER_MIN")); } - plist_in_text.replace("@TYPEINFO@", + plist_in_text.replace(QLatin1String("@TYPEINFO@"), (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ? QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4).toQString())); QFile plist_out_file(Option::output_dir + "/Info.plist"); @@ -1666,32 +1653,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t" << writeSettings("rootObject", keyFor("QMAKE_PBX_ROOT")) << ";\n" << "}\n"; - if(project->isActiveConfig("generate_pbxbuild_makefile")) { - QString mkwrap = Option::output_dir + project->first("/MAKEFILE"); - QFile mkwrapf(mkwrap); - if(mkwrapf.open(QIODevice::WriteOnly | QIODevice::Text)) { - writingUnixMakefileGenerator = true; - debug_msg(1, "pbuilder: Creating file: %s", mkwrap.toLatin1().constData()); - QTextStream mkwrapt(&mkwrapf); - writeHeader(mkwrapt); - const char cleans[] = "preprocess_clean "; - const QString cmd = escapeFilePath(project->first("QMAKE_ORIG_TARGET") + projectSuffix() + "/") + " && " + pbxbuild(); - mkwrapt << "#This is a makefile wrapper for PROJECT BUILDER\n" - << "all:\n\t" - << "cd " << cmd << "\n" - << "install: all\n\t" - << "cd " << cmd << " install\n" - << "distclean clean: preprocess_clean\n\t" - << "cd " << cmd << " clean\n" - << (!did_preprocess ? cleans : "") << ":\n"; - if(did_preprocess) - mkwrapt << cleans << ":\n\t" - << "make -f " - << pbx_dir << Option::dir_sep << "qt_preprocess.mak $@\n"; - writingUnixMakefileGenerator = false; - } - } - // Scheme { QString xcodeSpecDir = project->first("QMAKE_XCODE_SPECDIR").toQString(); @@ -1711,9 +1672,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QTextStream defaultSchemeStream(&defaultSchemeFile); QString schemeData = defaultSchemeStream.readAll(); - schemeData.replace("@QMAKE_ORIG_TARGET@", target); - schemeData.replace("@TARGET_PBX_KEY@", keyFor(pbx_dir + "QMAKE_PBX_TARGET")); - schemeData.replace("@TEST_BUNDLE_PBX_KEY@", keyFor("QMAKE_TEST_BUNDLE_REFERENCE")); + schemeData.replace(QLatin1String("@QMAKE_ORIG_TARGET@"), target); + schemeData.replace(QLatin1String("@TARGET_PBX_KEY@"), keyFor(pbx_dir + "QMAKE_PBX_TARGET")); + schemeData.replace(QLatin1String("@TEST_BUNDLE_PBX_KEY@"), keyFor("QMAKE_TEST_BUNDLE_REFERENCE")); QTextStream outputSchemeStream(&outputSchemeFile); outputSchemeStream << schemeData; diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 4dfe69fbde..5ec4cfb7ef 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1132,8 +1132,8 @@ MakefileGenerator::writeObj(QTextStream &t, const char *src) ProStringList::ConstIterator oit = objl.begin(); ProStringList::ConstIterator sit = srcl.begin(); - QString stringSrc("$src"); - QString stringObj("$obj"); + QLatin1String stringSrc("$src"); + QLatin1String stringObj("$obj"); for(;sit != srcl.end() && oit != objl.end(); ++oit, ++sit) { if((*sit).isEmpty()) continue; @@ -2282,7 +2282,7 @@ MakefileGenerator::writeHeader(QTextStream &t) t << "# Project: " << fileFixify(project->projectFile()) << endl; t << "# Template: " << var("TEMPLATE") << endl; if(!project->isActiveConfig("build_pass")) - t << "# Command: " << build_args().replace("$(QMAKE)", var("QMAKE_QMAKE")) << endl; + t << "# Command: " << build_args().replace(QLatin1String("$(QMAKE)"), var("QMAKE_QMAKE")) << endl; t << "#############################################################################\n"; t << endl; QString ofile = Option::fixPathToTargetOS(Option::output.fileName()); @@ -3177,7 +3177,7 @@ MakefileGenerator::pkgConfigFixPath(QString path) const { QString prefix = pkgConfigPrefix(); if(path.startsWith(prefix)) - path.replace(prefix, "${prefix}"); + path.replace(prefix, QLatin1String("${prefix}")); return path; } @@ -3329,7 +3329,7 @@ static QString windowsifyPath(const QString &str) { // The paths are escaped in prl files, so every slash needs to turn into two backslashes. // Then each backslash needs to be escaped for sed. And another level for C quoting here. - return QString(str).replace('/', "\\\\\\\\"); + return QString(str).replace('/', QLatin1String("\\\\\\\\")); } QString MakefileGenerator::installMetaFile(const ProKey &replace_rule, const QString &src, const QString &dst) @@ -3358,8 +3358,7 @@ QString MakefileGenerator::installMetaFile(const ProKey &replace_rule, const QSt QString MakefileGenerator::shellQuote(const QString &str) { - return isWindowsShell() ? QMakeInternal::IoUtils::shellQuoteWin(str) - : QMakeInternal::IoUtils::shellQuoteUnix(str); + return isWindowsShell() ? IoUtils::shellQuoteWin(str) : IoUtils::shellQuoteUnix(str); } QT_END_NAMESPACE diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index 12b9f09edd..d2483459d8 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -178,12 +178,12 @@ UnixMakefileGenerator::init() pchBaseName += project->first("QMAKE_ORIG_TARGET").toQString(); // replace place holders - pchFlags.replace("${QMAKE_PCH_INPUT}", + pchFlags.replace(QLatin1String("${QMAKE_PCH_INPUT}"), escapeFilePath(project->first("PRECOMPILED_HEADER").toQString())); - pchFlags.replace("${QMAKE_PCH_OUTPUT_BASE}", escapeFilePath(pchBaseName)); + pchFlags.replace(QLatin1String("${QMAKE_PCH_OUTPUT_BASE}"), escapeFilePath(pchBaseName)); if (project->isActiveConfig("icc_pch_style")) { // icc style - pchFlags.replace("${QMAKE_PCH_OUTPUT}", + pchFlags.replace(QLatin1String("${QMAKE_PCH_OUTPUT}"), escapeFilePath(pchBaseName + project->first("QMAKE_PCH_OUTPUT_EXT"))); } else { // gcc style (including clang_pch_style) @@ -197,7 +197,7 @@ UnixMakefileGenerator::init() ProString language = project->first(ProKey("QMAKE_LANGUAGE_" + compiler)); if (!language.isEmpty()) { - pchFlags.replace("${QMAKE_PCH_OUTPUT}", + pchFlags.replace(QLatin1String("${QMAKE_PCH_OUTPUT}"), escapeFilePath(pchBaseName + language + headerSuffix)); } } @@ -569,7 +569,7 @@ UnixMakefileGenerator::defaultInstall(const QString &t) dst = escapeFilePath(filePrefixRoot(root, targetdir + src.section('/', -1))); if(!ret.isEmpty()) ret += "\n\t"; - ret += "-$(INSTALL_FILE) " + escapeFilePath(src) + ' ' + dst; + ret += "-$(INSTALL_FILE) " + escapeFilePath(Option::fixPathToTargetOS(src, false)) + ' ' + dst; if(!uninst.isEmpty()) uninst.append("\n\t"); uninst.append("-$(DEL_FILE) " + dst); diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 9db64bebee..848e47f696 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -536,7 +536,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << "ld -r -o " << incr_target_dir_f << ' ' << link_deps << endl; //communicated below ProStringList &cmd = project->values("QMAKE_LINK_SHLIB_CMD"); - cmd[0] = cmd.at(0).toQString().replace("$(OBJECTS) ", "$(INCREMENTAL_OBJECTS)"); //ick + cmd[0] = cmd.at(0).toQString().replace(QLatin1String("$(OBJECTS) "), QLatin1String("$(INCREMENTAL_OBJECTS)")); //ick cmd.append(incr_target_dir_f); deps.prepend(incr_target_dir_d + ' '); incr_deps = "$(INCREMENTAL_OBJECTS)"; @@ -704,7 +704,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << destdir_d << "$(TARGET): " << depVar("PRE_TARGETDEPS") << ' ' << depVar("POST_TARGETDEPS") << valList(escapeDependencyPaths(build)) << "\n\t"; ar = project->first("QMAKE_AR_CMD").toQString(); - ar.replace("$(OBJECTS)", escapeFilePaths(build).join(' ')); + ar.replace(QLatin1String("$(OBJECTS)"), escapeFilePaths(build).join(' ')); } else { t << destdir_d << escapeDependencyPath(*libit) << ": " << valList(escapeDependencyPaths(build)) << "\n\t"; @@ -1083,8 +1083,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << "\n\techo \"// Automatically generated, do not modify\" > " << sourceFile_f << "\n\trm -f " << escapeFilePath(pchOutput); - pchFlags.replace("${QMAKE_PCH_TEMP_SOURCE}", sourceFile_f) - .replace("${QMAKE_PCH_TEMP_OBJECT}", escapeFilePath(objectFile)); + pchFlags.replace(QLatin1String("${QMAKE_PCH_TEMP_SOURCE}"), sourceFile_f) + .replace(QLatin1String("${QMAKE_PCH_TEMP_OBJECT}"), escapeFilePath(objectFile)); } else { // gcc style (including clang_pch_style) ProString header_prefix = project->first("QMAKE_PRECOMP_PREFIX"); @@ -1103,9 +1103,9 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << escapeDependencyPaths(findDependencies(pchInput)).join(" \\\n\t\t") << "\n\t" << mkdir_p_asstring(pchOutputDir); } - pchFlags.replace("${QMAKE_PCH_INPUT}", escapeFilePath(pchInput)) - .replace("${QMAKE_PCH_OUTPUT_BASE}", escapeFilePath(pchBaseName.toQString())) - .replace("${QMAKE_PCH_OUTPUT}", escapeFilePath(pchOutput.toQString())); + pchFlags.replace(QLatin1String("${QMAKE_PCH_INPUT}"), escapeFilePath(pchInput)) + .replace(QLatin1String("${QMAKE_PCH_OUTPUT_BASE}"), escapeFilePath(pchBaseName.toQString())) + .replace(QLatin1String("${QMAKE_PCH_OUTPUT}"), escapeFilePath(pchOutput.toQString())); QString compilerExecutable; if (compiler == "C" || compiler == "OBJC") @@ -1151,7 +1151,7 @@ void UnixMakefileGenerator::init2() ProStringList &ar_cmd = project->values("QMAKE_AR_CMD"); if (!ar_cmd.isEmpty()) - ar_cmd[0] = ar_cmd.at(0).toQString().replace("(TARGET)","(TARGETA)"); + ar_cmd[0] = ar_cmd.at(0).toQString().replace(QLatin1String("(TARGET)"), QLatin1String("(TARGETA)")); else ar_cmd.append("$(AR) $(TARGETA) $(OBJECTS)"); if (!project->isEmpty("QMAKE_BUNDLE")) { diff --git a/qmake/generators/win32/cesdkhandler.cpp b/qmake/generators/win32/cesdkhandler.cpp index 4550cc8aed..8934bbd95f 100644 --- a/qmake/generators/win32/cesdkhandler.cpp +++ b/qmake/generators/win32/cesdkhandler.cpp @@ -147,7 +147,7 @@ bool CeSdkHandler::parseMsBuildFile(QFile *file, CeSdkInfo *info) QSettings sdkRootPathRegistry(regString, QSettings::NativeFormat); const QString erg = sdkRootPathRegistry.value(QStringLiteral(".")).toString(); const QString fullSdkRootPath = erg + sdkRootPath.mid(endIndex + 1); - const QString rootString = QStringLiteral("$(SdkRootPath)"); + const QLatin1String rootString("$(SdkRootPath)"); includePath = includePath.replace(rootString, fullSdkRootPath); libraryPath = libraryPath.replace(rootString, fullSdkRootPath); diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index 1837c6c0cf..8c315e0696 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -51,7 +51,7 @@ QString MingwMakefileGenerator::escapeDependencyPath(const QString &path) const { QString ret = path; ret.replace('\\', "/"); // ### this shouldn't be here - ret.replace(' ', "\\ "); + ret.replace(' ', QLatin1String("\\ ")); return ret; } diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index bcfab80ccf..9dbb33ba14 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -328,7 +328,7 @@ static QString vcxCommandSeparator() static QString unquote(const QString &value) { QString result = value; - result.replace(QStringLiteral("\\\""), QStringLiteral("\"")); + result.replace(QLatin1String("\\\""), QLatin1String("\"")); return result; } diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 27427db68b..f7a5019f8b 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -53,7 +53,7 @@ static QString nmakePathList(const QStringList &list) pathList.append(QDir::cleanPath(path)); return QDir::toNativeSeparators(pathList.join(QLatin1Char(';'))) - .replace('#', QStringLiteral("^#")).replace('$', QStringLiteral("$$")); + .replace('#', QLatin1String("^#")).replace('$', QLatin1String("$$")); } NmakeMakefileGenerator::NmakeMakefileGenerator() : Win32MakefileGenerator(), usePCH(false) @@ -261,12 +261,9 @@ void NmakeMakefileGenerator::writeSubMakeCall(QTextStream &t, const QString &cal QString NmakeMakefileGenerator::defaultInstall(const QString &t) { - if((t != "target" && t != "dlltarget") || - (t == "dlltarget" && (project->first("TEMPLATE") != "lib" || !project->isActiveConfig("shared"))) || - project->first("TEMPLATE") == "subdirs") - return QString(); - QString ret = Win32MakefileGenerator::defaultInstall(t); + if (ret.isEmpty()) + return ret; const QString root = installRoot(); ProStringList &uninst = project->values(ProKey(t + ".uninstall")); @@ -330,7 +327,7 @@ QString NmakeMakefileGenerator::var(const ProKey &value) const QString precompRule = QString("-c -FI%1 -Yu%2 -Fp%3") .arg(precompH_f, precompH_f, escapeFilePath(precompPch)); QString p = MakefileGenerator::var(value); - p.replace("-c", precompRule); + p.replace(QLatin1String("-c"), precompRule); // Cannot use -Gm with -FI & -Yu, as this gives an // internal compiler error, on the newer compilers // ### work-around for a VS 2003 bug. Move to some prf file or remove completely. diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index a1a8407a11..52d84e8bce 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -704,12 +704,12 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) } QString slnConf = _slnSolutionConf; if (!project->isEmpty("VCPROJ_ARCH")) { - slnConf.replace(QString("|Win32"), "|" + project->first("VCPROJ_ARCH")); + slnConf.replace(QLatin1String("|Win32"), "|" + project->first("VCPROJ_ARCH")); } else if (!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH")) { QString slnPlatform = QString("|") + project->values("CE_SDK").join(' ') + " (" + project->first("CE_ARCH") + ")"; - slnConf.replace(QString("|Win32"), slnPlatform); + slnConf.replace(QLatin1String("|Win32"), slnPlatform); } else if (is64Bit) { - slnConf.replace(QString("|Win32"), "|x64"); + slnConf.replace(QLatin1String("|Win32"), QLatin1String("|x64")); } t << slnConf; @@ -1706,12 +1706,12 @@ QString VcprojGenerator::replaceExtraCompilerVariables( if(defines.isEmpty()) defines.append(varGlue("PRL_EXPORT_DEFINES"," -D"," -D","") + varGlue("DEFINES"," -D"," -D","")); - ret.replace("$(DEFINES)", defines.first().toQString()); + ret.replace(QLatin1String("$(DEFINES)"), defines.first().toQString()); ProStringList &incpath = project->values("VCPROJ_MAKEFILE_INCPATH"); if(incpath.isEmpty() && !this->var("MSVCPROJ_INCPATH").isEmpty()) incpath.append(this->var("MSVCPROJ_INCPATH")); - ret.replace("$(INCPATH)", incpath.join(' ')); + ret.replace(QLatin1String("$(INCPATH)"), incpath.join(' ')); return ret; } diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index a042cb0d4b..ccf6457048 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -401,7 +401,7 @@ void Win32MakefileGenerator::processRcFileVar() project->values("RC_FILE").first() = fi.absoluteFilePath(); } - resFile.replace(".rc", Option::res_ext); + resFile.replace(QLatin1String(".rc"), Option::res_ext); project->values("RES_FILE").prepend(fileInfo(resFile).fileName()); QString resDestDir; if (project->isActiveConfig("staticlib")) @@ -771,8 +771,8 @@ QString Win32MakefileGenerator::escapeFilePath(const QString &path) const QString Win32MakefileGenerator::cQuoted(const QString &str) { QString ret = str; - ret.replace(QLatin1Char('\\'), QStringLiteral("\\\\")); - ret.replace(QLatin1Char('"'), QStringLiteral("\\\"")); + ret.replace(QLatin1Char('\\'), QLatin1String("\\\\")); + ret.replace(QLatin1Char('"'), QLatin1String("\\\"")); ret.prepend(QLatin1Char('"')); ret.append(QLatin1Char('"')); return ret; diff --git a/qmake/generators/xmloutput.cpp b/qmake/generators/xmloutput.cpp index 4f2e7fee69..479a7e426d 100644 --- a/qmake/generators/xmloutput.cpp +++ b/qmake/generators/xmloutput.cpp @@ -140,11 +140,11 @@ QString XmlOutput::doConversion(const QString &text) } if (conversion == XMLConversion) { - output.replace('\"', """); - output.replace('\'', "'"); + output.replace('\"', QLatin1String(""")); + output.replace('\'', QLatin1String("'")); } else if (conversion == EscapeConversion) { - output.replace('\"', "\\\""); - output.replace('\'', "\\\'"); + output.replace('\"', QLatin1String("\\\"")); + output.replace('\'', QLatin1String("\\\'")); } return output; } diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp index 95a072392e..8170eee76c 100644 --- a/qmake/library/qmakeparser.cpp +++ b/qmake/library/qmakeparser.cpp @@ -280,7 +280,8 @@ void QMakeParser::putHashStr(ushort *&pTokPtr, const ushort *buf, uint len) *tokPtr++ = (ushort)hash; *tokPtr++ = (ushort)(hash >> 16); *tokPtr++ = (ushort)len; - memcpy(tokPtr, buf, len * 2); + if (len) // buf may be nullptr; don't pass that to memcpy (-> undefined behavior) + memcpy(tokPtr, buf, len * 2); pTokPtr = tokPtr + len; } diff --git a/qmake/main.cpp b/qmake/main.cpp index 5f848d4820..96cb758e26 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -130,7 +130,7 @@ static int doSed(int argc, char **argv) SedSubst subst; subst.from = QRegExp(phases.at(0), matchcase); subst.to = phases.at(1); - subst.to.replace("\\\\", "\\"); // QString::replace(rx, sub) groks \1, but not \\. + subst.to.replace(QLatin1String("\\\\"), QLatin1String("\\")); // QString::replace(rx, sub) groks \1, but not \\. substs << subst; } } else if (argv[i][0] == '-' && argv[i][1] != 0) { diff --git a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro index edfc0e7954..163842e8fc 100644 --- a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro +++ b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro @@ -7,8 +7,12 @@ CONFIG += \ load(qt_helper_lib) +# built-in shapers list configuration: +SHAPERS += opentype # HB's main shaper; enabling it should be enough most of the time +mac: SHAPERS += coretext # native shaper on OSX/iOS; could be used alone to handle both OT and AAT fonts + DEFINES += HAVE_CONFIG_H -DEFINES += HAVE_OT HB_NO_UNICODE_FUNCS HB_DISABLE_DEPRECATED +DEFINES += HB_NO_UNICODE_FUNCS HB_DISABLE_DEPRECATED # platform/compiler specific definitions DEFINES += HAVE_ATEXIT @@ -78,57 +82,59 @@ HEADERS += \ $$PWD/src/hb-unicode.h \ $$PWD/src/hb-version.h -# Open Type -SOURCES += \ - $$PWD/src/hb-ot-font.cc \ - $$PWD/src/hb-ot-layout.cc \ - $$PWD/src/hb-ot-map.cc \ - $$PWD/src/hb-ot-shape.cc \ - $$PWD/src/hb-ot-shape-complex-arabic.cc \ - $$PWD/src/hb-ot-shape-complex-default.cc \ - $$PWD/src/hb-ot-shape-complex-hangul.cc \ - $$PWD/src/hb-ot-shape-complex-hebrew.cc \ - $$PWD/src/hb-ot-shape-complex-indic.cc \ - $$PWD/src/hb-ot-shape-complex-indic-table.cc \ - $$PWD/src/hb-ot-shape-complex-myanmar.cc \ - $$PWD/src/hb-ot-shape-complex-thai.cc \ - $$PWD/src/hb-ot-shape-complex-tibetan.cc \ - $$PWD/src/hb-ot-shape-complex-use.cc \ - $$PWD/src/hb-ot-shape-complex-use-table.cc \ - $$PWD/src/hb-ot-shape-fallback.cc \ - $$PWD/src/hb-ot-shape-normalize.cc +contains(SHAPERS, opentype) { + DEFINES += HAVE_OT -HEADERS += \ - $$PWD/src/hb-ot-layout-common-private.hh \ - $$PWD/src/hb-ot-layout-gdef-table.hh \ - $$PWD/src/hb-ot-layout-gpos-table.hh \ - $$PWD/src/hb-ot-layout-gsubgpos-private.hh \ - $$PWD/src/hb-ot-layout-gsub-table.hh \ - $$PWD/src/hb-ot-layout-jstf-table.hh \ - $$PWD/src/hb-ot-layout-private.hh \ - $$PWD/src/hb-ot-map-private.hh \ - $$PWD/src/hb-ot-shape-complex-arabic-fallback.hh \ - $$PWD/src/hb-ot-shape-complex-arabic-private.hh \ - $$PWD/src/hb-ot-shape-complex-arabic-table.hh \ - $$PWD/src/hb-ot-shape-complex-indic-machine.hh \ - $$PWD/src/hb-ot-shape-complex-indic-private.hh \ - $$PWD/src/hb-ot-shape-complex-myanmar-machine.hh \ - $$PWD/src/hb-ot-shape-complex-private.hh \ - $$PWD/src/hb-ot-shape-complex-use-machine.hh \ - $$PWD/src/hb-ot-shape-complex-use-private.hh \ - $$PWD/src/hb-ot-shape-fallback-private.hh \ - $$PWD/src/hb-ot-shape-normalize-private.hh \ - $$PWD/src/hb-ot-shape-private.hh + SOURCES += \ + $$PWD/src/hb-ot-font.cc \ + $$PWD/src/hb-ot-layout.cc \ + $$PWD/src/hb-ot-map.cc \ + $$PWD/src/hb-ot-shape.cc \ + $$PWD/src/hb-ot-shape-complex-arabic.cc \ + $$PWD/src/hb-ot-shape-complex-default.cc \ + $$PWD/src/hb-ot-shape-complex-hangul.cc \ + $$PWD/src/hb-ot-shape-complex-hebrew.cc \ + $$PWD/src/hb-ot-shape-complex-indic.cc \ + $$PWD/src/hb-ot-shape-complex-indic-table.cc \ + $$PWD/src/hb-ot-shape-complex-myanmar.cc \ + $$PWD/src/hb-ot-shape-complex-thai.cc \ + $$PWD/src/hb-ot-shape-complex-tibetan.cc \ + $$PWD/src/hb-ot-shape-complex-use.cc \ + $$PWD/src/hb-ot-shape-complex-use-table.cc \ + $$PWD/src/hb-ot-shape-fallback.cc \ + $$PWD/src/hb-ot-shape-normalize.cc -HEADERS += \ - $$PWD/src/hb-ot.h \ - $$PWD/src/hb-ot-font.h \ - $$PWD/src/hb-ot-layout.h \ - $$PWD/src/hb-ot-shape.h \ - $$PWD/src/hb-ot-tag.h - -mac { - # Apple Advanced Typography + HEADERS += \ + $$PWD/src/hb-ot-layout-common-private.hh \ + $$PWD/src/hb-ot-layout-gdef-table.hh \ + $$PWD/src/hb-ot-layout-gpos-table.hh \ + $$PWD/src/hb-ot-layout-gsubgpos-private.hh \ + $$PWD/src/hb-ot-layout-gsub-table.hh \ + $$PWD/src/hb-ot-layout-jstf-table.hh \ + $$PWD/src/hb-ot-layout-private.hh \ + $$PWD/src/hb-ot-map-private.hh \ + $$PWD/src/hb-ot-shape-complex-arabic-fallback.hh \ + $$PWD/src/hb-ot-shape-complex-arabic-private.hh \ + $$PWD/src/hb-ot-shape-complex-arabic-table.hh \ + $$PWD/src/hb-ot-shape-complex-indic-machine.hh \ + $$PWD/src/hb-ot-shape-complex-indic-private.hh \ + $$PWD/src/hb-ot-shape-complex-myanmar-machine.hh \ + $$PWD/src/hb-ot-shape-complex-private.hh \ + $$PWD/src/hb-ot-shape-complex-use-machine.hh \ + $$PWD/src/hb-ot-shape-complex-use-private.hh \ + $$PWD/src/hb-ot-shape-fallback-private.hh \ + $$PWD/src/hb-ot-shape-normalize-private.hh \ + $$PWD/src/hb-ot-shape-private.hh + + HEADERS += \ + $$PWD/src/hb-ot.h \ + $$PWD/src/hb-ot-font.h \ + $$PWD/src/hb-ot-layout.h \ + $$PWD/src/hb-ot-shape.h \ + $$PWD/src/hb-ot-tag.h +} + +contains(SHAPERS, coretext) { DEFINES += HAVE_CORETEXT SOURCES += \ diff --git a/src/3rdparty/libpng/ANNOUNCE b/src/3rdparty/libpng/ANNOUNCE index 9f1b665834..4dae783b55 100644 --- a/src/3rdparty/libpng/ANNOUNCE +++ b/src/3rdparty/libpng/ANNOUNCE @@ -1,4 +1,4 @@ -Libpng 1.6.19 - November 12, 2015 +Libpng 1.6.20 - December 3, 2015 This is a public release of libpng, intended for use in production codes. @@ -7,104 +7,41 @@ Files available for download: Source files with LF line endings (for Unix/Linux) and with a "configure" script - libpng-1.6.19.tar.xz (LZMA-compressed, recommended) - libpng-1.6.19.tar.gz + libpng-1.6.20.tar.xz (LZMA-compressed, recommended) + libpng-1.6.20.tar.gz Source files with CRLF line endings (for Windows), without the "configure" script - lpng1619.7z (LZMA-compressed, recommended) - lpng1619.zip + /scratch/glennrp/Libpng16/lpng1620.7z (LZMA-compressed, recommended) + /scratch/glennrp/Libpng16/lpng1620.zip Other information: - libpng-1.6.19-README.txt - libpng-1.6.19-LICENSE.txt - libpng-1.6.19-*.asc (armored detached GPG signatures) - -Changes since the last public release (1.6.18): - - Updated obsolete information about the simplified API macros in the - manual pages (Bug report by Arc Riley). - Avoid potentially dereferencing NULL info_ptr in png_info_init_3(). - Rearranged png.h to put the major sections in the same order as - in libpng17. - Eliminated unused PNG_COST_SHIFT, PNG_WEIGHT_SHIFT, PNG_COST_FACTOR, and - PNG_WEIGHT_FACTOR macros. - Suppressed some warnings from the Borland C++ 5.5.1/5.82 compiler - (Bug report by Viktor Szakats). Several warnings remain and are - unavoidable, where we test for overflow. - Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c - Fixed uninitialized variable in contrib/gregbook/rpng2-x.c - Moved config.h.in~ from the "libpng_autotools_files" list to the - "libpng_autotools_extra" list in autogen.sh because it was causing a - false positive for missing files (bug report by Robert C. Seacord). - Removed unreachable "break" statements in png.c, pngread.c, and pngrtran.c - to suppress clang warnings (Bug report by Viktor Szakats). - Fixed some bad links in the man page. - Changed "n bit" to "n-bit" in comments. - Added signed/unsigned 16-bit safety net. This removes the dubious - 0x8000 flag definitions on 16-bit systems. They aren't supported - yet the defs *probably* work, however it seems much safer to do this - and be advised if anyone, contrary to advice, is building libpng 1.6 - on a 16-bit system. It also adds back various switch default clauses - for GCC; GCC errors out if they are not present (with an appropriately - high level of warnings). - Safely convert num_bytes to a png_byte in png_set_sig_bytes() (Robert - Seacord). - Fixed the recently reported 1's complement security issue by replacing - the value that is illegal in the PNG spec, in both signed and unsigned - values, with 0. Illegal unsigned values (anything greater than or equal - to 0x80000000) can still pass through, but since these are not illegal - in ANSI-C (unlike 0x80000000 in the signed case) the checking that - occurs later can catch them (John Bowler). - Fixed png_save_int_32 when int is not 2's complement (John Bowler). - Updated libpng16 with all the recent test changes from libpng17, - including changes to pngvalid.c to ensure that the original, - distributed, version of contrib/visupng/cexcept.h can be used - (John Bowler). - pngvalid contains the correction to the use of SAVE/STORE_ - UNKNOWN_CHUNKS; a bug revealed by changes in libpng 1.7. More - tests contain the --strict option to detect warnings and the - pngvalid-standard test has been corrected so that it does not - turn on progressive-read. There is a separate test which does - that. (John Bowler) - Also made some signed/unsigned fixes. - Make pngstest error limits version specific. Splitting the machine - generated error structs out to a file allows the values to be updated - without changing pngstest.c itself. Since libpng 1.6 and 1.7 have - slightly different error limits this simplifies maintenance. The - makepngs.sh script has also been updated to more accurately reflect - current problems in libpng 1.7 (John Bowler). - Incorporated new test PNG files into make check. tests/pngstest-* - are changed so that the new test files are divided into 8 groups by - gamma and alpha channel. These tests have considerably better code - and pixel-value coverage than contrib/pngsuite; however,coverage is - still incomplete (John Bowler). - Removed the '--strict' in 1.6 because of the double-gamma-correction - warning, updated pngstest-errors.h for the errors detected with the - new contrib/testspngs PNG test files (John Bowler). - Worked around rgb-to-gray issues in libpng 1.6. The previous - attempts to ignore the errors in the code aren't quite enough to - deal with the 'channel selection' encoding added to libpng 1.7; abort. - Fixed 'pow' macros in pngvalid.c. It is legal for 'pow' to be a - macro, therefore the argument list cannot contain preprocessing - directives. Make sure pow is a function where this happens. This is - a minimal safe fix, the issue only arises in non-performance-critical - code (bug report by Curtis Leach, fix by John Bowler). - Added sPLT support to pngtest.c - Prevent setting or writing over-length PLTE chunk (Cosmin Truta). - Silently truncate over-length PLTE chunk while reading. - Libpng incorrectly calculated the output rowbytes when the application - decreased either the number of channels or the bit depth (or both) in - a user transform. This was safe; libpng overallocated buffer space - (potentially by quite a lot; up to 4 times the amount required) but, - from 1.5.4 on, resulted in a png_error (John Bowler). - Fixed some inconsequential cut-and-paste typos in png_set_cHRM_XYZ_fixed(). - Clarified COPYRIGHT information to state explicitly that versions - are derived from previous versions. - Removed much of the long list of previous versions from png.h and - libpng.3. + libpng-1.6.20-README.txt + libpng-1.6.20-LICENSE.txt + libpng-1.6.20-*.asc (armored detached GPG signatures) + +Changes since the last public release (1.6.19): + Avoid potential pointer overflow/underflow in png_handle_sPLT() and + png_handle_pCAL() (Bug report by John Regehr). + Fixed incorrect implementation of png_set_PLTE() that uses png_ptr + not info_ptr, that left png_set_PLTE() open to the CVE-2015-8126 + vulnerability. + Backported tests from libpng-1.7.0beta69. + Fixed an error in handling of bad zlib CMINFO field in pngfix, found by + American Fuzzy Lop, reported by Brian Carpenter. inflate() doesn't + immediately fault a bad CMINFO field; instead a 'too far back' error + happens later (at least some times). pngfix failed to limit CMINFO to + the allowed values but then assumed that window_bits was in range, + triggering an assert. The bug is mostly harmless; the PNG file cannot + be fixed. + In libpng 1.6 zlib initialization was changed to use the window size + in the zlib stream, not a fixed value. This causes some invalid images, + where CINFO is too large, to display 'correctly' if the rest of the + data is valid. This provides a workaround for zlib versions where the + error arises (ones that support the API change to use the window size + in the stream). Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/src/3rdparty/libpng/CHANGES b/src/3rdparty/libpng/CHANGES index 2e4d2bb292..28094fd26c 100644 --- a/src/3rdparty/libpng/CHANGES +++ b/src/3rdparty/libpng/CHANGES @@ -5409,11 +5409,43 @@ Version 1.6.19rc03 [November 3, 2015] Version 1.6.19rc04 [November 5, 2015] Fixed new bug with CRC error after reading an over-length palette - (bug report by Cosmin Truta). + (bug report by Cosmin Truta) (CVE-2015-8126). Version 1.6.19 [November 12, 2015] Cleaned up coding style in png_handle_PLTE(). +Version 1.6.20beta01 [November 20, 2015] + Avoid potential pointer overflow/underflow in png_handle_sPLT() and + png_handle_pCAL() (Bug report by John Regehr). + +Version 1.6.20beta02 [November 23, 2015] + Fixed incorrect implementation of png_set_PLTE() that uses png_ptr + not info_ptr, that left png_set_PLTE() open to the CVE-2015-8126 + vulnerability. + +Version 1.6.20beta03 [November 24, 2015] + Backported tests from libpng-1.7.0beta69. + +Version 1.6.20rc01 [November 26, 2015] + Fixed an error in handling of bad zlib CMINFO field in pngfix, found by + American Fuzzy Lop, reported by Brian Carpenter. inflate() doesn't + immediately fault a bad CMINFO field; instead a 'too far back' error + happens later (at least some times). pngfix failed to limit CMINFO to + the allowed values but then assumed that window_bits was in range, + triggering an assert. The bug is mostly harmless; the PNG file cannot + be fixed. + +Version 1.6.20rc02 [November 29, 2015] + In libpng 1.6 zlib initialization was changed to use the window size + in the zlib stream, not a fixed value. This causes some invalid images, + where CINFO is too large, to display 'correctly' if the rest of the + data is valid. This provides a workaround for zlib versions where the + error arises (ones that support the API change to use the window size + in the stream). + +Version 1.6.20 [December 3, 2015] + No changes. + Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement diff --git a/src/3rdparty/libpng/LICENSE b/src/3rdparty/libpng/LICENSE index 11f6ffe5db..82dbe117f6 100644 --- a/src/3rdparty/libpng/LICENSE +++ b/src/3rdparty/libpng/LICENSE @@ -10,7 +10,7 @@ this sentence. This code is released under the libpng license. -libpng versions 1.0.7, July 1, 2000, through 1.6.19, November 12, 2015, are +libpng versions 1.0.7, July 1, 2000, through 1.6.20, December 3, 2015, are Copyright (c) 2000-2002, 2004, 2006-2015 Glenn Randers-Pehrson, are derived from libpng-1.0.6, and are distributed according to the same disclaimer and license as libpng-1.0.6 with the following individuals @@ -109,4 +109,4 @@ the additional disclaimers inserted at version 1.0.7. Glenn Randers-Pehrson glennrp at users.sourceforge.net -November 12, 2015 +December 3, 2015 diff --git a/src/3rdparty/libpng/README b/src/3rdparty/libpng/README index 17484e0fd7..59f1f918ae 100644 --- a/src/3rdparty/libpng/README +++ b/src/3rdparty/libpng/README @@ -1,4 +1,4 @@ -README for libpng version 1.6.19 - November 12, 2015 (shared library 16.0) +README for libpng version 1.6.20 - December 3, 2015 (shared library 16.0) See the note about version numbers near the top of png.h See INSTALL for instructions on how to install libpng. diff --git a/src/3rdparty/libpng/libpng-manual.txt b/src/3rdparty/libpng/libpng-manual.txt index bc7a441cf2..87eeb2b583 100644 --- a/src/3rdparty/libpng/libpng-manual.txt +++ b/src/3rdparty/libpng/libpng-manual.txt @@ -1,6 +1,6 @@ libpng-manual.txt - A description on how to use and modify libpng - libpng version 1.6.19 - November 12, 2015 + libpng version 1.6.20 - December 3, 2015 Updated and distributed by Glenn Randers-Pehrson <glennrp at users.sourceforge.net> Copyright (c) 1998-2015 Glenn Randers-Pehrson @@ -11,7 +11,7 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng versions 0.97, January 1998, through 1.6.19 - November 12, 2015 + libpng versions 0.97, January 1998, through 1.6.20 - December 3, 2015 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2015 Glenn Randers-Pehrson @@ -2960,6 +2960,7 @@ width, height, bit_depth, and color_type must be the same in each call. (array of png_color) num_palette - number of entries in the palette + png_set_gAMA(png_ptr, info_ptr, file_gamma); png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma); @@ -4897,7 +4898,7 @@ a set of "safe" limits is applied in pngpriv.h. These can be overridden by application calls to png_set_user_limits(), png_set_user_chunk_cache_max(), and/or png_set_user_malloc_max() that increase or decrease the limits. Also, in libpng-1.5.10 the default width and height limits were increased -from 1,000,000 to 0x7ffffff (i.e., made unlimited). Therefore, the +from 1,000,000 to 0x7fffffff (i.e., made unlimited). Therefore, the limits are now default safe png_user_width_max 0x7fffffff 1,000,000 @@ -5323,7 +5324,7 @@ Since the PNG Development group is an ad-hoc body, we can't make an official declaration. This is your unofficial assurance that libpng from version 0.71 and -upward through 1.6.19 are Y2K compliant. It is my belief that earlier +upward through 1.6.20 are Y2K compliant. It is my belief that earlier versions were also Y2K compliant. Libpng only has two year fields. One is a 2-byte unsigned integer diff --git a/src/3rdparty/libpng/png.c b/src/3rdparty/libpng/png.c index 6fcfad72ec..c183e3f8fa 100644 --- a/src/3rdparty/libpng/png.c +++ b/src/3rdparty/libpng/png.c @@ -14,7 +14,7 @@ #include "pngpriv.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_19 Your_png_h_is_not_version_1_6_19; +typedef png_libpng_version_1_6_20 Your_png_h_is_not_version_1_6_20; /* Tells libpng that we have already handled the first "num_bytes" bytes * of the PNG file signature. If the PNG data is embedded into another @@ -775,13 +775,13 @@ png_get_copyright(png_const_structrp png_ptr) #else # ifdef __STDC__ return PNG_STRING_NEWLINE \ - "libpng version 1.6.19 - November 12, 2015" PNG_STRING_NEWLINE \ + "libpng version 1.6.20 - December 3, 2015" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2015 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ PNG_STRING_NEWLINE; # else - return "libpng version 1.6.19 - November 12, 2015\ + return "libpng version 1.6.20 - December 3, 2015\ Copyright (c) 1998-2015 Glenn Randers-Pehrson\ Copyright (c) 1996-1997 Andreas Dilger\ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; @@ -2343,7 +2343,7 @@ png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr, * Fall through to "no match". */ png_chunk_report(png_ptr, - "Not recognizing known sRGB profile that has been edited", + "Not recognizing known sRGB profile that has been edited", PNG_CHUNK_WARNING); break; # endif diff --git a/src/3rdparty/libpng/png.h b/src/3rdparty/libpng/png.h index c83051b1ca..4d03dfc136 100644 --- a/src/3rdparty/libpng/png.h +++ b/src/3rdparty/libpng/png.h @@ -1,7 +1,7 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.19, November 12, 2015 + * libpng version 1.6.20, December 3, 2015 * * Copyright (c) 1998-2015 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -12,7 +12,8 @@ * Authors and maintainers: * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger - * libpng versions 0.97, January 1998, through 1.6.19, November 12, 2015: Glenn + * libpng versions 0.97, January 1998, through 1.6.20, December 3, 2015: + * Glenn Randers-Pehrson. * See also "Contributing Authors", below. */ @@ -24,7 +25,7 @@ * * This code is released under the libpng license. * - * libpng versions 1.0.7, July 1, 2000, through 1.6.19, November 12, 2015, are + * libpng versions 1.0.7, July 1, 2000, through 1.6.20, December 3, 2015, are * Copyright (c) 2000-2002, 2004, 2006-2015 Glenn Randers-Pehrson, are * derived from libpng-1.0.6, and are distributed according to the same * disclaimer and license as libpng-1.0.6 with the following individuals @@ -185,7 +186,7 @@ * ... * 1.5.23 15 10523 15.so.15.23[.0] * ... - * 1.6.19 16 10619 16.so.16.19[.0] + * 1.6.20 16 10620 16.so.16.20[.0] * * Henceforth the source version will match the shared-library major * and minor numbers; the shared-library major version number will be @@ -213,13 +214,13 @@ * Y2K compliance in libpng: * ========================= * - * November 12, 2015 + * December 3, 2015 * * Since the PNG Development group is an ad-hoc body, we can't make * an official declaration. * * This is your unofficial assurance that libpng from version 0.71 and - * upward through 1.6.19 are Y2K compliant. It is my belief that + * upward through 1.6.20 are Y2K compliant. It is my belief that * earlier versions were also Y2K compliant. * * Libpng only has two year fields. One is a 2-byte unsigned integer @@ -281,9 +282,9 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.19" +#define PNG_LIBPNG_VER_STRING "1.6.20" #define PNG_HEADER_VERSION_STRING \ - " libpng version 1.6.19 - November 12, 2015\n" + " libpng version 1.6.20 - December 3, 2015\n" #define PNG_LIBPNG_VER_SONUM 16 #define PNG_LIBPNG_VER_DLLNUM 16 @@ -291,7 +292,7 @@ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MINOR 6 -#define PNG_LIBPNG_VER_RELEASE 19 +#define PNG_LIBPNG_VER_RELEASE 20 /* This should match the numeric part of the final component of * PNG_LIBPNG_VER_STRING, omitting any leading zero: @@ -322,7 +323,7 @@ * version 1.0.0 was mis-numbered 100 instead of 10000). From * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release */ -#define PNG_LIBPNG_VER 10619 /* 1.6.19 */ +#define PNG_LIBPNG_VER 10620 /* 1.6.20 */ /* Library configuration: these options cannot be changed after * the library has been built. @@ -432,7 +433,7 @@ extern "C" { /* This triggers a compiler error in png.c, if png.c and png.h * do not agree upon the version number. */ -typedef char* png_libpng_version_1_6_19; +typedef char* png_libpng_version_1_6_20; /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. * diff --git a/src/3rdparty/libpng/pngconf.h b/src/3rdparty/libpng/pngconf.h index f1b795b478..92f250000c 100644 --- a/src/3rdparty/libpng/pngconf.h +++ b/src/3rdparty/libpng/pngconf.h @@ -1,7 +1,7 @@ /* pngconf.h - machine configurable file for libpng * - * libpng version 1.6.19, July 23, 2015 + * libpng version 1.6.20, December 3, 2015 * * Copyright (c) 1998-2015 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) diff --git a/src/3rdparty/libpng/pngerror.c b/src/3rdparty/libpng/pngerror.c index 0781866a89..bdb959ee51 100644 --- a/src/3rdparty/libpng/pngerror.c +++ b/src/3rdparty/libpng/pngerror.c @@ -768,7 +768,7 @@ png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN) /* If control reaches this point, png_longjmp() must not return. The only * choice is to terminate the whole process (or maybe the thread); to do - * this the ANSI-C abort() function is used unless a different method is + * this the ANSI-C abort() function is used unless a different method is * implemented by overriding the default configuration setting for * PNG_ABORT(). */ diff --git a/src/3rdparty/libpng/pnginfo.h b/src/3rdparty/libpng/pnginfo.h index c8c874dd1e..4bd264b869 100644 --- a/src/3rdparty/libpng/pnginfo.h +++ b/src/3rdparty/libpng/pnginfo.h @@ -223,7 +223,7 @@ defined(PNG_READ_BACKGROUND_SUPPORTED) /* Storage for unknown chunks that the library doesn't recognize. */ png_unknown_chunkp unknown_chunks; - /* The type of this field is limited by the type of + /* The type of this field is limited by the type of * png_struct::user_chunk_cache_max, else overflow can occur. */ int unknown_chunks_num; diff --git a/src/3rdparty/libpng/pnglibconf.h b/src/3rdparty/libpng/pnglibconf.h index 8b6da9eb2c..0dba5055f7 100644 --- a/src/3rdparty/libpng/pnglibconf.h +++ b/src/3rdparty/libpng/pnglibconf.h @@ -1,6 +1,6 @@ /* pnglibconf.h - library build configuration */ -/* libpng version 1.6.19, July 23, 2015 */ +/* libpng version 1.6.20 - December 3, 2015 */ /* Copyright (c) 1998-2014 Glenn Randers-Pehrson */ diff --git a/src/3rdparty/libpng/pngpread.c b/src/3rdparty/libpng/pngpread.c index 9f68f99023..89ffc4018f 100644 --- a/src/3rdparty/libpng/pngpread.c +++ b/src/3rdparty/libpng/pngpread.c @@ -133,7 +133,7 @@ png_process_some_data(png_structrp png_ptr, png_inforp info_ptr) void /* PRIVATE */ png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr) { - png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */ + png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */ num_to_check = 8 - num_checked; if (png_ptr->buffer_size < num_to_check) @@ -662,7 +662,7 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer, * change the current behavior (see comments in inflate.c * for why this doesn't happen at present with zlib 1.2.5). */ - ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH); + ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH); /* Check for any failure before proceeding. */ if (ret != Z_OK && ret != Z_STREAM_END) diff --git a/src/3rdparty/libpng/pngpriv.h b/src/3rdparty/libpng/pngpriv.h index f7a45477a4..c06deee68d 100644 --- a/src/3rdparty/libpng/pngpriv.h +++ b/src/3rdparty/libpng/pngpriv.h @@ -1229,6 +1229,14 @@ PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr), /* Initialize the row buffers, etc. */ PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY); +#if PNG_ZLIB_VERNUM >= 0x1240 +PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush), + PNG_EMPTY); +# define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush) +#else /* Zlib < 1.2.4 */ +# define PNG_INFLATE(pp, flush) inflate(&(pp)->zstream, flush) +#endif /* Zlib < 1.2.4 */ + #ifdef PNG_READ_TRANSFORMS_SUPPORTED /* Optional call to update the users info structure */ PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr, diff --git a/src/3rdparty/libpng/pngread.c b/src/3rdparty/libpng/pngread.c index 48aae84881..9cb4d2e41d 100644 --- a/src/3rdparty/libpng/pngread.c +++ b/src/3rdparty/libpng/pngread.c @@ -2838,7 +2838,6 @@ png_image_read_colormap(png_voidp argument) default: png_error(png_ptr, "invalid PNG color type"); /*NOT REACHED*/ - break; } /* Now deal with the output processing */ diff --git a/src/3rdparty/libpng/pngrutil.c b/src/3rdparty/libpng/pngrutil.c index ee584a8c40..6189251352 100644 --- a/src/3rdparty/libpng/pngrutil.c +++ b/src/3rdparty/libpng/pngrutil.c @@ -1,7 +1,7 @@ /* pngrutil.c - utilities to read a PNG file * - * Last changed in libpng 1.6.19 [November 12, 2015] + * Last changed in libpng 1.6.20 [December 3, 2015] * Copyright (c) 1998-2015 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) @@ -377,10 +377,16 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) == PNG_OPTION_ON) + { window_bits = 15; + png_ptr->zstream_start = 0; /* fixed window size */ + } else + { window_bits = 0; + png_ptr->zstream_start = 1; + } # else # define window_bits 0 # endif @@ -429,6 +435,31 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) #endif } +#if PNG_ZLIB_VERNUM >= 0x1240 +/* Handle the start of the inflate stream if we called inflateInit2(strm,0); + * in this case some zlib versions skip validation of the CINFO field and, in + * certain circumstances, libpng may end up displaying an invalid image, in + * contrast to implementations that call zlib in the normal way (e.g. libpng + * 1.5). + */ +int /* PRIVATE */ +png_zlib_inflate(png_structrp png_ptr, int flush) +{ + if (png_ptr->zstream_start && png_ptr->zstream.avail_in > 0) + { + if ((*png_ptr->zstream.next_in >> 4) > 7) + { + png_ptr->zstream.msg = "invalid window size (libpng)"; + return Z_DATA_ERROR; + } + + png_ptr->zstream_start = 0; + } + + return inflate(&png_ptr->zstream, flush); +} +#endif /* Zlib >= 1.2.4 */ + #ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED /* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to * allow the caller to do multiple calls if required. If the 'finish' flag is @@ -522,7 +553,7 @@ png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish, * the previous chunk of input data. Tell zlib if we have reached the * end of the output buffer. */ - ret = inflate(&png_ptr->zstream, avail_out > 0 ? Z_NO_FLUSH : + ret = PNG_INFLATE(png_ptr, avail_out > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH)); } while (ret == Z_OK); @@ -771,7 +802,7 @@ png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size, * the available output is produced; this allows reading of truncated * streams. */ - ret = inflate(&png_ptr->zstream, + ret = PNG_INFLATE(png_ptr, *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH)); } while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0)); @@ -1670,7 +1701,7 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) ++entry_start; /* A sample depth should follow the separator, and we should be on it */ - if (entry_start > buffer + length - 2) + if (length < 2U || entry_start > buffer + (length - 2U)) { png_warning(png_ptr, "malformed sPLT chunk"); return; @@ -2174,7 +2205,7 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) /* We need to have at least 12 bytes after the purpose string * in order to get the parameter information. */ - if (endptr <= buf + 12) + if (endptr - buf <= 12) { png_chunk_benign_error(png_ptr, "invalid"); return; @@ -4039,7 +4070,7 @@ png_read_IDAT_data(png_structrp png_ptr, png_bytep output, * * TODO: deal more elegantly with truncated IDAT lists. */ - ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); + ret = PNG_INFLATE(png_ptr, Z_NO_FLUSH); /* Take the unconsumed output back. */ if (output != NULL) diff --git a/src/3rdparty/libpng/pngset.c b/src/3rdparty/libpng/pngset.c index 05a2134dbb..8fd7965fca 100644 --- a/src/3rdparty/libpng/pngset.c +++ b/src/3rdparty/libpng/pngset.c @@ -520,8 +520,8 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr, if (png_ptr == NULL || info_ptr == NULL) return; - max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? - (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; + max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? + (1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; if (num_palette < 0 || num_palette > (int) max_palette_length) { @@ -1573,7 +1573,7 @@ png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max, { /* Images with dimensions larger than these limits will be * rejected by png_set_IHDR(). To accept any PNG datastream - * regardless of dimensions, set both limits to 0x7ffffff. + * regardless of dimensions, set both limits to 0x7fffffff. */ if (png_ptr == NULL) return; diff --git a/src/3rdparty/libpng/pngstruct.h b/src/3rdparty/libpng/pngstruct.h index c8c0e46e8b..d0bcc7914a 100644 --- a/src/3rdparty/libpng/pngstruct.h +++ b/src/3rdparty/libpng/pngstruct.h @@ -263,6 +263,9 @@ struct png_struct_def /* pixel depth used for the row buffers */ png_byte transformed_pixel_depth; /* pixel depth after read/write transforms */ +#if PNG_ZLIB_VERNUM >= 0x1240 + png_byte zstream_start; /* at start of an input zlib stream */ +#endif /* Zlib >= 1.2.4 */ #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) png_uint_16 filler; /* filler bytes for pixel expansion */ #endif diff --git a/src/3rdparty/libpng/pngwutil.c b/src/3rdparty/libpng/pngwutil.c index adc4729c24..0ee102b5fb 100644 --- a/src/3rdparty/libpng/pngwutil.c +++ b/src/3rdparty/libpng/pngwutil.c @@ -2563,7 +2563,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) if (filter_to_do == PNG_FILTER_SUB) /* It's the only filter so no testing is needed */ { - (void) png_setup_sub_row(png_ptr, bpp, row_bytes, mins); + (void) png_setup_sub_row(png_ptr, bpp, row_bytes, mins); best_row = png_ptr->try_row; } @@ -2572,7 +2572,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) png_size_t sum; png_size_t lmins = mins; - sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins); + sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins); if (sum < mins) { @@ -2598,7 +2598,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) png_size_t sum; png_size_t lmins = mins; - sum = png_setup_up_row(png_ptr, row_bytes, lmins); + sum = png_setup_up_row(png_ptr, row_bytes, lmins); if (sum < mins) { diff --git a/src/3rdparty/sqlite/0001-Fixing-the-SQLite3-build-for-WEC2013-again.patch b/src/3rdparty/sqlite/0001-Fixing-the-SQLite3-build-for-WEC2013-again.patch new file mode 100644 index 0000000000..2d92cfffa7 --- /dev/null +++ b/src/3rdparty/sqlite/0001-Fixing-the-SQLite3-build-for-WEC2013-again.patch @@ -0,0 +1,33 @@ +From c7bbe85015995c1e0627d88bac6fd5715b1338a0 Mon Sep 17 00:00:00 2001 +From: Bjoern Breitmeyer <bjoern.breitmeyer@kdab.com> +Date: Fri, 3 Jul 2015 14:08:04 +0200 +Subject: [PATCH] Fixing the SQLite3 build for WEC2013 again. + +The new version broke the build again +-> fix it again. + +Change-Id: I75761d134d97a2784f1de5076412aa814fdf9bcd +--- + src/3rdparty/sqlite/sqlite3.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c +index 71f6c10..040a9e1 100644 +--- a/src/3rdparty/sqlite/sqlite3.c ++++ b/src/3rdparty/sqlite/sqlite3.c +@@ -15474,9 +15474,11 @@ static void clearYMD_HMS_TZ(DateTime *p){ + #define HAVE_LOCALTIME_S 1 + #endif + +-#if defined(_WIN32_WCE) ++#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800 + #undef HAVE_LOCALTIME_S + struct tm *__cdecl localtime(const time_t *t); ++#elif defined(_WIN32_WCE) && _WIN32_WCE >= 0x800 ++# define SQLITE_MSVC_LOCALTIME_API 1 + #endif + + #ifndef SQLITE_OMIT_LOCALTIME +-- +1.8.1.msysgit.1 + diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index 06f6d154f1..65379a822d 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -15742,9 +15742,11 @@ static void clearYMD_HMS_TZ(DateTime *p){ #define HAVE_LOCALTIME_S 1 #endif -#if defined(_WIN32_WCE) +#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800 #undef HAVE_LOCALTIME_S struct tm *__cdecl localtime(const time_t *t); +#elif defined(_WIN32_WCE) && _WIN32_WCE >= 0x800 +# define SQLITE_MSVC_LOCALTIME_API 1 #endif #ifndef SQLITE_OMIT_LOCALTIME diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index ac77de0bab..4cce86e8bb 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -92,6 +92,7 @@ public class QtActivityDelegate private Method m_super_onConfigurationChanged = null; private Method m_super_onActivityResult = null; private Method m_super_dispatchGenericMotionEvent = null; + private Method m_super_onWindowFocusChanged = null; private static final String NATIVE_LIBRARIES_KEY = "native.libraries"; private static final String BUNDLED_LIBRARIES_KEY = "bundled.libraries"; @@ -520,6 +521,7 @@ public class QtActivityDelegate m_super_onKeyUp = m_activity.getClass().getMethod("super_onKeyUp", Integer.TYPE, KeyEvent.class); m_super_onConfigurationChanged = m_activity.getClass().getMethod("super_onConfigurationChanged", Configuration.class); m_super_onActivityResult = m_activity.getClass().getMethod("super_onActivityResult", Integer.TYPE, Integer.TYPE, Intent.class); + m_super_onWindowFocusChanged = m_activity.getClass().getMethod("super_onWindowFocusChanged", Boolean.TYPE); if (Build.VERSION.SDK_INT >= 12) { try { m_super_dispatchGenericMotionEvent = m_activity.getClass().getMethod("super_dispatchGenericMotionEvent", MotionEvent.class); @@ -943,6 +945,16 @@ public class QtActivityDelegate } } + public void onWindowFocusChanged(boolean hasFocus) { + try { + m_super_onWindowFocusChanged.invoke(m_activity, hasFocus); + } catch (Exception e) { + e.printStackTrace(); + } + if (hasFocus) + updateFullScreen(); + } + public void onConfigurationChanged(Configuration configuration) { try { diff --git a/src/concurrent/concurrent.pro b/src/concurrent/concurrent.pro index 2b8fef2d6a..2a519314f3 100644 --- a/src/concurrent/concurrent.pro +++ b/src/concurrent/concurrent.pro @@ -7,8 +7,6 @@ win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x66000000 QMAKE_DOCS = $$PWD/doc/qtconcurrent.qdocconf -load(qt_module) - PRECOMPILED_HEADER = ../corelib/global/qt_pch.h SOURCES += \ @@ -41,3 +39,5 @@ HEADERS += \ contains(QT_CONFIG, clock-gettime) { linux-*|hpux-*|solaris-*: LIBS_PRIVATE *= -lrt } + +load(qt_module) diff --git a/src/corelib/arch/qatomic_cxx11.h b/src/corelib/arch/qatomic_cxx11.h index 4136e09ce2..baa3d65faf 100644 --- a/src/corelib/arch/qatomic_cxx11.h +++ b/src/corelib/arch/qatomic_cxx11.h @@ -144,7 +144,7 @@ template <typename X> struct QAtomicOps static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; } template <typename T> - static bool testAndSetRelaxed(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW + static bool testAndSetRelaxed(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW { bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed); if (currentValue) @@ -153,7 +153,7 @@ template <typename X> struct QAtomicOps } template <typename T> - static bool testAndSetAcquire(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW + static bool testAndSetAcquire(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW { bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire); if (currentValue) @@ -162,7 +162,7 @@ template <typename X> struct QAtomicOps } template <typename T> - static bool testAndSetRelease(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW + static bool testAndSetRelease(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW { bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release); if (currentValue) @@ -171,7 +171,7 @@ template <typename X> struct QAtomicOps } template <typename T> - static bool testAndSetOrdered(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW + static bool testAndSetOrdered(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW { bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel); if (currentValue) diff --git a/src/corelib/codecs/qicucodec.cpp b/src/corelib/codecs/qicucodec.cpp index b375999aeb..4a4cfd45aa 100644 --- a/src/corelib/codecs/qicucodec.cpp +++ b/src/corelib/codecs/qicucodec.cpp @@ -417,6 +417,7 @@ QList<QByteArray> QIcuCodec::availableCodecs() QList<int> QIcuCodec::availableMibs() { QList<int> mibs; + mibs.reserve(mibToNameSize + 1); for (int i = 0; i < mibToNameSize; ++i) mibs += mibToName[i].mib; diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index ab3f29e2c7..37f33253e0 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -7,6 +7,7 @@ MODULE_CONFIG = moc resources !isEmpty(QT_NAMESPACE): MODULE_DEFINES = QT_NAMESPACE=$$QT_NAMESPACE CONFIG += $$MODULE_CONFIG +DEFINES += $$MODULE_DEFINES DEFINES += QT_NO_USING_NAMESPACE win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x67000000 irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused @@ -31,7 +32,6 @@ ANDROID_PERMISSIONS = \ # variable and on FreeBSD, this variable is in the final executable itself freebsd: QMAKE_LFLAGS_NOUNDEF = -load(qt_module) load(qfeatures) include(animation/animation.pri) @@ -60,8 +60,6 @@ mac|darwin { LIBS_PRIVATE += -framework CoreFoundation LIBS_PRIVATE += -framework Foundation } -win32:DEFINES-=QT_NO_CAST_TO_ASCII -DEFINES += $$MODULE_DEFINES QMAKE_LIBS += $$QMAKE_LIBS_CORE @@ -78,6 +76,11 @@ qt_conf.variable = QT_CONFIG QMAKE_PKGCONFIG_VARIABLES += host_bins qt_conf +load(qt_module) + +# Override qt_module, so the symbols are actually included into the library. +win32: DEFINES -= QT_NO_CAST_TO_ASCII + ctest_macros_file.input = $$PWD/Qt5CTestMacros.cmake ctest_macros_file.output = $$DESTDIR/cmake/Qt5Core/Qt5CTestMacros.cmake ctest_macros_file.CONFIG = verbatim diff --git a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc index 6f183d3e71..216bd985db 100644 --- a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc +++ b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc @@ -251,7 +251,8 @@ This example illustrates that objects can work together without needing to know any information about each other. To enable this, the objects only need to be connected together, and this can be achieved with some simple - QObject::connect() function calls, or with \c{uic}'s {automatic connections} feature. + QObject::connect() function calls, or with \c{uic}'s + \l{Automatic Connections}{automatic connections} feature. \section1 A Real Example diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index aa4945f90e..dd846955f6 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -53,7 +53,10 @@ slog2 { journald { CONFIG += link_pkgconfig - PKGCONFIG_PRIVATE += libsystemd-journal + packagesExist(libsystemd): \ + PKGCONFIG_PRIVATE += libsystemd + else: \ + PKGCONFIG_PRIVATE += libsystemd-journal DEFINES += QT_USE_JOURNALD } diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index b0c7c65c1b..8bcacca13f 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -47,7 +47,7 @@ QT_END_NAMESPACE # include "qcoreapplication.h" #endif -#ifdef Q_OS_MAC +#ifdef Q_OS_DARWIN # include "private/qcore_mac_p.h" #endif @@ -165,7 +165,7 @@ QSettings *QLibraryInfoPrivate::findConfiguration() if (QFile::exists(qtconfig)) return new QSettings(qtconfig, QSettings::IniFormat); #else -#ifdef Q_OS_MAC +#ifdef Q_OS_DARWIN CFBundleRef bundleRef = CFBundleGetMainBundle(); if (bundleRef) { QCFType<CFURLRef> urlRef = CFBundleCopyResourceURL(bundleRef, @@ -403,12 +403,11 @@ static const struct { /*! Returns the location specified by \a loc. - */ QString QLibraryInfo::location(LibraryLocation loc) { -#ifdef QT_BUILD_QMAKE +#ifdef QT_BUILD_QMAKE // ends inside rawLocation ! QString ret = rawLocation(loc, FinalPaths); // Automatically prepend the sysroot to target paths @@ -427,7 +426,7 @@ QLibraryInfo::location(LibraryLocation loc) QString QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) { -#endif +#endif // QT_BUILD_QMAKE, started inside location ! QString ret; #ifdef QT_BUILD_QMAKE // Logic for choosing the right data source: if EffectivePaths are requested @@ -543,25 +542,26 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) } else { // we make any other path absolute to the prefix directory baseDir = rawLocation(PrefixPath, group); + } #else if (loc == PrefixPath) { if (QCoreApplication::instance()) { -#ifdef Q_OS_MAC +#ifdef Q_OS_DARWIN CFBundleRef bundleRef = CFBundleGetMainBundle(); if (bundleRef) { QCFType<CFURLRef> urlRef = CFBundleCopyBundleURL(bundleRef); if (urlRef) { QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle); -#ifdef Q_OS_MACX +#ifdef Q_OS_OSX QString bundleContentsDir = QString(path) + QLatin1String("/Contents/"); if (QDir(bundleContentsDir).exists()) return QDir::cleanPath(bundleContentsDir + ret); #else return QDir::cleanPath(QString(path) + QLatin1Char('/') + ret); // iOS -#endif +#endif // Q_OS_OSX } } -#endif +#endif // Q_OS_DARWIN // We make the prefix path absolute to the executable's directory. baseDir = QCoreApplication::applicationDirPath(); } else { @@ -570,8 +570,8 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) } else { // we make any other path absolute to the prefix directory baseDir = location(PrefixPath); -#endif } +#endif // QT_BUILD_QMAKE ret = QDir::cleanPath(baseDir + QLatin1Char('/') + ret); } return ret; diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 20c31f7ef8..ca38d672c3 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -250,10 +250,11 @@ static inline void convert_to_wchar_t_elided(wchar_t *d, size_t space, const cha if (len + 1 > space) { const size_t skip = len - space + 4; // 4 for "..." + '\0' s += skip; + len -= skip; for (int i = 0; i < 3; ++i) *d++ = L'.'; } - while (*s) + while (len--) *d++ = *s++; *d++ = 0; } @@ -1188,7 +1189,7 @@ static void slog2_default_handler(QtMsgType msgType, const char *message) buffer_config.buffer_set_name = __progname; buffer_config.num_buffers = 1; - buffer_config.verbosity_level = SLOG2_INFO; + buffer_config.verbosity_level = SLOG2_DEBUG1; buffer_config.buffer_config[0].buffer_name = "default"; buffer_config.buffer_config[0].num_pages = 8; diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index c4f5415a01..4d0bd6903d 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1626,7 +1626,8 @@ public: }; enum ScrollPhase { - ScrollBegin = 1, + NoScrollPhase = 0, // Make public in 5.7 or asap + ScrollBegin, ScrollUpdate, ScrollEnd }; diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 7c5263ddbd..527bded3c2 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -3070,6 +3070,8 @@ This enum describes the phase of scrolling. + \omitvalue NoScrollPhase The input device doesn't support scroll phase. + \value ScrollBegin Scrolling is about to begin, but the scrolling distance did not yet change. diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h index 751c6a9a0e..f1abc88b99 100644 --- a/src/corelib/global/qsystemdetection.h +++ b/src/corelib/global/qsystemdetection.h @@ -106,6 +106,9 @@ # if defined(WINCE) || defined(_WIN32_WCE) # define Q_OS_WINCE # elif defined(WINAPI_FAMILY) +# ifndef WINAPI_FAMILY_PC_APP +# define WINAPI_FAMILY_PC_APP WINAPI_FAMILY_APP +# endif # if defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP # define Q_OS_WINPHONE # define Q_OS_WINRT diff --git a/src/corelib/global/qt_windows.h b/src/corelib/global/qt_windows.h index 92ed1966d0..fcb8d27cd6 100644 --- a/src/corelib/global/qt_windows.h +++ b/src/corelib/global/qt_windows.h @@ -39,22 +39,14 @@ #pragma qt_sync_stop_processing #endif -#if defined(Q_CC_BOR) -// Borland's windows.h does not set these correctly, resulting in -// unusable WinSDK standard dialogs -#ifndef WINVER -# define WINVER 0x0501 -#endif -#ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0501 -#endif -#endif - #if defined(Q_CC_MINGW) // mingw's windows.h does not set _WIN32_WINNT, resulting breaking compilation -#ifndef WINVER -# define WINVER 0x501 -#endif +# ifndef WINVER +# define WINVER 0x501 +# endif +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0501 +# endif #endif #ifndef NOMINMAX diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index c590d81f7a..9bd31932b3 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -260,17 +260,21 @@ QString QFileSystemEntry::completeSuffix() const bool QFileSystemEntry::isRelative() const { resolveFilePath(); - return (m_filePath.isEmpty() || (!m_filePath.isEmpty() && (m_filePath.at(0).unicode() != '/') - && (!(m_filePath.length() >= 2 && m_filePath.at(1).unicode() == ':')))); + return (m_filePath.isEmpty() + || (m_filePath.at(0).unicode() != '/' + && !(m_filePath.length() >= 2 && m_filePath.at(1).unicode() == ':'))); } bool QFileSystemEntry::isAbsolute() const { resolveFilePath(); - return (!m_filePath.isEmpty() && ((m_filePath.length() >= 3 - && (m_filePath.at(0).isLetter() && m_filePath.at(1).unicode() == ':' && m_filePath.at(2).unicode() == '/')) - || (m_filePath.length() >= 2 && (m_filePath.at(0) == QLatin1Char('/') && m_filePath.at(1) == QLatin1Char('/'))) - )); + return ((m_filePath.length() >= 3 + && m_filePath.at(0).isLetter() + && m_filePath.at(1).unicode() == ':' + && m_filePath.at(2).unicode() == '/') + || (m_filePath.length() >= 2 + && m_filePath.at(0) == QLatin1Char('/') + && m_filePath.at(1) == QLatin1Char('/'))); } #else bool QFileSystemEntry::isRelative() const diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index d7fed87222..b00a56785e 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -31,13 +31,6 @@ ** ****************************************************************************/ -#if !defined(WINAPI_FAMILY) -# if _WIN32_WINNT < 0x0500 -# undef _WIN32_WINNT -# define _WIN32_WINNT 0x0500 -# endif // _WIN32_WINNT < 0x500 -#endif // !WINAPI_FAMILY - #include "qfilesystemiterator_p.h" #include "qfilesystemengine_p.h" #include "qplatformdefs.h" diff --git a/src/corelib/io/qfilesystemwatcher_win.cpp b/src/corelib/io/qfilesystemwatcher_win.cpp index 410753868e..582aa3bbe9 100644 --- a/src/corelib/io/qfilesystemwatcher_win.cpp +++ b/src/corelib/io/qfilesystemwatcher_win.cpp @@ -165,7 +165,7 @@ QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths, // now look for a thread to insert bool found = false; foreach(QWindowsFileSystemWatcherEngineThread *thread, threads) { - QMutexLocker(&(thread->mutex)); + QMutexLocker locker(&(thread->mutex)); if (thread->handles.count() < MAXIMUM_WAIT_OBJECTS) { DEBUG() << "Added handle" << handle.handle << "for" << absolutePath << "to watch" << fileInfo.absoluteFilePath() << "to existing thread " << thread; diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h index f95358250e..60c513d12e 100644 --- a/src/corelib/io/qprocess.h +++ b/src/corelib/io/qprocess.h @@ -243,7 +243,7 @@ Q_SIGNALS: void finished(int exitCode); // ### Qt 6: merge the two signals with a default value void finished(int exitCode, QProcess::ExitStatus exitStatus); #if QT_DEPRECATED_SINCE(5,6) - QT_MOC_COMPAT void error(QProcess::ProcessError error); + void error(QProcess::ProcessError error); #endif void errorOccurred(QProcess::ProcessError error); void stateChanged(QProcess::ProcessState state, QPrivateSignal); diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 80e6d5bb61..98ada82446 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -647,7 +647,8 @@ bool QProcessPrivate::waitForReadyRead(int msecs) return false; if (WaitForSingleObjectEx(pid->hProcess, 0, false) == WAIT_OBJECT_0) { bool readyReadEmitted = drainOutputPipes(); - _q_processDied(); + if (pid) + _q_processDied(); return readyReadEmitted; } @@ -752,7 +753,8 @@ bool QProcessPrivate::waitForFinished(int msecs) if (WaitForSingleObject(pid->hProcess, timer.nextSleepTime()) == WAIT_OBJECT_0) { drainOutputPipes(); - _q_processDied(); + if (pid) + _q_processDied(); return true; } diff --git a/src/corelib/io/qsettings_win.cpp b/src/corelib/io/qsettings_win.cpp index 1546219c3b..da0c4c3c14 100644 --- a/src/corelib/io/qsettings_win.cpp +++ b/src/corelib/io/qsettings_win.cpp @@ -484,6 +484,12 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa return false; } + // workaround for rare cases where trailing '\0' are missing in registry + if (dataType == REG_SZ || dataType == REG_EXPAND_SZ) + dataSize += 2; + else if (dataType == REG_MULTI_SZ) + dataSize += 4; + // get the value QByteArray data(dataSize, 0); res = RegQueryValueEx(handle, reinterpret_cast<const wchar_t *>(rSubkeyName.utf16()), 0, 0, diff --git a/src/corelib/io/qstandardpaths_mac.mm b/src/corelib/io/qstandardpaths_mac.mm index 7b97a03db2..f65ca2048a 100644 --- a/src/corelib/io/qstandardpaths_mac.mm +++ b/src/corelib/io/qstandardpaths_mac.mm @@ -229,6 +229,14 @@ QString QStandardPaths::displayName(StandardLocation type) if (QStandardPaths::HomeLocation == type) return QCoreApplication::translate("QStandardPaths", "Home"); + if (QStandardPaths::DownloadLocation == type) { + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSURL *url = [fileManager URLForDirectory:NSDownloadsDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil]; + if (!url) + return QString(); + return QString::fromNSString([fileManager displayNameAtPath: [url absoluteString]]); + } + FSRef ref; OSErr err = FSFindFolder(kOnAppropriateDisk, translateLocation(type), false, &ref); if (err) diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp index 73d49cbc25..c1b34d1341 100644 --- a/src/corelib/io/qstandardpaths_win.cpp +++ b/src/corelib/io/qstandardpaths_win.cpp @@ -111,6 +111,7 @@ static inline void appendTestMode(QString &path) // Map QStandardPaths::StandardLocation to CLSID of SHGetSpecialFolderPath() static int writableSpecialFolderClsid(QStandardPaths::StandardLocation type) { +#ifndef Q_OS_WINCE static const int clsids[] = { CSIDL_DESKTOPDIRECTORY, // DesktopLocation CSIDL_PERSONAL, // DocumentsLocation @@ -130,6 +131,27 @@ static int writableSpecialFolderClsid(QStandardPaths::StandardLocation type) CSIDL_APPDATA, // AppDataLocation ("Roaming" path) CSIDL_LOCAL_APPDATA, // AppConfigLocation ("Local" path) }; +#else // !Q_OS_WINCE + static const int clsids[] = { + CSIDL_DESKTOPDIRECTORY, // DesktopLocation + CSIDL_PERSONAL, // DocumentsLocation + CSIDL_FONTS, // FontsLocation + CSIDL_PROGRAMS, // ApplicationsLocation + CSIDL_MYMUSIC, // MusicLocation + CSIDL_MYVIDEO, // MoviesLocation + CSIDL_MYPICTURES, // PicturesLocation + -1, -1, // TempLocation/HomeLocation + CSIDL_APPDATA, // AppLocalDataLocation, AppLocalDataLocation = DataLocation + -1, // CacheLocation + CSIDL_APPDATA, // GenericDataLocation + -1, // RuntimeLocation + CSIDL_APPDATA, // ConfigLocation + -1, -1, // DownloadLocation/GenericCacheLocation + CSIDL_APPDATA, // GenericConfigLocation + CSIDL_APPDATA, // AppDataLocation + CSIDL_APPDATA, // AppConfigLocation + }; +#endif // Q_OS_WINCE Q_STATIC_ASSERT(sizeof(clsids) / sizeof(clsids[0]) == size_t(QStandardPaths::AppConfigLocation + 1)); return size_t(type) < sizeof(clsids) / sizeof(clsids[0]) ? clsids[type] : -1; diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index a8fd2dd7ab..78dcbfe0e7 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -449,6 +449,10 @@ bool QTextStreamPrivate::fillReadBuffer(qint64 maxBytes) bytesRead = device->read(buf, sizeof(buf)); } + // reset the Text flag. + if (textModeEnabled) + device->setTextModeEnabled(true); + if (bytesRead <= 0) return false; @@ -484,10 +488,6 @@ bool QTextStreamPrivate::fillReadBuffer(qint64 maxBytes) readBuffer += QString::fromLatin1(buf, bytesRead); #endif - // reset the Text flag. - if (textModeEnabled) - device->setTextModeEnabled(true); - // remove all '\r\n' in the string. if (readBuffer.size() > oldReadBufferSize && textModeEnabled) { QChar CR = QLatin1Char('\r'); @@ -586,17 +586,18 @@ void QTextStreamPrivate::flushWriteBuffer() qDebug("QTextStreamPrivate::flushWriteBuffer(), device->write(\"%s\") == %d", qt_prettyDebug(data.constData(), qMin(data.size(),32), data.size()).constData(), int(bytesWritten)); #endif - if (bytesWritten <= 0) { - status = QTextStream::WriteFailed; - return; - } #if defined (Q_OS_WIN) - // replace the text flag + // reset the text flag if (textModeEnabled) device->setTextModeEnabled(true); #endif + if (bytesWritten <= 0) { + status = QTextStream::WriteFailed; + return; + } + // flush the file #ifndef QT_NO_QOBJECT QFileDevice *file = qobject_cast<QFileDevice *>(device); diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index fd14523d45..5b11ba6112 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -39,17 +39,10 @@ QT_BEGIN_NAMESPACE QWindowsPipeWriter::QWindowsPipeWriter(HANDLE pipe, QObject * parent) : QThread(parent), - writePipe(INVALID_HANDLE_VALUE), + writePipe(pipe), quitNow(false), hasWritten(false) { -#if !defined(Q_OS_WINCE) || (_WIN32_WCE >= 0x600) - DuplicateHandle(GetCurrentProcess(), pipe, GetCurrentProcess(), - &writePipe, 0, FALSE, DUPLICATE_SAME_ACCESS); -#else - Q_UNUSED(pipe); - writePipe = GetCurrentProcess(); -#endif } QWindowsPipeWriter::~QWindowsPipeWriter() @@ -60,9 +53,6 @@ QWindowsPipeWriter::~QWindowsPipeWriter() lock.unlock(); if (!wait(30000)) terminate(); -#if !defined(Q_OS_WINCE) || (_WIN32_WCE >= 0x600) - CloseHandle(writePipe); -#endif } bool QWindowsPipeWriter::waitForWrite(int msecs) @@ -153,7 +143,6 @@ void QWindowsPipeWriter::run() msleep(100); continue; } -#ifndef Q_OS_WINCE if (writeError != ERROR_IO_PENDING) { qErrnoWarning(writeError, "QWindowsPipeWriter: async WriteFile failed."); return; @@ -162,9 +151,6 @@ void QWindowsPipeWriter::run() qErrnoWarning(GetLastError(), "QWindowsPipeWriter: GetOverlappedResult failed."); return; } -#else - return; -#endif } totalWritten += written; #if defined QPIPEWRITER_DEBUG diff --git a/src/corelib/io/qwinoverlappedionotifier.cpp b/src/corelib/io/qwinoverlappedionotifier.cpp index 0cefa374fa..dee263c664 100644 --- a/src/corelib/io/qwinoverlappedionotifier.cpp +++ b/src/corelib/io/qwinoverlappedionotifier.cpp @@ -75,6 +75,22 @@ QT_BEGIN_NAMESPACE or WriteFile() is ignored and can be used for other purposes. \warning This class is only available on Windows. + + Due to peculiarities of the Windows I/O completion port API, users of + QWinOverlappedIoNotifier must pay attention to the following restrictions: + \list + \li File handles with a QWinOverlappedIoNotifer are assigned to an I/O + completion port until the handle is closed. It is impossible to + disassociate the file handle from the I/O completion port. + \li There can be only one QWinOverlappedIoNotifer per file handle. Creating + another QWinOverlappedIoNotifier for that file, even with a duplicated + handle, will fail. + \li Certain Windows API functions are unavailable for file handles that are + assigned to an I/O completion port. This includes the functions + \c{ReadFileEx} and \c{WriteFileEx}. + \endlist + See also the remarks in the MSDN documentation for the + \c{CreateIoCompletionPort} function. */ struct IOResult diff --git a/src/corelib/itemmodels/qstringlistmodel.cpp b/src/corelib/itemmodels/qstringlistmodel.cpp index dad736b445..b0919c5d78 100644 --- a/src/corelib/itemmodels/qstringlistmodel.cpp +++ b/src/corelib/itemmodels/qstringlistmodel.cpp @@ -276,7 +276,9 @@ void QStringListModel::sort(int, Qt::SortOrder order) QModelIndexList oldList = persistentIndexList(); QModelIndexList newList; - for (int i = 0; i < oldList.count(); ++i) + const int numOldIndexes = oldList.count(); + newList.reserve(numOldIndexes); + for (int i = 0; i < numOldIndexes; ++i) newList.append(index(forwarding.at(oldList.at(i).row()), 0)); changePersistentIndexList(oldList, newList); diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h index 7f5a2d88a1..59d0c91785 100644 --- a/src/corelib/json/qjson_p.h +++ b/src/corelib/json/qjson_p.h @@ -144,6 +144,13 @@ public: return *this; } }; +} // namespace QJsonPrivate + +template <typename T> +class QTypeInfo<QJsonPrivate::q_littleendian<T> > + : public QTypeInfoMerger<QJsonPrivate::q_littleendian<T>, T> {}; + +namespace QJsonPrivate { typedef q_littleendian<short> qle_short; typedef q_littleendian<unsigned short> qle_ushort; @@ -395,7 +402,7 @@ public: // pack with itself, we'll discard the high part anyway chunk = _mm_packus_epi16(chunk, chunk); // unaligned 64-bit store - *(quint64*)&l[i] = _mm_cvtsi128_si64(chunk); + qUnalignedStore(l + i, _mm_cvtsi128_si64(chunk)); i += 8; } # endif @@ -788,7 +795,11 @@ public: if (reserve) { if (reserve < 128) reserve = 128; - size = qMax(size + reserve, size *2); + size = qMax(size + reserve, qMin(size *2, (int)Value::MaxSize)); + if (size > Value::MaxSize) { + qWarning("QJson: Document too large to store in data structure"); + return 0; + } } char *raw = (char *)malloc(size); Q_CHECK_PTR(raw); diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp index bb33dbde74..dc8851e8e7 100644 --- a/src/corelib/json/qjsonarray.cpp +++ b/src/corelib/json/qjsonarray.cpp @@ -256,8 +256,45 @@ QJsonArray QJsonArray::fromStringList(const QStringList &list) QJsonArray QJsonArray::fromVariantList(const QVariantList &list) { QJsonArray array; - for (QVariantList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it) - array.append(QJsonValue::fromVariant(*it)); + if (list.isEmpty()) + return array; + + array.detach2(1024); + + QVector<QJsonPrivate::Value> values; + values.resize(list.size()); + QJsonPrivate::Value *valueData = values.data(); + uint currentOffset = sizeof(QJsonPrivate::Base); + + for (int i = 0; i < list.size(); ++i) { + QJsonValue val = QJsonValue::fromVariant(list.at(i)); + + bool latinOrIntValue; + int valueSize = QJsonPrivate::Value::requiredStorage(val, &latinOrIntValue); + + if (!array.detach2(valueSize)) + return QJsonArray(); + + QJsonPrivate::Value *v = valueData + i; + v->type = (val.t == QJsonValue::Undefined ? QJsonValue::Null : val.t); + v->latinOrIntValue = latinOrIntValue; + v->latinKey = false; + v->value = QJsonPrivate::Value::valueToStore(val, currentOffset); + if (valueSize) + QJsonPrivate::Value::copyData(val, (char *)array.a + currentOffset, latinOrIntValue); + + currentOffset += valueSize; + array.a->size = currentOffset; + } + + // write table + array.a->tableOffset = currentOffset; + if (!array.detach2(sizeof(QJsonPrivate::offset)*values.size())) + return QJsonArray(); + memcpy(array.a->table(), values.constData(), values.size()*sizeof(uint)); + array.a->length = values.size(); + array.a->size = currentOffset + sizeof(QJsonPrivate::offset)*values.size(); + return array; } @@ -382,7 +419,7 @@ void QJsonArray::removeAt(int i) if (!a || i < 0 || i >= (int)a->length) return; - detach(); + detach2(); a->removeItems(i, 1); ++d->compactionCounter; if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(a->length) / 2u) @@ -442,7 +479,8 @@ void QJsonArray::insert(int i, const QJsonValue &value) bool compressed; int valueSize = QJsonPrivate::Value::requiredStorage(val, &compressed); - detach(valueSize + sizeof(QJsonPrivate::Value)); + if (!detach2(valueSize + sizeof(QJsonPrivate::Value))) + return; if (!a->length) a->tableOffset = sizeof(QJsonPrivate::Array); @@ -492,7 +530,8 @@ void QJsonArray::replace(int i, const QJsonValue &value) bool compressed; int valueSize = QJsonPrivate::Value::requiredStorage(val, &compressed); - detach(valueSize); + if (!detach2(valueSize)) + return; if (!a->length) a->tableOffset = sizeof(QJsonPrivate::Array); @@ -1123,21 +1162,38 @@ bool QJsonArray::operator!=(const QJsonArray &other) const */ void QJsonArray::detach(uint reserve) { + Q_UNUSED(reserve) + Q_ASSERT(!reserve); + detach2(0); +} + +/*! + \internal + */ +bool QJsonArray::detach2(uint reserve) +{ if (!d) { + if (reserve >= QJsonPrivate::Value::MaxSize) { + qWarning("QJson: Document too large to store in data structure"); + return false; + } d = new QJsonPrivate::Data(reserve, QJsonValue::Array); a = static_cast<QJsonPrivate::Array *>(d->header->root()); d->ref.ref(); - return; + return true; } if (reserve == 0 && d->ref.load() == 1) - return; + return true; QJsonPrivate::Data *x = d->clone(a, reserve); + if (!x) + return false; x->ref.ref(); if (!d->ref.deref()) delete d; d = x; a = static_cast<QJsonPrivate::Array *>(d->header->root()); + return true; } /*! @@ -1148,7 +1204,7 @@ void QJsonArray::compact() if (!d || !d->compactionCounter) return; - detach(); + detach2(); d->compact(); a = static_cast<QJsonPrivate::Array *>(d->header->root()); } diff --git a/src/corelib/json/qjsonarray.h b/src/corelib/json/qjsonarray.h index 611e1f4193..0f86cfc988 100644 --- a/src/corelib/json/qjsonarray.h +++ b/src/corelib/json/qjsonarray.h @@ -185,10 +185,10 @@ public: friend class const_iterator; // stl style - inline iterator begin() { detach(); return iterator(this, 0); } + inline iterator begin() { detach2(); return iterator(this, 0); } inline const_iterator begin() const { return const_iterator(this, 0); } inline const_iterator constBegin() const { return const_iterator(this, 0); } - inline iterator end() { detach(); return iterator(this, size()); } + inline iterator end() { detach2(); return iterator(this, size()); } inline const_iterator end() const { return const_iterator(this, size()); } inline const_iterator constEnd() const { return const_iterator(this, size()); } iterator insert(iterator before, const QJsonValue &value) { insert(before.i, value); return before; } @@ -229,7 +229,9 @@ private: QJsonArray(QJsonPrivate::Data *data, QJsonPrivate::Array *array); void initialize(); void compact(); + // ### Qt 6: remove me and merge with detach2 void detach(uint reserve = 0); + bool detach2(uint reserve = 0); QJsonPrivate::Data *d; QJsonPrivate::Array *a; diff --git a/src/corelib/json/qjsondocument.cpp b/src/corelib/json/qjsondocument.cpp index 3ef006d82d..5f8f807cf0 100644 --- a/src/corelib/json/qjsondocument.cpp +++ b/src/corelib/json/qjsondocument.cpp @@ -482,7 +482,7 @@ void QJsonDocument::setObject(const QJsonObject &object) if (d->compactionCounter) o.compact(); else - o.detach(); + o.detach2(); d = o.d; d->ref.ref(); return; @@ -509,7 +509,7 @@ void QJsonDocument::setArray(const QJsonArray &array) if (d->compactionCounter) a.compact(); else - a.detach(); + a.detach2(); d = a.d; d->ref.ref(); return; diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp index 27f937e750..b83c8dd19a 100644 --- a/src/corelib/json/qjsonobject.cpp +++ b/src/corelib/json/qjsonobject.cpp @@ -197,11 +197,54 @@ QJsonObject &QJsonObject::operator =(const QJsonObject &other) */ QJsonObject QJsonObject::fromVariantMap(const QVariantMap &map) { - // ### this is implemented the trivial way, not the most efficient way - QJsonObject object; - for (QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it) - object.insert(it.key(), QJsonValue::fromVariant(it.value())); + if (map.isEmpty()) + return object; + + object.detach2(1024); + + QVector<QJsonPrivate::offset> offsets; + QJsonPrivate::offset currentOffset; + currentOffset = sizeof(QJsonPrivate::Base); + + // the map is already sorted, so we can simply append one entry after the other and + // write the offset table at the end + for (QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it) { + QString key = it.key(); + QJsonValue val = QJsonValue::fromVariant(it.value()); + + bool latinOrIntValue; + int valueSize = QJsonPrivate::Value::requiredStorage(val, &latinOrIntValue); + + bool latinKey = QJsonPrivate::useCompressed(key); + int valueOffset = sizeof(QJsonPrivate::Entry) + QJsonPrivate::qStringSize(key, latinKey); + int requiredSize = valueOffset + valueSize; + + if (!object.detach2(requiredSize + sizeof(QJsonPrivate::offset))) // offset for the new index entry + return QJsonObject(); + + QJsonPrivate::Entry *e = reinterpret_cast<QJsonPrivate::Entry *>(reinterpret_cast<char *>(object.o) + currentOffset); + e->value.type = val.t; + e->value.latinKey = latinKey; + e->value.latinOrIntValue = latinOrIntValue; + e->value.value = QJsonPrivate::Value::valueToStore(val, (char *)e - (char *)object.o + valueOffset); + QJsonPrivate::copyString((char *)(e + 1), key, latinKey); + if (valueSize) + QJsonPrivate::Value::copyData(val, (char *)e + valueOffset, latinOrIntValue); + + offsets << currentOffset; + currentOffset += requiredSize; + object.o->size = currentOffset; + } + + // write table + object.o->tableOffset = currentOffset; + if (!object.detach2(sizeof(QJsonPrivate::offset)*offsets.size())) + return QJsonObject(); + memcpy(object.o->table(), offsets.constData(), offsets.size()*sizeof(uint)); + object.o->length = offsets.size(); + object.o->size = currentOffset + sizeof(QJsonPrivate::offset)*offsets.size(); + return object; } @@ -270,16 +313,14 @@ QVariantHash QJsonObject::toVariantHash() const */ QStringList QJsonObject::keys() const { - if (!d) - return QStringList(); - QStringList keys; - keys.reserve(o->length); - for (uint i = 0; i < o->length; ++i) { - QJsonPrivate::Entry *e = o->entryAt(i); - keys.append(e->key()); + if (o) { + keys.reserve(o->length); + for (uint i = 0; i < o->length; ++i) { + QJsonPrivate::Entry *e = o->entryAt(i); + keys.append(e->key()); + } } - return keys; } @@ -391,7 +432,8 @@ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue & int valueOffset = sizeof(QJsonPrivate::Entry) + QJsonPrivate::qStringSize(key, latinKey); int requiredSize = valueOffset + valueSize; - detach(requiredSize + sizeof(QJsonPrivate::offset)); // offset for the new index entry + if (!detach2(requiredSize + sizeof(QJsonPrivate::offset))) // offset for the new index entry + return iterator(); if (!o->length) o->tableOffset = sizeof(QJsonPrivate::Object); @@ -435,7 +477,7 @@ void QJsonObject::remove(const QString &key) if (!keyExists) return; - detach(); + detach2(); o->removeItems(index, 1); ++d->compactionCounter; if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) @@ -462,7 +504,7 @@ QJsonValue QJsonObject::take(const QString &key) return QJsonValue(QJsonValue::Undefined); QJsonValue v(d, o, o->entryAt(index)->value); - detach(); + detach2(); o->removeItems(index, 1); ++d->compactionCounter; if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) @@ -556,7 +598,7 @@ QJsonObject::iterator QJsonObject::find(const QString &key) int index = o ? o->indexOf(key, &keyExists) : 0; if (!keyExists) return end(); - detach(); + detach2(); return iterator(this, index); } @@ -1063,21 +1105,35 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const */ void QJsonObject::detach(uint reserve) { + Q_UNUSED(reserve) + Q_ASSERT(!reserve); + detach2(reserve); +} + +bool QJsonObject::detach2(uint reserve) +{ if (!d) { + if (reserve >= QJsonPrivate::Value::MaxSize) { + qWarning("QJson: Document too large to store in data structure"); + return false; + } d = new QJsonPrivate::Data(reserve, QJsonValue::Object); o = static_cast<QJsonPrivate::Object *>(d->header->root()); d->ref.ref(); - return; + return true; } if (reserve == 0 && d->ref.load() == 1) - return; + return true; QJsonPrivate::Data *x = d->clone(o, reserve); + if (!x) + return false; x->ref.ref(); if (!d->ref.deref()) delete d; d = x; o = static_cast<QJsonPrivate::Object *>(d->header->root()); + return true; } /*! @@ -1088,7 +1144,7 @@ void QJsonObject::compact() if (!d || !d->compactionCounter) return; - detach(); + detach2(); d->compact(); o = static_cast<QJsonPrivate::Object *>(d->header->root()); } diff --git a/src/corelib/json/qjsonobject.h b/src/corelib/json/qjsonobject.h index 8535da4a6c..6fb82b7165 100644 --- a/src/corelib/json/qjsonobject.h +++ b/src/corelib/json/qjsonobject.h @@ -182,10 +182,10 @@ public: friend class const_iterator; // STL style - inline iterator begin() { detach(); return iterator(this, 0); } + inline iterator begin() { detach2(); return iterator(this, 0); } inline const_iterator begin() const { return const_iterator(this, 0); } inline const_iterator constBegin() const { return const_iterator(this, 0); } - inline iterator end() { detach(); return iterator(this, size()); } + inline iterator end() { detach2(); return iterator(this, size()); } inline const_iterator end() const { return const_iterator(this, size()); } inline const_iterator constEnd() const { return const_iterator(this, size()); } iterator erase(iterator it); @@ -215,7 +215,9 @@ private: QJsonObject(QJsonPrivate::Data *data, QJsonPrivate::Object *object); void initialize(); + // ### Qt 6: remove me and merge with detach2 void detach(uint reserve = 0); + bool detach2(uint reserve = 0); void compact(); QString keyAt(int i) const; diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp index 0d62687388..b8a628fdcc 100644 --- a/src/corelib/json/qjsonparser.cpp +++ b/src/corelib/json/qjsonparser.cpp @@ -732,7 +732,7 @@ bool Parser::parseNumber(QJsonPrivate::Value *val, int baseOffset) } int pos = reserveSpace(sizeof(double)); - *(quint64 *)(data + pos) = qToLittleEndian(ui); + qToLittleEndian(ui, reinterpret_cast<uchar *>(data + pos)); if (current - baseOffset >= Value::MaxSize) { lastError = QJsonParseError::DocumentTooLarge; return false; diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 798307f8ab..1a2b047041 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -107,6 +107,7 @@ QAppleOperatingSystemVersion qt_apple_os_version() // Use temporary variables so we can return 0.0.0 (unknown version) // in case of an error partway through determining the OS version qint32 major = 0, minor = 0, patch = 0; +#if QT_MAC_DEPLOYMENT_TARGET_BELOW(__MAC_10_10, __IPHONE_8_0) #if defined(Q_OS_IOS) @autoreleasepool { NSArray *parts = [UIDevice.currentDevice.systemVersion componentsSeparatedByString:@"."]; @@ -130,6 +131,7 @@ QAppleOperatingSystemVersion qt_apple_os_version() if (pGestalt('sys3', &patch) != 0) return v; #endif +#endif v.major = major; v.minor = minor; v.patch = patch; diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 48d70f2747..30a3204d3d 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -617,7 +617,8 @@ void QCoreApplicationPrivate::initLocale() This class is used by non-GUI applications to provide their event loop. For non-GUI application that uses Qt, there should be exactly one QCoreApplication object. For GUI applications, see - QApplication. + QGuiApplication. For applications that use the Qt Widgets module, + see QApplication. QCoreApplication contains the main event loop, where all events from the operating system (e.g., timer and network events) and @@ -631,10 +632,10 @@ void QCoreApplicationPrivate::initLocale() operations can call processEvents() to keep the application responsive. - In general, we recommend that you create a QCoreApplication or a - QApplication object in your \c main() function as early as - possible. exec() will not return until the event loop exits; e.g., - when quit() is called. + In general, we recommend that you create a QCoreApplication, + QGuiApplication or a QApplication object in your \c main() + function as early as possible. exec() will not return until + the event loop exits; e.g., when quit() is called. Several static convenience functions are also provided. The QCoreApplication object is available from instance(). Events can @@ -676,8 +677,8 @@ void QCoreApplicationPrivate::initLocale() instance, when converting between data types such as floats and strings, since the notation may differ between locales. To get around this problem, call the POSIX function \c{setlocale(LC_NUMERIC,"C")} - right after initializing QApplication or QCoreApplication to reset - the locale that is used for number formatting to "C"-locale. + right after initializing QApplication, QGuiApplication or QCoreApplication + to reset the locale that is used for number formatting to "C"-locale. \sa QGuiApplication, QAbstractEventDispatcher, QEventLoop, {Semaphores Example}, {Wait Conditions Example} @@ -687,7 +688,7 @@ void QCoreApplicationPrivate::initLocale() \fn static QCoreApplication *QCoreApplication::instance() Returns a pointer to the application's QCoreApplication (or - QApplication) instance. + QGuiApplication/QApplication) instance. If no instance has been allocated, \c null is returned. */ @@ -702,7 +703,7 @@ QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p) : QObject(p, 0) #endif { - init(); + d_func()->q_ptr = this; // note: it is the subclasses' job to call // QCoreApplicationPrivate::eventDispatcher->startingUp(); } @@ -751,27 +752,26 @@ QCoreApplication::QCoreApplication(int &argc, char **argv : QObject(*new QCoreApplicationPrivate(argc, argv, _internal)) #endif { - init(); + d_func()->q_ptr = this; + d_func()->init(); #ifndef QT_NO_QOBJECT QCoreApplicationPrivate::eventDispatcher->startingUp(); #endif } -// ### move to QCoreApplicationPrivate constructor? -void QCoreApplication::init() +void QCoreApplicationPrivate::init() { - d_ptr->q_ptr = this; - Q_D(QCoreApplication); + Q_Q(QCoreApplication); - QCoreApplicationPrivate::initLocale(); + initLocale(); - Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object"); - QCoreApplication::self = this; + Q_ASSERT_X(!QCoreApplication::self, "QCoreApplication", "there should be only one application object"); + QCoreApplication::self = q; // Store app name (so it's still available after QCoreApplication is destroyed) if (!coreappdata()->applicationNameSet) - coreappdata()->application = d_func()->appName(); + coreappdata()->application = appName(); QLoggingRegistry::instance()->init(); @@ -787,7 +787,7 @@ void QCoreApplication::init() // anywhere in the list, we can just linearly scan the lists and find the items that // have been removed. Once the original list is exhausted we know all the remaining // items have been added. - QStringList newPaths(libraryPaths()); + QStringList newPaths(q->libraryPaths()); for (int i = manualPaths->length(), j = appPaths->length(); i > 0 || j > 0; qt_noop()) { if (--j < 0) { newPaths.prepend((*manualPaths)[--i]); @@ -807,28 +807,28 @@ void QCoreApplication::init() #ifndef QT_NO_QOBJECT // use the event dispatcher created by the app programmer (if any) - if (!QCoreApplicationPrivate::eventDispatcher) - QCoreApplicationPrivate::eventDispatcher = d->threadData->eventDispatcher.load(); + if (!eventDispatcher) + eventDispatcher = threadData->eventDispatcher.load(); // otherwise we create one - if (!QCoreApplicationPrivate::eventDispatcher) - d->createEventDispatcher(); - Q_ASSERT(QCoreApplicationPrivate::eventDispatcher != 0); + if (!eventDispatcher) + createEventDispatcher(); + Q_ASSERT(eventDispatcher); - if (!QCoreApplicationPrivate::eventDispatcher->parent()) { - QCoreApplicationPrivate::eventDispatcher->moveToThread(d->threadData->thread); - QCoreApplicationPrivate::eventDispatcher->setParent(this); + if (!eventDispatcher->parent()) { + eventDispatcher->moveToThread(threadData->thread); + eventDispatcher->setParent(q); } - d->threadData->eventDispatcher = QCoreApplicationPrivate::eventDispatcher; - d->eventDispatcherReady(); + threadData->eventDispatcher = eventDispatcher; + eventDispatcherReady(); #endif #ifdef QT_EVAL extern void qt_core_eval_init(QCoreApplicationPrivate::Type); - qt_core_eval_init(d->application_type); + qt_core_eval_init(application_type); #endif - d->processCommandLineArguments(); + processCommandLineArguments(); qt_call_pre_routines(); qt_startup_hook(); @@ -838,7 +838,7 @@ void QCoreApplication::init() #endif #ifndef QT_NO_QOBJECT - QCoreApplicationPrivate::is_app_running = true; // No longer starting up. + is_app_running = true; // No longer starting up. #endif } @@ -1868,7 +1868,7 @@ void QCoreApplication::quit() Installing or removing a QTranslator, or changing an installed QTranslator generates a \l{QEvent::LanguageChange}{LanguageChange} event for the - QCoreApplication instance. A QApplication instance will propagate the event + QCoreApplication instance. A QGuiApplication instance will propagate the event to all toplevel windows, where a reimplementation of changeEvent can re-translate the user interface by passing user-visible strings via the tr() function to the respective property setters. User-interface classes diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h index d865c4e7a8..a008c25c76 100644 --- a/src/corelib/kernel/qcoreapplication.h +++ b/src/corelib/kernel/qcoreapplication.h @@ -200,8 +200,6 @@ private: static bool notifyInternal2(QObject *receiver, QEvent *); #endif - void init(); - static QCoreApplication *self; Q_DISABLE_COPY(QCoreApplication) diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 9a9e8dd09a..45c34b7df2 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -74,6 +74,8 @@ public: QCoreApplicationPrivate(int &aargc, char **aargv, uint flags); ~QCoreApplicationPrivate(); + void init(); + QString appName() const; #ifdef Q_OS_MAC diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index 53da4a849b..9aa3a2d290 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -317,6 +317,11 @@ private: friend class QGraphicsView; friend class QGraphicsScene; friend class QGraphicsScenePrivate; + // from QtTest: + friend class QSpontaneKeyEvent; + // needs this: + Q_ALWAYS_INLINE + void setSpontaneous() { spont = true; } }; class Q_CORE_EXPORT QTimerEvent : public QEvent diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp index df070dd1ae..ca4ba72b66 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt.cpp +++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp @@ -210,8 +210,10 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags) const QVector<HANDLE> timerHandles = d->timerIdToHandle.values().toVector(); if (waitTime) emit aboutToBlock(); + bool timerEventsSent = false; DWORD waitResult = WaitForMultipleObjectsEx(timerHandles.count(), timerHandles.constData(), FALSE, waitTime, TRUE); - if (waitResult >= WAIT_OBJECT_0 && waitResult < WAIT_OBJECT_0 + timerHandles.count()) { + while (waitResult >= WAIT_OBJECT_0 && waitResult < WAIT_OBJECT_0 + timerHandles.count()) { + timerEventsSent = true; const HANDLE handle = timerHandles.value(waitResult - WAIT_OBJECT_0); ResetEvent(handle); const int timerId = d->timerHandleToId.value(handle); @@ -226,12 +228,10 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags) // Update timer's targetTime const quint64 targetTime = qt_msectime() + info.interval; info.targetTime = targetTime; - emit awake(); - return true; + waitResult = WaitForMultipleObjectsEx(timerHandles.count(), timerHandles.constData(), FALSE, 0, TRUE); } emit awake(); - - if (userEventsSent) + if (timerEventsSent || userEventsSent) return true; // We cannot wait infinitely like on other platforms, as diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index c316ebc69f..5afdd6a4e5 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3536,7 +3536,7 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect QMutexLocker &locker) { const int *argumentTypes = c->argumentTypes.load(); - if (!argumentTypes && argumentTypes != &DIRECT_CONNECTION_ONLY) { + if (!argumentTypes) { QMetaMethod m = QMetaObjectPrivate::signal(sender->metaObject(), signal); argumentTypes = queuedConnectionTypes(m.parameterTypes()); if (!argumentTypes) // cannot queue arguments diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 64c5b58fd4..771d2f5ea0 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -113,8 +113,8 @@ public: Q_INVOKABLE explicit QObject(QObject *parent=Q_NULLPTR); virtual ~QObject(); - virtual bool event(QEvent *); - virtual bool eventFilter(QObject *, QEvent *); + virtual bool event(QEvent *event); + virtual bool eventFilter(QObject *watched, QEvent *event); #ifdef Q_QDOC static QString tr(const char *sourceText, const char *comment = Q_NULLPTR, int n = -1); @@ -189,9 +189,9 @@ public: inline const QObjectList &children() const { return d_ptr->children; } - void setParent(QObject *); - void installEventFilter(QObject *); - void removeEventFilter(QObject *); + void setParent(QObject *parent); + void installEventFilter(QObject *filterObj); + void removeEventFilter(QObject *obj); static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType = Qt::AutoConnection); @@ -430,9 +430,9 @@ protected: int receivers(const char* signal) const; bool isSignalConnected(const QMetaMethod &signal) const; - virtual void timerEvent(QTimerEvent *); - virtual void childEvent(QChildEvent *); - virtual void customEvent(QEvent *); + virtual void timerEvent(QTimerEvent *event); + virtual void childEvent(QChildEvent *event); + virtual void customEvent(QEvent *event); virtual void connectNotify(const QMetaMethod &signal); virtual void disconnectNotify(const QMetaMethod &signal); diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index b1ed971eba..2e9ed4fb5f 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -152,6 +152,12 @@ inline void qYouForgotTheQ_OBJECT_Macro(T1, T2) {} # define Q_OBJECT_NO_OVERRIDE_WARNING #endif +#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 600 +# define Q_OBJECT_NO_ATTRIBUTES_WARNING QT_WARNING_DISABLE_GCC("-Wattributes") +#else +# define Q_OBJECT_NO_ATTRIBUTES_WARNING +#endif + /* qmake ignore Q_OBJECT */ #define Q_OBJECT \ public: \ @@ -162,10 +168,11 @@ public: \ virtual const QMetaObject *metaObject() const; \ virtual void *qt_metacast(const char *); \ virtual int qt_metacall(QMetaObject::Call, int, void **); \ - QT_WARNING_POP \ QT_TR_FUNCTIONS \ private: \ + Q_OBJECT_NO_ATTRIBUTES_WARNING \ Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \ + QT_WARNING_POP \ struct QPrivateSignal {}; /* qmake ignore Q_OBJECT */ @@ -179,7 +186,11 @@ public: \ void qt_check_for_QGADGET_macro(); \ typedef void QtGadgetHelper; \ private: \ - Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); + QT_WARNING_PUSH \ + Q_OBJECT_NO_ATTRIBUTES_WARNING \ + Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \ + QT_WARNING_POP \ + /*end*/ #endif // QT_NO_META_MACROS #else // Q_MOC_RUN diff --git a/src/corelib/mimetypes/qmimemagicrule.cpp b/src/corelib/mimetypes/qmimemagicrule.cpp index 6a3a429179..44834420fe 100644 --- a/src/corelib/mimetypes/qmimemagicrule.cpp +++ b/src/corelib/mimetypes/qmimemagicrule.cpp @@ -42,6 +42,7 @@ #include <QtCore/QList> #include <QtCore/QDebug> #include <qendian.h> +#include <private/qsimd_p.h> // for qUnalignedLoad QT_BEGIN_NAMESPACE @@ -176,7 +177,7 @@ static bool matchNumber(const QMimeMagicRulePrivate *d, const QByteArray &data) const char *p = data.constData() + d->startPos; const char *e = data.constData() + qMin(data.size() - int(sizeof(T)), d->endPos + 1); for ( ; p <= e; ++p) { - if ((*reinterpret_cast<const T*>(p) & mask) == (value & mask)) + if ((qUnalignedLoad<T>(p) & mask) == (value & mask)) return true; } diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp index 917c29b8d6..0c64db4d48 100644 --- a/src/corelib/mimetypes/qmimeprovider.cpp +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -591,9 +591,8 @@ void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data) const QStringRef name = xml.attributes().value(QLatin1String("type")); if (name.isEmpty()) continue; - if (name != data.name) { + if (name.compare(data.name, Qt::CaseInsensitive)) qWarning() << "Got name" << name << "in file" << file << "expected" << data.name; - } while (xml.readNextStartElement()) { const QStringRef tag = xml.name(); diff --git a/src/corelib/plugin/plugin.pri b/src/corelib/plugin/plugin.pri index 8b64f93467..473480eb55 100644 --- a/src/corelib/plugin/plugin.pri +++ b/src/corelib/plugin/plugin.pri @@ -35,4 +35,4 @@ integrity { SOURCES += plugin/qlibrary_unix.cpp } -LIBS_PRIVATE += $$QMAKE_LIBS_DYNLOAD +!no-libdl: LIBS_PRIVATE += $$QMAKE_LIBS_DYNLOAD diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp index cd158a9e49..13bc129605 100644 --- a/src/corelib/plugin/qlibrary_unix.cpp +++ b/src/corelib/plugin/qlibrary_unix.cpp @@ -286,7 +286,7 @@ bool QLibraryPrivate::unload_sys() return true; } -#ifdef Q_OS_LINUX +#if defined(Q_OS_LINUX) && !defined(QT_NO_DYNAMIC_LIBRARY) Q_CORE_EXPORT QFunctionPointer qt_linux_find_symbol_sys(const char *symbol) { return QFunctionPointer(dlsym(RTLD_DEFAULT, symbol)); diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index 590479d68c..a0a2e76bda 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -303,8 +303,9 @@ QThreadPrivate::~QThreadPrivate() The effect of the \a priority parameter is dependent on the operating system's scheduling policy. In particular, the \a priority will be ignored on systems that do not support thread priorities - (such as on Linux, see http://linux.die.net/man/2/sched_setscheduler - for more details). + (such as on Linux, see the + \l {http://linux.die.net/man/2/sched_setscheduler}{sched_setscheduler} + documentation for more details). \sa run(), terminate() */ diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index 32e8a52a28..6df85d8b8f 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -31,12 +31,6 @@ ** ****************************************************************************/ -//#define WINVER 0x0500 -#if !defined(WINAPI_FAMILY) && (_WIN32_WINNT < 0x0400) -#define _WIN32_WINNT 0x0400 -#endif - - #include "qthread.h" #include "qthread_p.h" #include "qthreadstorage.h" diff --git a/src/corelib/thread/thread.pri b/src/corelib/thread/thread.pri index 2cb00a6cf4..0a989cfcaf 100644 --- a/src/corelib/thread/thread.pri +++ b/src/corelib/thread/thread.pri @@ -43,24 +43,20 @@ SOURCES += thread/qatomic.cpp \ thread/qthreadpool.cpp \ thread/qthreadstorage.cpp -unix:SOURCES += thread/qthread_unix.cpp \ - thread/qwaitcondition_unix.cpp - -win32:SOURCES += thread/qthread_win.cpp \ - thread/qwaitcondition_win.cpp - -integrity:SOURCES += thread/qthread_unix.cpp \ - thread/qwaitcondition_unix.cpp - -false { - # files #included by others, but listed here so IDEs parsing this file know - # they are part of QtCore. Usually, qmake can find out that certain files - # are #included by others and thus remove from SOURCES, but it gets lost - # with qmutex.cpp. +win32 { SOURCES += \ - thread/qmutex_linux.cpp \ - thread/qmutex_mac.cpp \ - thread/qmutex_unix.cpp \ - thread/qmutex_win.cpp + thread/qmutex_win.cpp \ + thread/qthread_win.cpp \ + thread/qwaitcondition_win.cpp +} else { + darwin { + SOURCES += thread/qmutex_mac.cpp + } else: linux { + SOURCES += thread/qmutex_linux.cpp + } else { + SOURCES += thread/qmutex_unix.cpp + } + SOURCES += \ + thread/qthread_unix.cpp \ + thread/qwaitcondition_unix.cpp } - diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index cf4fcd4929..d4004098c5 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -155,7 +155,7 @@ bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const case AmPmSection: hour = (newVal == 0 ? hour % 12 : (hour % 12) + 12); break; default: qWarning("QDateTimeParser::setDigit() Internal error (%s)", - qPrintable(sectionName(node.type))); + qPrintable(node.name())); break; } @@ -206,7 +206,7 @@ int QDateTimeParser::absoluteMax(int s, const QDateTime &cur) const default: break; } qWarning("QDateTimeParser::absoluteMax() Internal error (%s)", - qPrintable(sectionName(sn.type))); + qPrintable(sn.name())); return -1; } @@ -235,7 +235,7 @@ int QDateTimeParser::absoluteMin(int s) const default: break; } qWarning("QDateTimeParser::absoluteMin() Internal error (%s, %0x)", - qPrintable(sectionName(sn.type)), sn.type); + qPrintable(sn.name()), sn.type); return -1; } @@ -290,7 +290,7 @@ int QDateTimeParser::sectionPos(const SectionNode &sn) const default: break; } if (sn.pos == -1) { - qWarning("QDateTimeParser::sectionPos Internal error (%s)", qPrintable(sectionName(sn.type))); + qWarning("QDateTimeParser::sectionPos Internal error (%s)", qPrintable(sn.name())); return -1; } return sn.pos; @@ -514,7 +514,7 @@ bool QDateTimeParser::parseFormat(const QString &newFormat) last.pos = -1; // for (int i=0; i<sectionNodes.size(); ++i) { -// QDTPDEBUG << sectionName(sectionNodes.at(i).type) << sectionNodes.at(i).count; +// QDTPDEBUG << sectionNodes.at(i).name() << sectionNodes.at(i).count; // } QDTPDEBUG << newFormat << displayFormat; @@ -625,7 +625,7 @@ int QDateTimeParser::sectionMaxSize(Section s, int count) const case TimeSectionMask: case DateSectionMask: qWarning("QDateTimeParser::sectionMaxSize: Invalid section %s", - sectionName(s).toLatin1().constData()); + SectionNode::name(s).toLatin1().constData()); case NoSectionIndex: case FirstSectionIndex: @@ -691,7 +691,7 @@ int QDateTimeParser::parseSection(const QDateTime ¤tValue, int sectionInde const SectionNode &sn = sectionNode(sectionIndex); if ((sn.type & Internal) == Internal) { qWarning("QDateTimeParser::parseSection Internal error (%s %d)", - qPrintable(sectionName(sn.type)), sectionIndex); + qPrintable(sn.name()), sectionIndex); return -1; } @@ -699,7 +699,7 @@ int QDateTimeParser::parseSection(const QDateTime ¤tValue, int sectionInde QString sectiontext = text.mid(index, sectionmaxsize); int sectiontextSize = sectiontext.size(); - QDTPDEBUG << "sectionValue for" << sectionName(sn.type) + QDTPDEBUG << "sectionValue for" << sn.name() << "with text" << text << "and st" << sectiontext << text.mid(index, sectionmaxsize) << index; @@ -849,7 +849,7 @@ int QDateTimeParser::parseSection(const QDateTime ¤tValue, int sectionInde break; } default: qWarning("QDateTimeParser::parseSection Internal error (%s %d)", - qPrintable(sectionName(sn.type)), sectionIndex); + qPrintable(sn.name()), sectionIndex); return -1; } @@ -910,7 +910,7 @@ QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPos int used; num = parseSection(currentValue, index, input, cursorPosition, pos, tmpstate, &used); - QDTPDEBUG << "sectionValue" << sectionName(sectionType(index)) << input + QDTPDEBUG << "sectionValue" << sn.name() << input << "pos" << pos << "used" << used << stateName(tmpstate); if (fixup && tmpstate == Intermediate && used < sn.count) { const FieldInfo fi = fieldInfo(index); @@ -928,7 +928,7 @@ QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPos break; } - QDTPDEBUG << index << sectionName(sectionType(index)) << "is set to" + QDTPDEBUG << index << sn.name() << "is set to" << pos << "state is" << stateName(state); @@ -948,7 +948,7 @@ QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPos case AmPmSection: current = &m; break; default: qWarning("QDateTimeParser::parse Internal error (%s)", - qPrintable(sectionName(sn.type))); + qPrintable(sn.name())); break; } if (!current) { @@ -956,7 +956,7 @@ QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPos return StateNode(); } if (isSet & sn.type && *current != num) { - QDTPDEBUG << "CONFLICT " << sectionName(sn.type) << *current << num; + QDTPDEBUG << "CONFLICT " << sn.name() << *current << num; conflicts = true; if (index != currentSectionIndex || num == -1) { continue; @@ -1040,15 +1040,16 @@ QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPos const QLocale loc = locale(); for (int i=0; i<sectionNodesCount; ++i) { - const Section thisSectionType = sectionType(i); - if (thisSectionType & (DaySection)) { - input.replace(sectionPos(i), sectionSize(i), loc.toString(day)); - } else if (thisSectionType & (DayOfWeekSectionShort|DayOfWeekSectionLong)) { + const SectionNode sn = sectionNode(i); + if (sn.type & DaySection) { + input.replace(sectionPos(sn), sectionSize(i), loc.toString(day)); + } else if (sn.type & (DayOfWeekSectionShort | DayOfWeekSectionLong)) { const int dayOfWeek = QDate(year, month, day).dayOfWeek(); - const QLocale::FormatType dayFormat = (thisSectionType == DayOfWeekSectionShort - ? QLocale::ShortFormat : QLocale::LongFormat); + const QLocale::FormatType dayFormat = + (sn.type == DayOfWeekSectionShort + ? QLocale::ShortFormat : QLocale::LongFormat); const QString dayName(loc.dayName(dayOfWeek, dayFormat)); - input.replace(sectionPos(i), sectionSize(i), dayName); + input.replace(sectionPos(sn), sectionSize(i), dayName); } } } else { @@ -1162,7 +1163,7 @@ end: toMin = newCurrentValue.daysTo(minimum); toMax = newCurrentValue.daysTo(maximum); } - const int maxChange = QDateTimeParser::maxChange(i); + const int maxChange = sn.maxChange(); if (toMin > maxChange) { QDTPDEBUG << "invalid because toMin > maxChange" << toMin << maxChange << t << newCurrentValue << minimum; @@ -1176,7 +1177,7 @@ end: const int min = getDigit(minimum, i); if (min == -1) { qWarning("QDateTimeParser::parse Internal error 4 (%s)", - qPrintable(sectionName(sn.type))); + qPrintable(sn.name())); state = Invalid; done = true; break; @@ -1188,7 +1189,7 @@ end: pos = -1; if (!potentialValue(t.simplified(), min, max, i, newCurrentValue, pos)) { QDTPDEBUG << "invalid because potentialValue(" << t.simplified() << min << max - << sectionName(sn.type) << "returned" << toMax << toMin << pos; + << sn.name() << "returned" << toMax << toMin << pos; state = Invalid; done = true; break; @@ -1354,22 +1355,20 @@ int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex /*! \internal - returns - 0 if str == tr("AM") - 1 if str == tr("PM") - 2 if str can become tr("AM") - 3 if str can become tr("PM") - 4 if str can become tr("PM") and can become tr("AM") - -1 can't become anything sensible - + Returns + AM if str == tr("AM") + PM if str == tr("PM") + PossibleAM if str can become tr("AM") + PossiblePM if str can become tr("PM") + PossibleBoth if str can become tr("PM") and can become tr("AM") + Neither if str can't become anything sensible */ - -int QDateTimeParser::findAmPm(QString &str, int sectionIndex, int *used) const +QDateTimeParser::AmPmFinder QDateTimeParser::findAmPm(QString &str, int sectionIndex, int *used) const { const SectionNode &s = sectionNode(sectionIndex); if (s.type != AmPmSection) { qWarning("QDateTimeParser::findAmPm Internal error"); - return -1; + return Neither; } if (used) *used = str.size(); @@ -1446,10 +1445,9 @@ int QDateTimeParser::findAmPm(QString &str, int sectionIndex, int *used) const Max number of units that can be changed by this section. */ -int QDateTimeParser::maxChange(int index) const +int QDateTimeParser::SectionNode::maxChange() const { - const SectionNode &sn = sectionNode(index); - switch (sn.type) { + switch (type) { // Time. unit is msec case MSecSection: return 999; case SecondSection: return 59 * 1000; @@ -1465,7 +1463,7 @@ int QDateTimeParser::maxChange(int index) const case YearSection2Digits: return 100 * 365; default: qWarning("QDateTimeParser::maxChange() Internal error (%s)", - qPrintable(sectionName(sectionType(index)))); + qPrintable(name())); } return -1; @@ -1475,8 +1473,7 @@ QDateTimeParser::FieldInfo QDateTimeParser::fieldInfo(int index) const { FieldInfo ret = 0; const SectionNode &sn = sectionNode(index); - const Section s = sn.type; - switch (s) { + switch (sn.type) { case MSecSection: ret |= Fraction; // fallthrough @@ -1487,7 +1484,7 @@ QDateTimeParser::FieldInfo QDateTimeParser::fieldInfo(int index) const case YearSection: case YearSection2Digits: ret |= Numeric; - if (s != YearSection) { + if (sn.type != YearSection) { ret |= AllowPartial; } if (sn.count != 1) { @@ -1515,30 +1512,16 @@ QDateTimeParser::FieldInfo QDateTimeParser::fieldInfo(int index) const break; default: qWarning("QDateTimeParser::fieldInfo Internal error 2 (%d %s %d)", - index, qPrintable(sectionName(sn.type)), sn.count); + index, qPrintable(sn.name()), sn.count); break; } return ret; } -/*! - \internal - - Get a number that str can become which is between min - and max or -1 if this is not possible. -*/ - - -QString QDateTimeParser::sectionFormat(int index) const -{ - const SectionNode &sn = sectionNode(index); - return sectionFormat(sn.type, sn.count); -} - -QString QDateTimeParser::sectionFormat(Section s, int count) const +QString QDateTimeParser::SectionNode::format() const { QChar fillChar; - switch (s) { + switch (type) { case AmPmSection: return count == 1 ? QLatin1String("AP") : QLatin1String("ap"); case MSecSection: fillChar = QLatin1Char('z'); break; case SecondSection: fillChar = QLatin1Char('s'); break; @@ -1553,7 +1536,7 @@ QString QDateTimeParser::sectionFormat(Section s, int count) const case YearSection: fillChar = QLatin1Char('y'); break; default: qWarning("QDateTimeParser::sectionFormat Internal error (%s)", - qPrintable(sectionName(s))); + qPrintable(name(type))); return QString(); } if (fillChar.isNull()) { @@ -1651,7 +1634,7 @@ bool QDateTimeParser::skipToNextSection(int index, const QDateTime ¤t, con For debugging. Returns the name of the section \a s. */ -QString QDateTimeParser::sectionName(int s) const +QString QDateTimeParser::SectionNode::name(QDateTimeParser::Section s) { switch (s) { case QDateTimeParser::AmPmSection: return QLatin1String("AmPmSection"); @@ -1669,7 +1652,7 @@ QString QDateTimeParser::sectionName(int s) const case QDateTimeParser::NoSection: return QLatin1String("NoSection"); case QDateTimeParser::FirstSection: return QLatin1String("FirstSection"); case QDateTimeParser::LastSection: return QLatin1String("LastSection"); - default: return QLatin1String("Unknown section ") + QString::number(s); + default: return QLatin1String("Unknown section ") + QString::number(int(s)); } } @@ -1678,7 +1661,7 @@ QString QDateTimeParser::sectionName(int s) const For debugging. Returns the name of the state \a s. */ -QString QDateTimeParser::stateName(int s) const +QString QDateTimeParser::stateName(State s) const { switch (s) { case Invalid: return QLatin1String("Invalid"); diff --git a/src/corelib/tools/qdatetimeparser_p.h b/src/corelib/tools/qdatetimeparser_p.h index c96def6046..257cb6e2cc 100644 --- a/src/corelib/tools/qdatetimeparser_p.h +++ b/src/corelib/tools/qdatetimeparser_p.h @@ -97,7 +97,7 @@ public: none.zeroesAdded = 0; } virtual ~QDateTimeParser() {} - enum { + enum AmPmFinder { Neither = -1, AM = 0, PM = 1, @@ -107,25 +107,26 @@ public: }; enum Section { - NoSection = 0x00000, - AmPmSection = 0x00001, - MSecSection = 0x00002, + NoSection = 0x00000, + AmPmSection = 0x00001, + MSecSection = 0x00002, SecondSection = 0x00004, MinuteSection = 0x00008, Hour12Section = 0x00010, Hour24Section = 0x00020, TimeSectionMask = (AmPmSection|MSecSection|SecondSection|MinuteSection|Hour12Section|Hour24Section), - Internal = 0x10000, - DaySection = 0x00100, - MonthSection = 0x00200, - YearSection = 0x00400, + DaySection = 0x00100, + MonthSection = 0x00200, + YearSection = 0x00400, YearSection2Digits = 0x00800, DayOfWeekSectionShort = 0x01000, - DayOfWeekSectionLong = 0x20000, + DayOfWeekSectionLong = 0x02000, DateSectionMask = (DaySection|MonthSection|YearSection|YearSection2Digits|DayOfWeekSectionShort|DayOfWeekSectionLong), - FirstSection = 0x02000|Internal, - LastSection = 0x04000|Internal, - CalendarPopupSection = 0x08000|Internal, + + Internal = 0x10000, + FirstSection = 0x20000 | Internal, + LastSection = 0x40000 | Internal, + CalendarPopupSection = 0x80000 | Internal, NoSectionIndex = -1, FirstSectionIndex = -2, @@ -134,11 +135,16 @@ public: }; // duplicated from qdatetimeedit.h Q_DECLARE_FLAGS(Sections, Section) - struct SectionNode { + struct Q_CORE_EXPORT SectionNode { Section type; mutable int pos; int count; int zeroesAdded; + + static QString name(Section s); + QString name() const { return name(type); } + QString format() const; + int maxChange() const; }; enum State { // duplicated from QValidator @@ -195,16 +201,12 @@ public: int findDay(const QString &str1, int intDaystart, int sectionIndex, QString *dayName = 0, int *used = 0) const; #endif - int findAmPm(QString &str1, int index, int *used = 0) const; - int maxChange(int s) const; + AmPmFinder findAmPm(QString &str, int index, int *used = 0) const; bool potentialValue(const QString &str, int min, int max, int index, const QDateTime ¤tValue, int insert) const; bool skipToNextSection(int section, const QDateTime ¤t, const QString §ionText) const; - QString sectionName(int s) const; - QString stateName(int s) const; - QString sectionFormat(int index) const; - QString sectionFormat(Section s, int count) const; + QString stateName(State s) const; enum FieldInfoFlag { Numeric = 0x01, diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index b334a697a9..ac9e08de8b 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -106,24 +106,24 @@ static uint crc32(const Char *ptr, size_t len, uint h) p += 8; for ( ; p <= e; p += 8) - h2 = _mm_crc32_u64(h2, *reinterpret_cast<const qlonglong *>(p - 8)); + h2 = _mm_crc32_u64(h2, qUnalignedLoad<qlonglong>(p - 8)); h = h2; p -= 8; len = e - p; if (len & 4) { - h = _mm_crc32_u32(h, *reinterpret_cast<const uint *>(p)); + h = _mm_crc32_u32(h, qUnalignedLoad<uint>(p)); p += 4; } # else p += 4; for ( ; p <= e; p += 4) - h = _mm_crc32_u32(h, *reinterpret_cast<const uint *>(p - 4)); + h = _mm_crc32_u32(h, qUnalignedLoad<uint>(p - 4)); p -= 4; len = e - p; # endif if (len & 2) { - h = _mm_crc32_u16(h, *reinterpret_cast<const ushort *>(p)); + h = _mm_crc32_u16(h, qUnalignedLoad<ushort>(p)); p += 2; } if (sizeof(Char) == 1 && len & 1) @@ -308,7 +308,7 @@ int qGlobalQHashSeed() /*! \relates QHash \since 5.6 - Sets the global QHash seed. + Sets the global QHash seed to \a newSeed. Manually setting the global QHash seed value should be done only for testing and debugging purposes, when deterministic and reproducible behavior on a QHash diff --git a/src/corelib/tools/qlocale_unix.cpp b/src/corelib/tools/qlocale_unix.cpp index a333be62fa..732c4445df 100644 --- a/src/corelib/tools/qlocale_unix.cpp +++ b/src/corelib/tools/qlocale_unix.cpp @@ -247,7 +247,7 @@ QVariant QSystemLocale::query(QueryType type, QVariant in) const case StringToAlternateQuotation: return lc_messages.quoteString(in.value<QStringRef>(), QLocale::AlternateQuotation); case ListToSeparatedString: - return lc_messages.createSeparatedList(in.value<QStringList>()); + return lc_messages.createSeparatedList(in.toStringList()); case LocaleChanged: Q_ASSERT(false); default: diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp index e49a1a098d..27ae07441e 100644 --- a/src/corelib/tools/qmap.cpp +++ b/src/corelib/tools/qmap.cpp @@ -1175,7 +1175,7 @@ void QMapDataBase::freeData(QMapDataBase *d) /*! \fn QPair<iterator, iterator> QMap::equal_range(const Key &key) - Returns a pair of iterators delimiting the range of values that + Returns a pair of iterators delimiting the range of values \c{[first, second)}, that are stored under \a key. */ diff --git a/src/corelib/tools/qrect.h b/src/corelib/tools/qrect.h index 59cecf9a01..a0449ae134 100644 --- a/src/corelib/tools/qrect.h +++ b/src/corelib/tools/qrect.h @@ -245,7 +245,7 @@ Q_DECL_CONSTEXPR inline QPoint QRect::bottomLeft() const Q_DECL_NOTHROW { return QPoint(x1, y2); } Q_DECL_CONSTEXPR inline QPoint QRect::center() const Q_DECL_NOTHROW -{ return QPoint((x1+x2)/2, (y1+y2)/2); } +{ return QPoint(int((qint64(x1)+x2)/2), int((qint64(y1)+y2)/2)); } // cast avoids overflow on addition Q_DECL_CONSTEXPR inline int QRect::width() const Q_DECL_NOTHROW { return x2 - x1 + 1; } diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 86f4c6a268..851c1b3a1c 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -126,7 +126,7 @@ object being tracked is the same. \omit - \secton1 QSharedPointer internals + \section1 QSharedPointer internals QSharedPointer has two "private" members: the pointer itself being tracked and a d-pointer. Those members are private to the class, but QSharedPointer @@ -338,7 +338,7 @@ creating a QSharedPointer using toStrongRef() is too high. \omit - \secton1 QWeakPointer internals + \section1 QWeakPointer internals QWeakPointer shares most of its internal functionality with \l{QSharedPointer#qsharedpointer-internals}{QSharedPointer}, so see that diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index f07eb098f2..5ca2ce4c6f 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -716,4 +716,26 @@ void qDumpCPUFeatures() puts(""); } +/*! + \internal + \fn T qUnalignedLoad(const void *ptr) + \since 5.6.1 + + Loads a \c{T} from address \a ptr, which may be misaligned. + + Use of this function avoid the undefined behavior that the C++ standard + otherwise attributes to unaligned loads. +*/ + +/*! + \internal + \fn void qUnalignedStore(void *ptr, T t) + \since 5.6.1 + + Stores \a t to address \a ptr, which may be misaligned. + + Use of this function avoid the undefined behavior that the C++ standard + otherwise attributes to unaligned stores. +*/ + QT_END_NAMESPACE diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index 12a329f36c..8171184ad2 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -470,6 +470,43 @@ unsigned _bit_scan_forward(unsigned val) #define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length) \ for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((4 - ((reinterpret_cast<quintptr>(ptr) >> 2) & 0x3)) & 0x3))); ++i) +// these defines are copied from qendian.h +// in Qt 5.7, they have been moved to qglobal.h +// drop them when merging this to 5.7 +#ifdef __has_builtin +# define QT_HAS_BUILTIN(x) __has_builtin(x) +#else +# define QT_HAS_BUILTIN(x) 0 +#endif + +template <typename T> +Q_ALWAYS_INLINE +T qUnalignedLoad(const void *ptr) Q_DECL_NOTHROW +{ + T result; +#if QT_HAS_BUILTIN(__builtin_memcpy) + __builtin_memcpy +#else + memcpy +#endif + /*memcpy*/(&result, ptr, sizeof result); + return result; +} + +template <typename T> +Q_ALWAYS_INLINE +void qUnalignedStore(void *ptr, T t) Q_DECL_NOTHROW +{ +#if QT_HAS_BUILTIN(__builtin_memcpy) + __builtin_memcpy +#else + memcpy +#endif + /*memcpy*/(ptr, &t, sizeof t); +} + +#undef QT_HAS_BUILTIN + QT_END_NAMESPACE #endif // QSIMD_P_H diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 39ec66c7f1..cdf37cca07 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -577,7 +577,7 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l) // we'll read uc[offset..offset+7] (16 bytes) and c[offset..offset+7] (8 bytes) if (uc + offset + 7 < e) { // same, but we're using an 8-byte load - __m128i chunk = _mm_cvtsi64_si128(*(const long long *)(c + offset)); + __m128i chunk = _mm_cvtsi64_si128(qUnalignedLoad<long long>(c + offset)); __m128i secondHalf = _mm_unpacklo_epi8(chunk, nullmask); __m128i ucdata = _mm_loadu_si128((const __m128i*)(uc + offset)); @@ -6163,11 +6163,7 @@ QString QString::vasprintf(const char *cformat, va_list ap) } case 'p': { void *arg = va_arg(ap, void*); -#ifdef Q_OS_WIN64 - quint64 i = reinterpret_cast<quint64>(arg); -#else - quint64 i = reinterpret_cast<unsigned long>(arg); -#endif + const quint64 i = reinterpret_cast<quintptr>(arg); flags |= QLocaleData::Alternate; subst = QLocaleData::c()->unsLongLongToString(i, precision, 16, width, flags); ++c; diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp index 333a5c3471..bf34a8b16f 100644 --- a/src/corelib/tools/qtimezone.cpp +++ b/src/corelib/tools/qtimezone.cpp @@ -61,7 +61,7 @@ static QTimeZonePrivate *newBackendTimeZone() #elif defined Q_OS_UNIX return new QTzTimeZonePrivate(); // Registry based timezone backend not available on WinRT -#elif defined Q_OS_WIN && !defined Q_OS_WINRT +#elif defined Q_OS_WIN return new QWinTimeZonePrivate(); #elif defined QT_USE_ICU return new QIcuTimeZonePrivate(); @@ -88,7 +88,7 @@ static QTimeZonePrivate *newBackendTimeZone(const QByteArray &ianaId) #elif defined Q_OS_UNIX return new QTzTimeZonePrivate(ianaId); // Registry based timezone backend not available on WinRT -#elif defined Q_OS_WIN && !defined Q_OS_WINRT +#elif defined Q_OS_WIN return new QWinTimeZonePrivate(ianaId); #elif defined QT_USE_ICU return new QIcuTimeZonePrivate(ianaId); diff --git a/src/corelib/tools/qtimezoneprivate_win.cpp b/src/corelib/tools/qtimezoneprivate_win.cpp index a9bb3aa3b5..0cb26c2e5b 100644 --- a/src/corelib/tools/qtimezoneprivate_win.cpp +++ b/src/corelib/tools/qtimezoneprivate_win.cpp @@ -42,6 +42,10 @@ QT_BEGIN_NAMESPACE +#ifndef Q_OS_WINRT +#define QT_USE_REGISTRY_TIMEZONE 1 +#endif + /* Private @@ -59,9 +63,10 @@ QT_BEGIN_NAMESPACE // Vista introduced support for historic data, see MSDN docs on DYNAMIC_TIME_ZONE_INFORMATION // http://msdn.microsoft.com/en-gb/library/windows/desktop/ms724253%28v=vs.85%29.aspx - +#ifdef QT_USE_REGISTRY_TIMEZONE static const char tzRegPath[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones"; static const char currTzRegPath[] = "SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation"; +#endif enum { MIN_YEAR = -292275056, @@ -123,6 +128,7 @@ static bool equalTzi(const TIME_ZONE_INFORMATION &tzi1, const TIME_ZONE_INFORMAT && wcscmp(tzi1.DaylightName, tzi2.DaylightName) == 0); } +#ifdef QT_USE_REGISTRY_TIMEZONE static bool openRegistryKey(const QString &keyPath, HKEY *key) { return (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (const wchar_t*)keyPath.utf16(), 0, KEY_READ, key) @@ -197,9 +203,61 @@ static TIME_ZONE_INFORMATION getRegistryTzi(const QByteArray &windowsId, bool *o return tzi; } +#else // QT_USE_REGISTRY_TIMEZONE +struct QWinDynamicTimeZone +{ + QString standardName; + QString daylightName; + QString timezoneName; + qint32 bias; + bool daylightTime; +}; + +typedef QHash<QByteArray, QWinDynamicTimeZone> QWinRTTimeZoneHash; + +Q_GLOBAL_STATIC(QWinRTTimeZoneHash, gTimeZones) + +static void enumerateTimeZones() +{ + DYNAMIC_TIME_ZONE_INFORMATION dtzInfo; + quint32 index = 0; + QString prevTimeZoneKeyName; + while (SUCCEEDED(EnumDynamicTimeZoneInformation(index++, &dtzInfo))) { + QWinDynamicTimeZone item; + item.timezoneName = QString::fromWCharArray(dtzInfo.TimeZoneKeyName); + // As soon as key name repeats, break. Some systems continue to always + // return the last item independent of index being out of range + if (item.timezoneName == prevTimeZoneKeyName) + break; + item.standardName = QString::fromWCharArray(dtzInfo.StandardName); + item.daylightName = QString::fromWCharArray(dtzInfo.DaylightName); + item.daylightTime = !dtzInfo.DynamicDaylightTimeDisabled; + item.bias = dtzInfo.Bias; + gTimeZones->insert(item.timezoneName.toUtf8(), item); + prevTimeZoneKeyName = item.timezoneName; + } +} + +static DYNAMIC_TIME_ZONE_INFORMATION dynamicInfoForId(const QByteArray &windowsId) +{ + DYNAMIC_TIME_ZONE_INFORMATION dtzInfo; + quint32 index = 0; + QString prevTimeZoneKeyName; + while (SUCCEEDED(EnumDynamicTimeZoneInformation(index++, &dtzInfo))) { + const QString timeZoneName = QString::fromWCharArray(dtzInfo.TimeZoneKeyName); + if (timeZoneName == QLatin1String(windowsId)) + break; + if (timeZoneName == prevTimeZoneKeyName) + break; + prevTimeZoneKeyName = timeZoneName; + } + return dtzInfo; +} +#endif // QT_USE_REGISTRY_TIMEZONE static QList<QByteArray> availableWindowsIds() { +#ifdef QT_USE_REGISTRY_TIMEZONE // TODO Consider caching results in a global static, very unlikely to change. QList<QByteArray> list; HKEY key = NULL; @@ -217,10 +275,16 @@ static QList<QByteArray> availableWindowsIds() RegCloseKey(key); } return list; +#else // QT_USE_REGISTRY_TIMEZONE + if (gTimeZones->isEmpty()) + enumerateTimeZones(); + return gTimeZones->keys(); +#endif // QT_USE_REGISTRY_TIMEZONE } static QByteArray windowsSystemZoneId() { +#ifdef QT_USE_REGISTRY_TIMEZONE // On Vista and later is held in the value TimeZoneKeyName in key currTzRegPath QString id; HKEY key = NULL; @@ -241,6 +305,11 @@ static QByteArray windowsSystemZoneId() if (equalTzi(getRegistryTzi(winId, &ok), sysTzi)) return winId; } +#else // QT_USE_REGISTRY_TIMEZONE + DYNAMIC_TIME_ZONE_INFORMATION dtzi; + if (SUCCEEDED(GetDynamicTimeZoneInformation(&dtzi))) + return QString::fromWCharArray(dtzi.TimeZoneKeyName).toLocal8Bit(); +#endif // QT_USE_REGISTRY_TIMEZONE // If we can't determine the current ID use UTC return QTimeZonePrivate::utcQByteArray(); @@ -361,6 +430,7 @@ void QWinTimeZonePrivate::init(const QByteArray &ianaId) } if (!m_windowsId.isEmpty()) { +#ifdef QT_USE_REGISTRY_TIMEZONE // Open the base TZI for the time zone HKEY baseKey = NULL; const QString baseKeyPath = QString::fromUtf8(tzRegPath) + QLatin1Char('\\') @@ -397,6 +467,34 @@ void QWinTimeZonePrivate::init(const QByteArray &ianaId) } RegCloseKey(baseKey); } +#else // QT_USE_REGISTRY_TIMEZONE + if (gTimeZones->isEmpty()) + enumerateTimeZones(); + QWinRTTimeZoneHash::const_iterator it = gTimeZones->find(m_windowsId); + if (it != gTimeZones->constEnd()) { + m_displayName = it->timezoneName; + m_standardName = it->standardName; + m_daylightName = it->daylightName; + DWORD firstYear = 0; + DWORD lastYear = 0; + DYNAMIC_TIME_ZONE_INFORMATION dtzi = dynamicInfoForId(m_windowsId); + GetDynamicTimeZoneInformationEffectiveYears(&dtzi, &firstYear, &lastYear); + // If there is no dynamic information, you can still query for + // year 0, which helps simplifying following part + for (DWORD year = firstYear; year <= lastYear; ++year) { + TIME_ZONE_INFORMATION tzi; + if (!GetTimeZoneInformationForYear(year, &dtzi, &tzi)) + continue; + QWinTransitionRule rule; + rule.standardTimeBias = tzi.Bias + tzi.StandardBias; + rule.daylightTimeBias = tzi.Bias + tzi.DaylightBias - rule.standardTimeBias; + rule.standardTimeRule = tzi.StandardDate; + rule.daylightTimeRule = tzi.DaylightDate; + rule.startYear = year; + m_tranRules.append(rule); + } + } +#endif // QT_USE_REGISTRY_TIMEZONE } // If there are no rules then we failed to find a windowsId or any tzi info diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index ed07f70e87..ed6afe70ce 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -147,9 +147,11 @@ else:unix { SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp tools/qtimezoneprivate_tz.cpp } else:win32 { - SOURCES += tools/qelapsedtimer_win.cpp tools/qlocale_win.cpp - !winrt: SOURCES += tools/qtimezoneprivate_win.cpp + SOURCES += tools/qelapsedtimer_win.cpp \ + tools/qlocale_win.cpp \ + tools/qtimezoneprivate_win.cpp winphone: LIBS_PRIVATE += -lWindowsPhoneGlobalizationUtil + winrt-*-msvc2013: LIBS += advapi32.lib } else:integrity:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp else:SOURCES += tools/qelapsedtimer_generic.cpp diff --git a/src/dbus/dbus.pro b/src/dbus/dbus.pro index ebeab5c1b0..4c1aec7bb3 100644 --- a/src/dbus/dbus.pro +++ b/src/dbus/dbus.pro @@ -25,8 +25,6 @@ win32 { QMAKE_DOCS = $$PWD/doc/qtdbus.qdocconf -load(qt_module) - PUB_HEADERS = qdbusargument.h \ qdbusconnectioninterface.h \ qdbusmacros.h \ @@ -91,3 +89,5 @@ SOURCES += qdbusconnection.cpp \ qdbusservicewatcher.cpp \ qdbusunixfiledescriptor.cpp \ qdbusvirtualobject.cpp + +load(qt_module) diff --git a/src/gui/gui.pro b/src/gui/gui.pro index aa05d72a3d..69434e801f 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -23,8 +23,6 @@ win32:contains(QT_CONFIG, angle)|contains(QT_CONFIG, dynamicgl) { \$\$QT_MODULE_INCLUDE_BASE/QtANGLE } -load(qt_module) - # Code coverage with TestCocoon # The following is required as extra compilers use $$QMAKE_CXX instead of $(CXX). # Without this, testcocoon.prf is read only after $$QMAKE_CXX is used by the @@ -50,6 +48,7 @@ include(itemmodels/itemmodels.pri) QMAKE_LIBS += $$QMAKE_LIBS_GUI +load(qt_module) load(cmake_functions) win32: CMAKE_WINDOWS_BUILD = True diff --git a/src/gui/image/qgifhandler.cpp b/src/gui/image/qgifhandler.cpp index 7ba6b123e8..9c748c0373 100644 --- a/src/gui/image/qgifhandler.cpp +++ b/src/gui/image/qgifhandler.cpp @@ -199,7 +199,7 @@ void QGIFFormat::disposePrevious(QImage *image) fillRect(image, l, t, r-l+1, b-t+1, color(bgcol)); } else { // Impossible: We don't know of a bgcol - use pixel 0 - QRgb *bits = (QRgb*)image->bits(); + const QRgb *bits = reinterpret_cast<const QRgb *>(image->constBits()); fillRect(image, l, t, r-l+1, b-t+1, bits[0]); } // ### Changed: QRect(l, t, r-l+1, b-t+1) @@ -208,7 +208,7 @@ void QGIFFormat::disposePrevious(QImage *image) if (frame >= 0) { for (int ln=t; ln<=b; ln++) { memcpy(image->scanLine(ln)+l, - backingstore.scanLine(ln-t), + backingstore.constScanLine(ln-t), (r-l+1)*sizeof(QRgb)); } // ### Changed: QRect(l, t, r-l+1, b-t+1) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 667b65431e..6f649efcf4 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -4411,7 +4411,8 @@ QImage QImage::smoothScaled(int w, int h) const { src = src.convertToFormat(QImage::Format_RGB32); } src = qSmoothScaleImage(src, w, h); - copyMetadata(src.d, d); + if (!src.isNull()) + copyMetadata(src.d, d); return src; } diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index 888c7beb32..d05044c44b 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -138,7 +138,7 @@ public: QImage(const QImage &); #ifdef Q_COMPILER_RVALUE_REFS inline QImage(QImage &&other) Q_DECL_NOEXCEPT - : QPaintDevice(), d(0) + : QPaintDevice(), d(Q_NULLPTR) { qSwap(d, other.d); } #endif ~QImage(); diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 0ef587f333..4322a41abd 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -1623,6 +1623,7 @@ void supportedImageHandlerMimeTypes(QFactoryLoader *loader, QList<QByteArray> QImageReader::supportedImageFormats() { QList<QByteArray> formats; + formats.reserve(_qt_NumFormats); for (int i = 0; i < _qt_NumFormats; ++i) formats << _qt_BuiltInFormats[i].extension; @@ -1647,6 +1648,7 @@ QList<QByteArray> QImageReader::supportedImageFormats() QList<QByteArray> QImageReader::supportedMimeTypes() { QList<QByteArray> mimeTypes; + mimeTypes.reserve(_qt_NumFormats); for (int i = 0; i < _qt_NumFormats; ++i) mimeTypes << _qt_BuiltInFormats[i].mimeType; diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index fb62889e40..0c8ab527b2 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -481,7 +481,7 @@ QMatrix QPixmap::trueMatrix(const QMatrix &m, int w, int h) bool QPixmap::isQBitmap() const { - return data->type == QPlatformPixmap::BitmapType; + return data && data->type == QPlatformPixmap::BitmapType; } /*! diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp index b254c5a2af..a68425e100 100644 --- a/src/gui/image/qpixmap_blitter.cpp +++ b/src/gui/image/qpixmap_blitter.cpp @@ -183,7 +183,7 @@ void QBlittablePlatformPixmap::fromImage(const QImage &image, correctFormatPic = correctFormatPic.convertToFormat(thisImg->format(), flags); uchar *mem = thisImg->bits(); - const uchar *bits = correctFormatPic.bits(); + const uchar *bits = correctFormatPic.constBits(); int bytesCopied = 0; while (bytesCopied < correctFormatPic.byteCount()) { memcpy(mem,bits,correctFormatPic.bytesPerLine()); diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp index a7a9b375ff..8db3bdbc7f 100644 --- a/src/gui/image/qpixmap_win.cpp +++ b/src/gui/image/qpixmap_win.cpp @@ -198,7 +198,7 @@ Q_GUI_EXPORT HBITMAP qt_createIconMask(const QBitmap &bitmap) QScopedArrayPointer<uchar> bits(new uchar[bpl * h]); bm.invertPixels(); for (int y = 0; y < h; ++y) - memcpy(bits.data() + y * bpl, bm.scanLine(y), bpl); + memcpy(bits.data() + y * bpl, bm.constScanLine(y), bpl); HBITMAP hbm = CreateBitmap(w, h, 1, 1, bits.data()); return hbm; } diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp index 7f23656c02..6eb35e1558 100644 --- a/src/gui/image/qppmhandler.cpp +++ b/src/gui/image/qppmhandler.cpp @@ -329,7 +329,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy if (image.format() == QImage::Format_Indexed8) { QVector<QRgb> color = image.colorTable(); for (uint y=0; y<h; y++) { - uchar *b = image.scanLine(y); + const uchar *b = image.constScanLine(y); uchar *p = buf; uchar *end = buf+bpl; if (gray) { @@ -350,7 +350,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy } } else { for (uint y=0; y<h; y++) { - uchar *b = image.scanLine(y); + const uchar *b = image.constScanLine(y); uchar *p = buf; uchar *end = buf + bpl; if (gray) { @@ -380,7 +380,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy uint bpl = w * 3; uchar *buf = new uchar[bpl]; for (uint y=0; y<h; y++) { - QRgb *b = (QRgb*)image.scanLine(y); + const QRgb *b = reinterpret_cast<const QRgb *>(image.constScanLine(y)); uchar *p = buf; uchar *end = buf+bpl; while (p < end) { diff --git a/src/gui/image/qxbmhandler.cpp b/src/gui/image/qxbmhandler.cpp index 81525d9dd6..44d07f1624 100644 --- a/src/gui/image/qxbmhandler.cpp +++ b/src/gui/image/qxbmhandler.cpp @@ -210,7 +210,7 @@ static bool write_xbm_image(const QImage &sourceImage, QIODevice *device, const char *p = buf; int bpl = (w+7)/8; for (int y = 0; y < h; ++y) { - uchar *b = image.scanLine(y); + const uchar *b = image.constScanLine(y); for (i = 0; i < bpl; ++i) { *p++ = '0'; *p++ = 'x'; *p++ = hexrep[*b >> 4]; diff --git a/src/gui/image/qxpmhandler.cpp b/src/gui/image/qxpmhandler.cpp index e9ac4a9cc2..fbce78eb74 100644 --- a/src/gui/image/qxpmhandler.cpp +++ b/src/gui/image/qxpmhandler.cpp @@ -1098,7 +1098,7 @@ static bool write_xpm_image(const QImage &sourceImage, QIODevice *device, const // build color table for(y=0; y<h; y++) { - QRgb * yp = (QRgb *)image.scanLine(y); + const QRgb *yp = reinterpret_cast<const QRgb *>(image.constScanLine(y)); for(x=0; x<w; x++) { QRgb color = *(yp + x); if (!colorMap.contains(color)) @@ -1144,7 +1144,7 @@ static bool write_xpm_image(const QImage &sourceImage, QIODevice *device, const // write pixels, limit to 4 characters per pixel line.truncate(cpp*w); for(y=0; y<h; y++) { - QRgb * yp = (QRgb *) image.scanLine(y); + const QRgb *yp = reinterpret_cast<const QRgb *>(image.constScanLine(y)); int cc = 0; for(x=0; x<w; x++) { int color = (int)(*(yp + x)); diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 2ca17692db..9281744692 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -726,8 +726,11 @@ QHoverEvent::~QHoverEvent() QWheelEvent::QWheelEvent(const QPointF &pos, int delta, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::Orientation orient) - : QInputEvent(Wheel, modifiers), p(pos), qt4D(delta), qt4O(orient), mouseState(buttons) + : QInputEvent(Wheel, modifiers), p(pos), qt4D(delta), qt4O(orient), mouseState(buttons), + ph(Qt::NoScrollPhase), src(Qt::MouseEventNotSynthesized) { + if (!QGuiApplicationPrivate::scrollNoPhaseAllowed) + ph = Qt::ScrollUpdate; g = QCursor::pos(); if (orient == Qt::Vertical) angleD = QPoint(0, delta); @@ -760,8 +763,11 @@ QWheelEvent::~QWheelEvent() QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::Orientation orient) - : QInputEvent(Wheel, modifiers), p(pos), g(globalPos), qt4D(delta), qt4O(orient), mouseState(buttons) + : QInputEvent(Wheel, modifiers), p(pos), g(globalPos), qt4D(delta), qt4O(orient), mouseState(buttons), + ph(Qt::NoScrollPhase), src(Qt::MouseEventNotSynthesized) { + if (!QGuiApplicationPrivate::scrollNoPhaseAllowed) + ph = Qt::ScrollUpdate; if (orient == Qt::Vertical) angleD = QPoint(0, delta); else @@ -796,8 +802,12 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) : QInputEvent(Wheel, modifiers), p(pos), g(globalPos), pixelD(pixelDelta), - angleD(angleDelta), qt4D(qt4Delta), qt4O(qt4Orientation), mouseState(buttons), ph(Qt::ScrollUpdate) -{} + angleD(angleDelta), qt4D(qt4Delta), qt4O(qt4Orientation), mouseState(buttons), ph(Qt::NoScrollPhase), + src(Qt::MouseEventNotSynthesized) +{ + if (!QGuiApplicationPrivate::scrollNoPhaseAllowed) + ph = Qt::ScrollUpdate; +} /*! Constructs a wheel event object. @@ -3569,6 +3579,7 @@ static inline void formatTouchEvent(QDebug d, const QTouchEvent &t) { d << "QTouchEvent("; QtDebugUtils::formatQEnum(d, t.type()); + d << " device: " << t.device()->name(); d << " states: "; QtDebugUtils::formatQFlags(d, t.touchPointStates()); d << ", " << t.touchPoints().size() << " points: " << t.touchPoints() << ')'; diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index b90fce97e0..b407663338 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -219,6 +219,8 @@ protected: uint ph : 2; uint src: 2; int reserved : 28; + + friend class QApplication; }; #endif @@ -795,7 +797,7 @@ public: TouchPoint(const TouchPoint &other); #ifdef Q_COMPILER_RVALUE_REFS TouchPoint(TouchPoint &&other) Q_DECL_NOEXCEPT - : d(0) + : d(Q_NULLPTR) { qSwap(d, other.d); } TouchPoint &operator=(TouchPoint &&other) Q_DECL_NOEXCEPT { qSwap(d, other.d); return *this; } diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 95e47e18a9..834449fec6 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -190,6 +190,9 @@ bool QGuiApplicationPrivate::obey_desktop_settings = true; QInputDeviceManager *QGuiApplicationPrivate::m_inputDeviceManager = 0; +// enable the fix for QTBUG-50199; TODO remove this check in 5.7 +bool QGuiApplicationPrivate::scrollNoPhaseAllowed = false; + static qreal fontSmoothingGamma = 1.7; extern void qRegisterGuiVariant(); @@ -239,11 +242,13 @@ static inline void clearFontUnlocked() QGuiApplicationPrivate::app_font = 0; } +// Using aggregate initialization instead of ctor so we can have a POD global static +#define Q_WINDOW_GEOMETRY_SPECIFICATION_INITIALIZER { Qt::TopLeftCorner, -1, -1, -1, -1 } + // Geometry specification for top level windows following the convention of the // -geometry command line arguments in X11 (see XParseGeometry). struct QWindowGeometrySpecification { - QWindowGeometrySpecification() : corner(Qt::TopLeftCorner), xOffset(-1), yOffset(-1), width(-1), height(-1) {} static QWindowGeometrySpecification fromArgument(const QByteArray &a); void applyTo(QWindow *window) const; @@ -280,7 +285,7 @@ static inline int nextGeometryToken(const QByteArray &a, int &pos, char *op) QWindowGeometrySpecification QWindowGeometrySpecification::fromArgument(const QByteArray &a) { - QWindowGeometrySpecification result; + QWindowGeometrySpecification result = Q_WINDOW_GEOMETRY_SPECIFICATION_INITIALIZER; int pos = 0; for (int i = 0; i < 4; ++i) { char op; @@ -337,7 +342,7 @@ void QWindowGeometrySpecification::applyTo(QWindow *window) const } } -static QWindowGeometrySpecification windowGeometrySpecification; +static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOMETRY_SPECIFICATION_INITIALIZER; /*! \class QGuiApplication @@ -576,7 +581,7 @@ QGuiApplication::QGuiApplication(int &argc, char **argv, int flags) QGuiApplication::QGuiApplication(QGuiApplicationPrivate &p) : QCoreApplication(p) { - d_func()->init(); } +} /*! Destructs the application. @@ -1259,6 +1264,8 @@ void QGuiApplicationPrivate::eventDispatcherReady() void QGuiApplicationPrivate::init() { + QCoreApplicationPrivate::init(); + QCoreApplicationPrivate::is_app_running = false; // Starting up. bool loadTestability = false; @@ -1414,6 +1421,8 @@ void QGuiApplicationPrivate::init() if (layout_direction == Qt::LayoutDirectionAuto || force_reverse) QGuiApplication::setLayoutDirection(qt_detectRTLLanguage() ? Qt::RightToLeft : Qt::LeftToRight); + + scrollNoPhaseAllowed = qEnvironmentVariableIsSet("QT_ENABLE_MOUSE_WHEEL_TRACKING"); } extern void qt_cleanupFontDatabase(); diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 4f0f6fdc44..306d76c5f0 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -75,6 +75,8 @@ public: QGuiApplicationPrivate(int &argc, char **argv, int flags); ~QGuiApplicationPrivate(); + void init(); + void createPlatformIntegration(); void createEventDispatcher() Q_DECL_OVERRIDE; void eventDispatcherReady() Q_DECL_OVERRIDE; @@ -286,6 +288,9 @@ public: static void setApplicationState(Qt::ApplicationState state, bool forcePropagate = false); + // enable the fix for QTBUG-50199; TODO remove this check in 5.7 + static bool scrollNoPhaseAllowed; + protected: virtual void notifyThemeChanged(); bool tryCloseRemainingWindows(QWindowList processedWindows); @@ -296,8 +301,6 @@ protected: private: friend class QDragManager; - void init(); - static QGuiApplicationPrivate *self; static QTouchDevice *m_fakeTouchDevice; static int m_fakeMouseSourcePointId; diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h index fac3ae420d..a7b80982af 100644 --- a/src/gui/kernel/qhighdpiscaling_p.h +++ b/src/gui/kernel/qhighdpiscaling_p.h @@ -162,7 +162,7 @@ inline QRect toNative(const QRect &rect, qreal scaleFactor, const QPoint &origin inline QRect fromNative(const QRect &rect, const QScreen *screen, const QPoint &screenOrigin) { - return toNative(rect, QHighDpiScaling::factor(screen), screenOrigin); + return fromNative(rect, QHighDpiScaling::factor(screen), screenOrigin); } inline QRect fromNativeScreenGeometry(const QRect &nativeScreenGeometry, const QScreen *screen) diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 46784f59be..6bb80042ee 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -1261,7 +1261,28 @@ QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat if ((key & Qt::KeypadModifier) == Qt::KeypadModifier) addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Num") : QString::fromLatin1("Num"), format); + QString p = keyName(key, format); +#if defined(Q_OS_OSX) + if (nativeText) + s += p; + else +#endif + addKey(s, p, format); + return s; +} + +/*! + \internal + Returns the text representation of the key \a key, which can be used i.e. + when the sequence is serialized. This does not take modifiers into account + (see encodeString() for a version that does). + + This static method is used by encodeString() and by the D-Bus menu exporter. +*/ +QString QKeySequencePrivate::keyName(int key, QKeySequence::SequenceFormat format) +{ + bool nativeText = (format == QKeySequence::NativeText); key &= ~(Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier); QString p; @@ -1312,14 +1333,7 @@ NonSymbol: } } } - -#if defined(Q_OS_MACX) - if (nativeText) - s += p; - else -#endif - addKey(s, p, format); - return s; + return p; } /*! Matches the sequence with \a seq. Returns ExactMatch if diff --git a/src/gui/kernel/qkeysequence_p.h b/src/gui/kernel/qkeysequence_p.h index a03549634f..6d20f798b3 100644 --- a/src/gui/kernel/qkeysequence_p.h +++ b/src/gui/kernel/qkeysequence_p.h @@ -75,6 +75,8 @@ public: QAtomicInt ref; int key[MaxKeyCount]; static QString encodeString(int key, QKeySequence::SequenceFormat format); + // used in dbusmenu + Q_GUI_EXPORT static QString keyName(int key, QKeySequence::SequenceFormat format); static int decodeString(const QString &keyStr, QKeySequence::SequenceFormat format); }; #endif // QT_NO_SHORTCUT diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index aea029b7f5..9f2c6af51f 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -484,8 +484,11 @@ QPlatformScreen *QPlatformWindow::screenForGeometry(const QRect &newGeometry) co { QPlatformScreen *currentScreen = screen(); QPlatformScreen *fallback = currentScreen; - //QRect::center can return a value outside the rectangle if it's empty - const QPoint center = newGeometry.isEmpty() ? newGeometry.topLeft() : newGeometry.center(); + // QRect::center can return a value outside the rectangle if it's empty. + // Apply mapToGlobal() in case it is a foreign/embedded window. + QPoint center = newGeometry.isEmpty() ? newGeometry.topLeft() : newGeometry.center(); + if (window()->type() == Qt::ForeignWindow) + center = mapToGlobal(center - newGeometry.topLeft()); if (!parent() && currentScreen && !currentScreen->geometry().contains(center)) { Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) { diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp index 52e7686439..e87f58d735 100644 --- a/src/gui/kernel/qscreen.cpp +++ b/src/gui/kernel/qscreen.cpp @@ -40,6 +40,7 @@ #include <QtCore/QDebug> #include <QtCore/private/qobject_p.h> +#include "qhighdpiscaling_p.h" QT_BEGIN_NAMESPACE @@ -683,7 +684,19 @@ QPixmap QScreen::grabWindow(WId window, int x, int y, int width, int height) qWarning("invoked with handle==0"); return QPixmap(); } - return platformScreen->grabWindow(window, x, y, width, height); + const qreal factor = QHighDpiScaling::factor(this); + if (qFuzzyCompare(factor, 1)) + return platformScreen->grabWindow(window, x, y, width, height); + + const QPoint nativePos = QHighDpi::toNative(QPoint(x, y), factor); + QSize nativeSize(width, height); + if (nativeSize.isValid()) + nativeSize = QHighDpi::toNative(nativeSize, factor); + QPixmap result = + platformScreen->grabWindow(window, nativePos.x(), nativePos.y(), + nativeSize.width(), nativeSize.height()); + result.setDevicePixelRatio(factor); + return result; } #ifndef QT_NO_DEBUG_STREAM diff --git a/src/gui/kernel/qshapedpixmapdndwindow.cpp b/src/gui/kernel/qshapedpixmapdndwindow.cpp index d77b6dc262..850987ac1d 100644 --- a/src/gui/kernel/qshapedpixmapdndwindow.cpp +++ b/src/gui/kernel/qshapedpixmapdndwindow.cpp @@ -42,52 +42,31 @@ QT_BEGIN_NAMESPACE QShapedPixmapWindow::QShapedPixmapWindow(QScreen *screen) - : QWindow(screen), - m_backingStore(0), - m_useCompositing(true) + : m_useCompositing(true) { + setScreen(screen); QSurfaceFormat format; format.setAlphaBufferSize(8); setFormat(format); - setSurfaceType(RasterSurface); - setFlags(Qt::ToolTip | Qt::FramelessWindowHint | - Qt::X11BypassWindowManagerHint | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus); - create(); - m_backingStore = new QBackingStore(this); + setFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint + | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus); } QShapedPixmapWindow::~QShapedPixmapWindow() { - delete m_backingStore; - m_backingStore = 0; -} - -void QShapedPixmapWindow::render() -{ - QRect rect(QPoint(), geometry().size()); - - m_backingStore->beginPaint(rect); - - QPaintDevice *device = m_backingStore->paintDevice(); - - { - QPainter p(device); - if (m_useCompositing) - p.setCompositionMode(QPainter::CompositionMode_Source); - else - p.fillRect(rect, QGuiApplication::palette().base()); - p.drawPixmap(0, 0, m_pixmap); - } - - m_backingStore->endPaint(); - m_backingStore->flush(rect); } void QShapedPixmapWindow::setPixmap(const QPixmap &pixmap) { m_pixmap = pixmap; - if (!m_useCompositing) - setMask(m_pixmap.mask()); + if (!m_useCompositing) { + const QBitmap mask = m_pixmap.mask(); + if (!mask.isNull()) { + if (!handle()) + create(); + setMask(mask); + } + } } void QShapedPixmapWindow::setHotspot(const QPoint &hotspot) @@ -95,19 +74,28 @@ void QShapedPixmapWindow::setHotspot(const QPoint &hotspot) m_hotSpot = hotspot; } -void QShapedPixmapWindow::updateGeometry(const QPoint &pos) +void QShapedPixmapWindow::paintEvent(QPaintEvent *) { - if (m_pixmap.isNull()) - m_backingStore->resize(QSize(1,1)); - else if (m_backingStore->size() != m_pixmap.size()) - m_backingStore->resize(m_pixmap.size()); - - setGeometry(QRect(pos - m_hotSpot, m_backingStore->size())); + if (!m_pixmap.isNull()) { + const QRect rect(QPoint(0, 0), size()); + QPainter painter(this); + if (m_useCompositing) + painter.setCompositionMode(QPainter::CompositionMode_Source); + else + painter.fillRect(rect, QGuiApplication::palette().base()); + painter.drawPixmap(rect, m_pixmap); + } } -void QShapedPixmapWindow::exposeEvent(QExposeEvent *) +void QShapedPixmapWindow::updateGeometry(const QPoint &pos) { - render(); + QSize size(1, 1); + if (!m_pixmap.isNull()) { + size = qFuzzyCompare(m_pixmap.devicePixelRatio(), 1.0) + ? m_pixmap.size() + : (QSizeF(m_pixmap.size()) / m_pixmap.devicePixelRatio()).toSize(); + } + setGeometry(QRect(pos - m_hotSpot, size)); } QT_END_NAMESPACE diff --git a/src/gui/kernel/qshapedpixmapdndwindow_p.h b/src/gui/kernel/qshapedpixmapdndwindow_p.h index 3d7974fa82..f2d678c1b4 100644 --- a/src/gui/kernel/qshapedpixmapdndwindow_p.h +++ b/src/gui/kernel/qshapedpixmapdndwindow_p.h @@ -45,21 +45,18 @@ // We mean it. // -#include <QtGui/QWindow> +#include <QtGui/QRasterWindow> #include <QtGui/QPixmap> -#include <QtGui/QBackingStore> QT_BEGIN_NAMESPACE -class QShapedPixmapWindow : public QWindow +class QShapedPixmapWindow : public QRasterWindow { Q_OBJECT public: explicit QShapedPixmapWindow(QScreen *screen = 0); ~QShapedPixmapWindow(); - void render(); - void setUseCompositing(bool on) { m_useCompositing = on; } void setPixmap(const QPixmap &pixmap); void setHotspot(const QPoint &hotspot); @@ -67,10 +64,9 @@ public: void updateGeometry(const QPoint &pos); protected: - void exposeEvent(QExposeEvent *) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; private: - QBackingStore *m_backingStore; QPixmap m_pixmap; QPoint m_hotSpot; bool m_useCompositing; diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp index 9f38c9b78a..00589d2303 100644 --- a/src/gui/kernel/qsimpledrag.cpp +++ b/src/gui/kernel/qsimpledrag.cpp @@ -88,7 +88,8 @@ static QWindow* topLevelAt(const QPoint &pos) QBasicDrag::QBasicDrag() : m_restoreCursor(false), m_eventLoop(0), m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false), - m_drag(0), m_drag_icon_window(0), m_useCompositing(true) + m_drag(0), m_drag_icon_window(0), m_useCompositing(true), + m_screen(Q_NULLPTR) { } @@ -211,7 +212,7 @@ void QBasicDrag::startDrag() pos = QPoint(); } #endif - recreateShapedPixmapWindow(Q_NULLPTR, pos); + recreateShapedPixmapWindow(m_screen, pos); enableEventFilter(); } diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h index 055136c436..b208c8ccc9 100644 --- a/src/gui/kernel/qsimpledrag_p.h +++ b/src/gui/kernel/qsimpledrag_p.h @@ -90,6 +90,8 @@ protected: bool useCompositing() const { return m_useCompositing; } void setUseCompositing(bool on) { m_useCompositing = on; } + void setScreen(QScreen *screen) { m_screen = screen; } + Qt::DropAction executedDropAction() const { return m_executed_drop_action; } void setExecutedDropAction(Qt::DropAction da) { m_executed_drop_action = da; } @@ -108,6 +110,7 @@ private: QDrag *m_drag; QShapedPixmapWindow *m_drag_icon_window; bool m_useCompositing; + QScreen *m_screen; }; class Q_GUI_EXPORT QSimpleDrag : public QBasicDrag diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 21734f1619..68bcbdec71 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -369,7 +369,7 @@ void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate) { Q_Q(QWindow); if (parentWindow) { - qWarning() << this << '(' << newScreen << "): Attempt to set a screen on a child window."; + qWarning() << q << '(' << newScreen << "): Attempt to set a screen on a child window."; return; } if (newScreen != topLevelScreen) { @@ -951,7 +951,7 @@ void QWindow::setMask(const QRegion ®ion) Q_D(QWindow); if (!d->platformWindow) return; - d->platformWindow->setMask(region); + d->platformWindow->setMask(QHighDpi::toNativeLocalRegion(region, this)); d->mask = region; } @@ -2298,7 +2298,7 @@ QPoint QWindow::mapToGlobal(const QPoint &pos) const // QTBUG-43252, prefer platform implementation for foreign windows. if (d->platformWindow && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) { - return d->platformWindow->mapToGlobal(pos); + return QHighDpi::fromNativeLocalPosition(d->platformWindow->mapToGlobal(QHighDpi::toNativeLocalPosition(pos, this)), this); } return pos + d->globalPosition(); } @@ -2318,7 +2318,7 @@ QPoint QWindow::mapFromGlobal(const QPoint &pos) const // QTBUG-43252, prefer platform implementation for foreign windows. if (d->platformWindow && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) { - return d->platformWindow->mapFromGlobal(pos); + return QHighDpi::fromNativeLocalPosition(d->platformWindow->mapFromGlobal(QHighDpi::toNativeLocalPosition(pos, this)), this); } return pos - d->globalPosition(); } diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index e10ddf22a7..cae976098c 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -311,6 +311,9 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *w, const QPointF & local, void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods, Qt::ScrollPhase phase, Qt::MouseEventSource source) { + if (!QGuiApplicationPrivate::scrollNoPhaseAllowed && phase == Qt::NoScrollPhase) + phase = Qt::ScrollUpdate; + // Qt 4 sends two separate wheel events for horizontal and vertical // deltas. For Qt 5 we want to send the deltas in one event, but at the // same time preserve source and behavior compatibility with Qt 4. @@ -857,7 +860,9 @@ Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF &local, const QP { bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowSystemEvents; QWindowSystemInterface::setSynchronousWindowSystemEvents(true); - QWindowSystemInterface::handleMouseEvent(w, timestamp, local, global, b, mods); + const qreal factor = QHighDpiScaling::factor(w); + QWindowSystemInterface::handleMouseEvent(w, timestamp, local * factor, + global * factor, b, mods); QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous); } @@ -906,36 +911,14 @@ Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int #endif } -static QWindowSystemInterface::TouchPoint touchPoint(const QTouchEvent::TouchPoint& pt) -{ - QWindowSystemInterface::TouchPoint p; - p.id = pt.id(); - p.flags = pt.flags(); - p.normalPosition = pt.normalizedPos(); - p.area = pt.screenRect(); - p.pressure = pt.pressure(); - p.state = pt.state(); - p.velocity = pt.velocity(); - p.rawPositions = pt.rawScreenPositions(); - return p; -} -static QList<struct QWindowSystemInterface::TouchPoint> touchPointList(const QList<QTouchEvent::TouchPoint>& pointList) -{ - QList<struct QWindowSystemInterface::TouchPoint> newList; - - Q_FOREACH (QTouchEvent::TouchPoint p, pointList) - newList.append(touchPoint(p)); - - return newList; -} - Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device, const QList<QTouchEvent::TouchPoint> &points, Qt::KeyboardModifiers mods = Qt::NoModifier) { bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowSystemEvents; QWindowSystemInterface::setSynchronousWindowSystemEvents(true); - QWindowSystemInterface::handleTouchEvent(w, device, touchPointList(points), mods); + QWindowSystemInterface::handleTouchEvent(w, device, + QWindowSystemInterfacePrivate::toNativeTouchPoints(points, w), mods); QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous); } @@ -950,5 +933,13 @@ bool QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowS return true; } +QWindowSystemInterfacePrivate::WheelEvent::WheelEvent(QWindow *w, ulong time, const QPointF &local, const QPointF &global, QPoint pixelD, + QPoint angleD, int qt4D, Qt::Orientation qt4O, Qt::KeyboardModifiers mods, Qt::ScrollPhase phase, Qt::MouseEventSource src) + : InputEvent(w, time, Wheel, mods), pixelDelta(pixelD), angleDelta(angleD), qt4Delta(qt4D), + qt4Orientation(qt4O), localPos(local), globalPos(global), + phase(!QGuiApplicationPrivate::scrollNoPhaseAllowed && phase == Qt::NoScrollPhase ? Qt::ScrollUpdate : phase), + source(src) +{ +} QT_END_NAMESPACE diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index a27c68649e..20d560f82e 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -94,8 +94,16 @@ public: quint32 nativeModifiers, const QString& text = QString(), bool autorep = false, ushort count = 1, bool tryShortcutOverride = true); - static void handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods = Qt::NoModifier, Qt::ScrollPhase phase = Qt::ScrollUpdate, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); - static void handleWheelEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods = Qt::NoModifier, Qt::ScrollPhase phase = Qt::ScrollUpdate, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); + static void handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, + QPoint pixelDelta, QPoint angleDelta, + Qt::KeyboardModifiers mods = Qt::NoModifier, + Qt::ScrollPhase phase = Qt::NoScrollPhase, + Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); + static void handleWheelEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, + QPoint pixelDelta, QPoint angleDelta, + Qt::KeyboardModifiers mods = Qt::NoModifier, + Qt::ScrollPhase phase = Qt::NoScrollPhase, + Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); // Wheel event compatibility functions. Will be removed: do not use. static void handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, int d, Qt::Orientation o, Qt::KeyboardModifiers mods = Qt::NoModifier); diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index e48d1e965b..b3c6d0d96d 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -236,8 +236,7 @@ public: class WheelEvent : public InputEvent { public: WheelEvent(QWindow *w, ulong time, const QPointF & local, const QPointF & global, QPoint pixelD, QPoint angleD, int qt4D, Qt::Orientation qt4O, - Qt::KeyboardModifiers mods, Qt::ScrollPhase phase = Qt::ScrollUpdate, Qt::MouseEventSource src = Qt::MouseEventNotSynthesized) - : InputEvent(w, time, Wheel, mods), pixelDelta(pixelD), angleDelta(angleD), qt4Delta(qt4D), qt4Orientation(qt4O), localPos(local), globalPos(global), phase(phase), source(src) { } + Qt::KeyboardModifiers mods, Qt::ScrollPhase phase = Qt::NoScrollPhase, Qt::MouseEventSource src = Qt::MouseEventNotSynthesized); QPoint pixelDelta; QPoint angleDelta; int qt4Delta; diff --git a/src/gui/opengl/qopengl.cpp b/src/gui/opengl/qopengl.cpp index a77d6743ad..3dedd7d7be 100644 --- a/src/gui/opengl/qopengl.cpp +++ b/src/gui/opengl/qopengl.cpp @@ -79,7 +79,7 @@ QOpenGLExtensionMatcher::QOpenGLExtensionMatcher() if (!glGetStringi) return; - GLint numExtensions; + GLint numExtensions = 0; funcs->glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); for (int i = 0; i < numExtensions; ++i) { diff --git a/src/gui/opengl/qopenglextrafunctions.h b/src/gui/opengl/qopenglextrafunctions.h index 6558284bd0..c53c3efba7 100644 --- a/src/gui/opengl/qopenglextrafunctions.h +++ b/src/gui/opengl/qopenglextrafunctions.h @@ -404,7 +404,7 @@ public: void glVertexBindingDivisor(GLuint bindingindex, GLuint divisor); private: - static bool isInitialized(const QOpenGLExtraFunctionsPrivate *d) { return d != 0; } + static bool isInitialized(const QOpenGLExtraFunctionsPrivate *d) { return d != Q_NULLPTR; } }; class QOpenGLExtraFunctionsPrivate : public QOpenGLFunctionsPrivate diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp index 9714aa4bec..d567800fbd 100644 --- a/src/gui/opengl/qopenglshaderprogram.cpp +++ b/src/gui/opengl/qopenglshaderprogram.cpp @@ -3386,7 +3386,7 @@ QVector<float> QOpenGLShaderProgram::defaultInnerTessellationLevels() const #if defined(QT_OPENGL_4) Q_D(const QOpenGLShaderProgram); if (d->tessellationFuncs) - d->tessellationFuncs->glGetFloatv(GL_PATCH_DEFAULT_OUTER_LEVEL, tessLevels.data()); + d->tessellationFuncs->glGetFloatv(GL_PATCH_DEFAULT_INNER_LEVEL, tessLevels.data()); #endif return tessLevels; } diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp index 8c3fd2ce4f..64da03f13a 100644 --- a/src/gui/painting/qcosmeticstroker.cpp +++ b/src/gui/painting/qcosmeticstroker.cpp @@ -62,8 +62,8 @@ static inline uint sourceOver(uint d, uint color) inline static int F16Dot16FixedDiv(int x, int y) { if (qAbs(x) > 0x7fff) - return (((qlonglong)x) << 16) / y; - return (x << 16) / y; + return qlonglong(x) * (1<<16) / y; + return x * (1<<16) / y; } typedef void (*DrawPixel)(QCosmeticStroker *stroker, int x, int y, int coverage); @@ -141,12 +141,14 @@ inline void drawPixel(QCosmeticStroker *stroker, int x, int y, int coverage) if (x < cl.x() || x > cl.right() || y < cl.y() || y > cl.bottom()) return; - int lastx = stroker->spans[stroker->current_span-1].x + stroker->spans[stroker->current_span-1].len ; - int lasty = stroker->spans[stroker->current_span-1].y; + if (stroker->current_span > 0) { + const int lastx = stroker->spans[stroker->current_span-1].x + stroker->spans[stroker->current_span-1].len ; + const int lasty = stroker->spans[stroker->current_span-1].y; - if (stroker->current_span == QCosmeticStroker::NSPANS || y < lasty || (y == lasty && x < lastx)) { - stroker->blend(stroker->current_span, stroker->spans, &stroker->state->penData); - stroker->current_span = 0; + if (stroker->current_span == QCosmeticStroker::NSPANS || y < lasty || (y == lasty && x < lastx)) { + stroker->blend(stroker->current_span, stroker->spans, &stroker->state->penData); + stroker->current_span = 0; + } } stroker->spans[stroker->current_span].x = ushort(x); @@ -433,14 +435,14 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal qSwap(x1, x2); } int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1); - int x = x1 << 10; + int x = x1 * (1<<10); int y = (y1 + 32) >> 6; int ys = (y2 + 32) >> 6; int round = (xinc > 0) ? 32 : 0; if (y != ys) { - x += ( ((((y << 6) + round - y1))) * xinc ) >> 6; + x += ((y * (1<<6)) + round - y1) * xinc >> 6; if (swapped) { lastPixel.x = x >> 16; @@ -472,7 +474,7 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal int round = (yinc > 0) ? 32 : 0; if (x != xs) { - y += ( ((((x << 6) + round - x1))) * yinc ) >> 6; + y += ((x * (1<<6)) + round - x1) * yinc >> 6; if (swapped) { lastPixel.x = x; @@ -751,7 +753,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, dir = QCosmeticStroker::BottomToTop; } int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1); - int x = x1 << 10; + int x = x1 * (1<<10); if ((stroker->lastDir ^ QCosmeticStroker::VerticalMask) == dir) caps |= swapped ? QCosmeticStroker::CapEnd : QCosmeticStroker::CapBegin; @@ -763,7 +765,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, int round = (xinc > 0) ? 32 : 0; if (y != ys) { - x += ( ((((y << 6) + round - y1))) * xinc ) >> 6; + x += ((y * (1<<6)) + round - y1) * xinc >> 6; // calculate first and last pixel and perform dropout control QCosmeticStroker::Point first; @@ -802,7 +804,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, stroker->lastDir = dir; stroker->lastAxisAligned = axisAligned; - Dasher dasher(stroker, swapped, y << 6, ys << 6); + Dasher dasher(stroker, swapped, y * (1<<6), ys * (1<<6)); do { if (dasher.on()) @@ -828,7 +830,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, dir = QCosmeticStroker::RightToLeft; } int yinc = F16Dot16FixedDiv(y2 - y1, x2 - x1); - int y = y1 << 10; + int y = y1 * (1<<10); if ((stroker->lastDir ^ QCosmeticStroker::HorizontalMask) == dir) caps |= swapped ? QCosmeticStroker::CapEnd : QCosmeticStroker::CapBegin; @@ -840,7 +842,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, int round = (yinc > 0) ? 32 : 0; if (x != xs) { - y += ( ((((x << 6) + round - x1))) * yinc ) >> 6; + y += ((x * (1<<6)) + round - x1) * yinc >> 6; // calculate first and last pixel to perform dropout control QCosmeticStroker::Point first; @@ -878,7 +880,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, stroker->lastDir = dir; stroker->lastAxisAligned = axisAligned; - Dasher dasher(stroker, swapped, x << 6, xs << 6); + Dasher dasher(stroker, swapped, x * (1<<6), xs * (1<<6)); do { if (dasher.on()) @@ -921,7 +923,7 @@ static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx caps = swapCaps(caps); } - int x = (x1 - 32) << 10; + int x = (x1 - 32) * (1<<10); x -= ( ((y1 & 63) - 32) * xinc ) >> 6; capAdjust(caps, y1, y2, x, xinc); @@ -984,7 +986,7 @@ static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx caps = swapCaps(caps); } - int y = (y1 - 32) << 10; + int y = (y1 - 32) * (1<<10); y -= ( ((x1 & 63) - 32) * yinc ) >> 6; capAdjust(caps, x1, x2, y, yinc); diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 87ceb9a89d..f0e5810b54 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1938,9 +1938,10 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c // intermediate_buffer[0] is a buffer of red-blue component of the pixel, in the form 0x00RR00BB // intermediate_buffer[1] is the alpha-green component of the pixel, in the form 0x00AA00GG + // +1 for the last pixel to interpolate with, and +1 for rounding errors. quint32 intermediate_buffer[2][buffer_size + 2]; // count is the size used in the intermediate_buffer. - int count = qCeil(length * data->m11) + 2; //+1 for the last pixel to interpolate with, and +1 for rounding errors. + int count = (qint64(length) * fdx + fixed_scale - 1) / fixed_scale + 2; Q_ASSERT(count <= buffer_size + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case int f = 0; int lim = count; @@ -2448,12 +2449,13 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper // The idea is first to do the interpolation between the row s1 and the row s2 // into an intermediate buffer, then we interpolate between two pixel of this buffer. FetchPixelsFunc fetch = qFetchPixels[layout->bpp]; + // +1 for the last pixel to interpolate with, and +1 for rounding errors. uint buf1[buffer_size + 2]; uint buf2[buffer_size + 2]; const uint *ptr1; const uint *ptr2; - int count = qCeil(length * data->m11) + 2; //+1 for the last pixel to interpolate with, and +1 for rounding errors. + int count = (qint64(length) * fdx + fixed_scale - 1) / fixed_scale + 2; Q_ASSERT(count <= buffer_size + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case if (blendType == BlendTransformedBilinearTiled) { @@ -3431,13 +3433,13 @@ static SourceFetchProc64 sourceFetch64[NBlendTypes][QImage::NImageFormats] = { static uint qt_gradient_pixel_fixed(const QGradientData *data, int fixed_pos) { int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS; - return data->colorTable[qt_gradient_clamp(data, ipos)].toArgb32(); + return data->colorTable32[qt_gradient_clamp(data, ipos)]; } static const QRgba64& qt_gradient_pixel64_fixed(const QGradientData *data, int fixed_pos) { int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS; - return data->colorTable[qt_gradient_clamp(data, ipos)]; + return data->colorTable64[qt_gradient_clamp(data, ipos)]; } static void QT_FASTCALL getLinearGradientValues(LinearGradientValues *v, const QSpanData *data) diff --git a/src/gui/painting/qdrawhelper_mips_dsp.cpp b/src/gui/painting/qdrawhelper_mips_dsp.cpp index 721b228395..c28b594de3 100644 --- a/src/gui/painting/qdrawhelper_mips_dsp.cpp +++ b/src/gui/painting/qdrawhelper_mips_dsp.cpp @@ -489,7 +489,7 @@ void QT_FASTCALL comp_func_SourceOut_mips_dsp(uint *dest, const uint *src, int l const uint * QT_FASTCALL qt_fetchUntransformed_888_mips_dsp (uint *buffer, const Operator *, const QSpanData *data, int y, int x, int length) { - uchar *line = (uchar *)data->texture.scanLine(y) + x; + const uchar *line = data->texture.scanLine(y) + x * 3; fetchUntransformed_888_asm_mips_dsp(buffer, line, length); return buffer; } @@ -497,7 +497,7 @@ const uint * QT_FASTCALL qt_fetchUntransformed_888_mips_dsp (uint *buffer, const const uint * QT_FASTCALL qt_fetchUntransformed_444_mips_dsp (uint *buffer, const Operator *, const QSpanData *data, int y, int x, int length) { - uchar *line = (uchar *)data->texture.scanLine(y) + x; + const uchar *line = data->texture.scanLine(y) + x * 2; fetchUntransformed_444_asm_mips_dsp(buffer, line, length); return buffer; } @@ -505,7 +505,7 @@ const uint * QT_FASTCALL qt_fetchUntransformed_444_mips_dsp (uint *buffer, const const uint * QT_FASTCALL qt_fetchUntransformed_argb8565_premultiplied_mips_dsp (uint *buffer, const Operator *, const QSpanData *data, int y, int x, int length) { - uchar *line = (uchar *)data->texture.scanLine(y) + x; + const uchar *line = data->texture.scanLine(y) + x * 3; fetchUntransformed_argb8565_premultiplied_asm_mips_dsp(buffer, line, length); return buffer; } diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 1ff19f4e04..ff98d186c5 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -268,7 +268,8 @@ struct QGradientData #define GRADIENT_STOPTABLE_SIZE 1024 #define GRADIENT_STOPTABLE_SIZE_SHIFT 10 - QRgba64* colorTable; //[GRADIENT_STOPTABLE_SIZE]; + const QRgba64 *colorTable64; //[GRADIENT_STOPTABLE_SIZE]; + const QRgb *colorTable32; //[GRADIENT_STOPTABLE_SIZE]; uint alphaColor : 1; }; @@ -376,13 +377,13 @@ static inline uint qt_gradient_clamp(const QGradientData *data, int ipos) static inline uint qt_gradient_pixel(const QGradientData *data, qreal pos) { int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5)); - return data->colorTable[qt_gradient_clamp(data, ipos)].toArgb32(); + return data->colorTable32[qt_gradient_clamp(data, ipos)]; } static inline const QRgba64& qt_gradient_pixel64(const QGradientData *data, qreal pos) { int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5)); - return data->colorTable[qt_gradient_clamp(data, ipos)]; + return data->colorTable64[qt_gradient_clamp(data, ipos)]; } static inline qreal qRadialDeterminant(qreal a, qreal b, qreal c) @@ -550,7 +551,7 @@ public: delta_det4_vec.v = Simd::v_add(delta_det4_vec.v, v_delta_delta_det16); \ b_vec.v = Simd::v_add(b_vec.v, v_delta_b4); \ for (int i = 0; i < 4; ++i) \ - *buffer++ = (extended_mask | v_buffer_mask.i[i]) & data->gradient.colorTable[index_vec.i[i]].toArgb32(); \ + *buffer++ = (extended_mask | v_buffer_mask.i[i]) & data->gradient.colorTable32[index_vec.i[i]]; \ } #define FETCH_RADIAL_LOOP(FETCH_RADIAL_LOOP_CLAMP) \ diff --git a/src/gui/painting/qpagelayout.cpp b/src/gui/painting/qpagelayout.cpp index f443bbd5ac..15dfa6f8c1 100644 --- a/src/gui/painting/qpagelayout.cpp +++ b/src/gui/painting/qpagelayout.cpp @@ -943,40 +943,37 @@ QRect QPageLayout::paintRectPixels(int resolution) const QDebug operator<<(QDebug dbg, const QPageLayout &layout) { QDebugStateSaver saver(dbg); + dbg.nospace(); + dbg.noquote(); + dbg << "QPageLayout("; if (layout.isValid()) { - QString output = QStringLiteral("QPageLayout(%1, %2, l:%3 r:%4 t:%5 b:%6 %7)"); - QString units; + const QMarginsF margins = layout.margins(); + dbg << '"' << layout.pageSize().name() << "\", " + << (layout.orientation() == QPageLayout::Portrait ? "Portrait" : "Landscape") + << ", l:" << margins.left() << " r:" << margins.right() << " t:" + << margins.top() << " b:" << margins.bottom() << ' '; switch (layout.units()) { case QPageLayout::Millimeter: - units = QStringLiteral("mm"); + dbg << "mm"; break; case QPageLayout::Point: - units = QStringLiteral("pt"); + dbg << "pt"; break; case QPageLayout::Inch: - units = QStringLiteral("in"); + dbg << "in"; break; case QPageLayout::Pica: - units = QStringLiteral("pc"); + dbg << "pc"; break; case QPageLayout::Didot: - units = QStringLiteral("DD"); + dbg << "DD"; break; case QPageLayout::Cicero: - units = QStringLiteral("CC"); + dbg << "CC"; break; } - output = output.arg(layout.pageSize().name()) - .arg(layout.orientation() == QPageLayout::Portrait ? QStringLiteral("Portrait") : QStringLiteral("Landscape")) - .arg(layout.margins().left()) - .arg(layout.margins().right()) - .arg(layout.margins().top()) - .arg(layout.margins().bottom()) - .arg(units); - dbg.nospace() << output; - } else { - dbg.nospace() << "QPageLayout()"; } + dbg << ')'; return dbg; } #endif diff --git a/src/gui/painting/qpagesize.cpp b/src/gui/painting/qpagesize.cpp index c0aae603b7..17f6b7bb64 100644 --- a/src/gui/painting/qpagesize.cpp +++ b/src/gui/painting/qpagesize.cpp @@ -1855,17 +1855,17 @@ QSize QPageSize::sizePixels(PageSizeId pageSizeId, int resolution) QDebug operator<<(QDebug dbg, const QPageSize &pageSize) { QDebugStateSaver saver(dbg); + dbg.nospace(); + dbg.noquote(); + dbg << "QPageSize("; if (pageSize.isValid()) { - QString output = QStringLiteral("QPageSize(\"%1\", \"%2\", %3x%4pt, %5)"); - output = output.arg(pageSize.name()) - .arg(pageSize.key()) - .arg(pageSize.sizePoints().width()) - .arg(pageSize.sizePoints().height()) - .arg(pageSize.id()); - dbg.nospace() << output; + dbg << '"' << pageSize.name() << "\", key=\"" << pageSize.key() + << "\", " << pageSize.sizePoints().width() << 'x' + << pageSize.sizePoints().height() << "pt, id=" << pageSize.id(); } else { dbg.nospace() << "QPageSize()"; } + dbg << ')'; return dbg; } #endif diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 05ccff5de0..f70bef72d8 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -683,6 +683,7 @@ void QRasterPaintEngine::penChanged() qDebug() << "QRasterPaintEngine::penChanged():" << state()->pen; #endif QRasterPaintEngineState *s = state(); + Q_ASSERT(s); s->strokeFlags |= DirtyPen; s->dirty |= DirtyPen; } @@ -2194,6 +2195,7 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); + Q_ASSERT(s); int sr_l = qFloor(sr.left()); int sr_r = qCeil(sr.right()) - 1; int sr_t = qFloor(sr.top()); @@ -2431,6 +2433,7 @@ void QRasterPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, #endif Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); + Q_ASSERT(s); QImage image; @@ -3610,7 +3613,7 @@ QImage QRasterBuffer::colorizeBitmap(const QImage &image, const QColor &color) { Q_ASSERT(image.depth() == 1); - QImage sourceImage = image.convertToFormat(QImage::Format_MonoLSB); + const QImage sourceImage = image.convertToFormat(QImage::Format_MonoLSB); QImage dest = QImage(sourceImage.size(), QImage::Format_ARGB32_Premultiplied); QRgb fg = qPremultiply(color.rgba()); @@ -3619,7 +3622,7 @@ QImage QRasterBuffer::colorizeBitmap(const QImage &image, const QColor &color) int height = sourceImage.height(); int width = sourceImage.width(); for (int y=0; y<height; ++y) { - uchar *source = sourceImage.scanLine(y); + const uchar *source = sourceImage.constScanLine(y); QRgb *target = reinterpret_cast<QRgb *>(dest.scanLine(y)); if (!source || !target) QT_THROW(std::bad_alloc()); // we must have run out of memory @@ -4138,7 +4141,8 @@ class QGradientCache { inline CacheInfo(QGradientStops s, int op, QGradient::InterpolationMode mode) : stops(qMove(s)), opacity(op), interpolationMode(mode) {} - QRgba64 buffer[GRADIENT_STOPTABLE_SIZE]; + QRgba64 buffer64[GRADIENT_STOPTABLE_SIZE]; + QRgb buffer32[GRADIENT_STOPTABLE_SIZE]; QGradientStops stops; int opacity; QGradient::InterpolationMode interpolationMode; @@ -4147,7 +4151,9 @@ class QGradientCache typedef QMultiHash<quint64, CacheInfo> QGradientColorTableHash; public: - inline const QRgba64 *getBuffer(const QGradient &gradient, int opacity) { + typedef QPair<const QRgb *, const QRgba64 *> ColorBufferPair; + + inline ColorBufferPair getBuffer(const QGradient &gradient, int opacity) { quint64 hash_val = 0; const QGradientStops stops = gradient.stops(); @@ -4163,7 +4169,8 @@ public: do { const CacheInfo &cache_info = it.value(); if (cache_info.stops == stops && cache_info.opacity == opacity && cache_info.interpolationMode == gradient.interpolationMode()) - return cache_info.buffer; + return qMakePair(reinterpret_cast<const QRgb *>(cache_info.buffer32), + reinterpret_cast<const QRgba64 *>(cache_info.buffer64)); ++it; } while (it != cache.constEnd() && it.key() == hash_val); // an exact match for these stops and opacity was not found, create new cache @@ -4177,14 +4184,18 @@ protected: inline void generateGradientColorTable(const QGradient& g, QRgba64 *colorTable, int size, int opacity) const; - QRgba64 *addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) { + ColorBufferPair addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) { if (cache.size() == maxCacheSize()) { // may remove more than 1, but OK cache.erase(cache.begin() + (qrand() % maxCacheSize())); } CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode()); - generateGradientColorTable(gradient, cache_entry.buffer, paletteSize(), opacity); - return cache.insert(hash_val, cache_entry).value().buffer; + generateGradientColorTable(gradient, cache_entry.buffer64, paletteSize(), opacity); + for (int i = 0; i < GRADIENT_STOPTABLE_SIZE; ++i) + cache_entry.buffer32[i] = cache_entry.buffer64[i].toArgb32(); + CacheInfo &cache_value = cache.insert(hash_val, cache_entry).value(); + return qMakePair(reinterpret_cast<const QRgb *>(cache_value.buffer32), + reinterpret_cast<const QRgba64 *>(cache_value.buffer64)); } QGradientColorTableHash cache; @@ -4418,7 +4429,11 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode type = LinearGradient; const QLinearGradient *g = static_cast<const QLinearGradient *>(brush.gradient()); gradient.alphaColor = !brush.isOpaque() || alpha != 256; - gradient.colorTable = const_cast<QRgba64*>(qt_gradient_cache()->getBuffer(*g, alpha)); + + QGradientCache::ColorBufferPair colorBuffers = qt_gradient_cache()->getBuffer(*g, alpha); + gradient.colorTable64 = colorBuffers.second; + gradient.colorTable32 = colorBuffers.first; + gradient.spread = g->spread(); QLinearGradientData &linearData = gradient.linear; @@ -4435,7 +4450,11 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode type = RadialGradient; const QRadialGradient *g = static_cast<const QRadialGradient *>(brush.gradient()); gradient.alphaColor = !brush.isOpaque() || alpha != 256; - gradient.colorTable = const_cast<QRgba64*>(qt_gradient_cache()->getBuffer(*g, alpha)); + + QGradientCache::ColorBufferPair colorBuffers = qt_gradient_cache()->getBuffer(*g, alpha); + gradient.colorTable64 = colorBuffers.second; + gradient.colorTable32 = colorBuffers.first; + gradient.spread = g->spread(); QRadialGradientData &radialData = gradient.radial; @@ -4456,7 +4475,11 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode type = ConicalGradient; const QConicalGradient *g = static_cast<const QConicalGradient *>(brush.gradient()); gradient.alphaColor = !brush.isOpaque() || alpha != 256; - gradient.colorTable = const_cast<QRgba64*>(qt_gradient_cache()->getBuffer(*g, alpha)); + + QGradientCache::ColorBufferPair colorBuffers = qt_gradient_cache()->getBuffer(*g, alpha); + gradient.colorTable64 = colorBuffers.second; + gradient.colorTable32 = colorBuffers.first; + gradient.spread = QGradient::RepeatSpread; QConicalGradientData &conicalData = gradient.conical; diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp index 3a686bd209..a5557c99ff 100644 --- a/src/gui/painting/qpathclipper.cpp +++ b/src/gui/painting/qpathclipper.cpp @@ -252,8 +252,6 @@ class SegmentTree public: SegmentTree(QPathSegments &segments); - QRectF boundingRect() const; - void produceIntersections(int segment); private: @@ -304,12 +302,6 @@ SegmentTree::SegmentTree(QPathSegments &segments) m_tree[0] = root; } -QRectF SegmentTree::boundingRect() const -{ - return QRectF(QPointF(m_bounds.x1, m_bounds.y1), - QPointF(m_bounds.x2, m_bounds.y2)); -} - static inline qreal coordinate(const QPointF &pos, int axis) { return axis == 0 ? pos.x() : pos.y(); diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index d746ab9379..d68d719c39 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1003,7 +1003,8 @@ void QPdfEngine::drawHyperlink(const QRectF &r, const QUrl &url) const uint annot = d->addXrefEntry(-1); const QByteArray urlascii = url.toEncoded(); int len = urlascii.size(); - QVarLengthArray<char> url_esc(0); + QVarLengthArray<char> url_esc; + url_esc.reserve(len + 1); for (int j = 0; j < len; j++) { if (urlascii[j] == '(' || urlascii[j] == ')' || urlascii[j] == '\\') url_esc.append('\\'); @@ -2007,10 +2008,11 @@ int QPdfEnginePrivate::createShadingFunction(const QGradient *gradient, int from } QVector<QGradientBound> gradientBounds; + gradientBounds.reserve((to - from) * (numStops - 1)); for (int step = from; step < to; ++step) { if (reflect && step % 2) { - for (int i = stops.size() - 1; i > 0; --i) { + for (int i = numStops - 1; i > 0; --i) { QGradientBound b; b.start = step + 1 - qBound(qreal(0.), stops.at(i).first, qreal(1.)); b.stop = step + 1 - qBound(qreal(0.), stops.at(i - 1).first, qreal(1.)); @@ -2019,7 +2021,7 @@ int QPdfEnginePrivate::createShadingFunction(const QGradient *gradient, int from gradientBounds << b; } } else { - for (int i = 0; i < stops.size() - 1; ++i) { + for (int i = 0; i < numStops - 1; ++i) { QGradientBound b; b.start = step + qBound(qreal(0.), stops.at(i).first, qreal(1.)); b.stop = step + qBound(qreal(0.), stops.at(i + 1).first, qreal(1.)); diff --git a/src/gui/painting/qpen.h b/src/gui/painting/qpen.h index 6ce50ae1d0..bfa1553c68 100644 --- a/src/gui/painting/qpen.h +++ b/src/gui/painting/qpen.h @@ -65,7 +65,7 @@ public: QPen &operator=(const QPen &pen) Q_DECL_NOTHROW; #ifdef Q_COMPILER_RVALUE_REFS QPen(QPen &&other) Q_DECL_NOTHROW - : d(other.d) { other.d = 0; } + : d(other.d) { other.d = Q_NULLPTR; } QPen &operator=(QPen &&other) Q_DECL_NOTHROW { qSwap(d, other.d); return *this; } #endif diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp index 5e648eabf5..757c78cec8 100644 --- a/src/gui/painting/qregion.cpp +++ b/src/gui/painting/qregion.cpp @@ -3735,7 +3735,7 @@ static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule) QRegionPrivate *qt_bitmapToRegion(const QBitmap& bitmap) { - QImage image = bitmap.toImage(); + const QImage image = bitmap.toImage(); QRegionPrivate *region = new QRegionPrivate; @@ -3753,7 +3753,7 @@ QRegionPrivate *qt_bitmapToRegion(const QBitmap& bitmap) int x, y; for (y = 0; y < image.height(); ++y) { - uchar *line = image.scanLine(y); + const uchar *line = image.constScanLine(y); int w = image.width(); uchar all = zero; int prev1 = -1; diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 97f82d16d3..20039d902a 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -339,7 +339,7 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subP uchar *dest = d + (c.y + y) *dbpl + c.x/8; if (y < mh) { - uchar *src = mask.scanLine(y); + const uchar *src = mask.constScanLine(y); for (int x = 0; x < c.w/8; ++x) { if (x < (mw+7)/8) dest[x] = src[x]; @@ -361,7 +361,7 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subP for (int y = 0; y < c.h; ++y) { uchar *dest = d + (c.y + y) *dbpl + c.x; if (y < mh) { - uchar *src = (uchar *) mask.scanLine(y); + const uchar *src = mask.constScanLine(y); for (int x = 0; x < c.w; ++x) { if (x < mw) dest[x] = (src[x >> 3] & (1 << (7 - (x & 7)))) > 0 ? 255 : 0; @@ -372,7 +372,7 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subP for (int y = 0; y < c.h; ++y) { uchar *dest = d + (c.y + y) *dbpl + c.x; if (y < mh) { - uchar *src = (uchar *) mask.scanLine(y); + const uchar *src = mask.constScanLine(y); for (int x = 0; x < c.w; ++x) { if (x < mw) dest[x] = src[x]; diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 2c5a0c74fc..fe68149346 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -131,7 +131,7 @@ extern bool qt_is_gui_used; Q_GUI_EXPORT int qt_defaultDpiX() { - if (qApp->testAttribute(Qt::AA_Use96Dpi)) + if (QCoreApplication::instance()->testAttribute(Qt::AA_Use96Dpi)) return 96; if (!qt_is_gui_used) @@ -146,7 +146,7 @@ Q_GUI_EXPORT int qt_defaultDpiX() Q_GUI_EXPORT int qt_defaultDpiY() { - if (qApp->testAttribute(Qt::AA_Use96Dpi)) + if (QCoreApplication::instance()->testAttribute(Qt::AA_Use96Dpi)) return 96; if (!qt_is_gui_used) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index d606681e52..928d1e4eb5 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -691,7 +691,9 @@ static QStringList familyList(const QFontDef &req) return family_list; QStringList list = req.family.split(QLatin1Char(',')); - for (int i = 0; i < list.size(); ++i) { + const int numFamilies = list.size(); + family_list.reserve(numFamilies); + for (int i = 0; i < numFamilies; ++i) { QString str = list.at(i).trimmed(); if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"'))) || (str.startsWith(QLatin1Char('\'')) && str.endsWith(QLatin1Char('\'')))) @@ -1607,6 +1609,7 @@ QStringList QFontDatabase::styles(const QString &family) const } } + l.reserve(allStyles.count); for (int i = 0; i < allStyles.count; i++) { l.append(allStyles.styles[i]->styleName.isEmpty() ? styleStringHelper(allStyles.styles[i]->key.weight, diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index fc66c4ec4c..03ad6a24e9 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -823,7 +823,7 @@ void QFontEngine::addBitmapFontToPath(qreal x, qreal y, const QGlyphLayout &glyp } } } - const uchar *bitmap_data = bitmap.bits(); + const uchar *bitmap_data = bitmap.constBits(); QFixedPoint offset = glyphs.offsets[i]; advanceX += offset.x; advanceY += offset.y; @@ -880,12 +880,12 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, con QImage QFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed /*subPixelPosition*/, const QTransform &t) { - QImage alphaMask = alphaMapForGlyph(glyph, t); + const QImage alphaMask = alphaMapForGlyph(glyph, t); QImage rgbMask(alphaMask.width(), alphaMask.height(), QImage::Format_RGB32); for (int y=0; y<alphaMask.height(); ++y) { uint *dst = (uint *) rgbMask.scanLine(y); - uchar *src = (uchar *) alphaMask.scanLine(y); + const uchar *src = alphaMask.constScanLine(y); for (int x=0; x<alphaMask.width(); ++x) { int val = src[x]; dst[x] = qRgb(val, val, val); @@ -973,7 +973,7 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph) for (int y=0; y<im.height(); ++y) { uchar *dst = (uchar *) alphaMap.scanLine(y); - uint *src = (uint *) im.scanLine(y); + const uint *src = reinterpret_cast<const uint *>(im.constScanLine(y)); for (int x=0; x<im.width(); ++x) dst[x] = qAlpha(src[x]); } diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index de5bec6f93..8fbeff3596 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1073,8 +1073,8 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, if (glyph_buffer_size < pitch * info.height) { glyph_buffer_size = pitch * info.height; glyph_buffer.reset(new uchar[glyph_buffer_size]); + memset(glyph_buffer.data(), 0, glyph_buffer_size); } - memset(glyph_buffer.data(), 0, glyph_buffer_size); if (slot->format == FT_GLYPH_FORMAT_OUTLINE) { FT_Bitmap bitmap; @@ -1719,8 +1719,8 @@ static inline QImage alphaMapFromGlyphData(QFontEngineFT::Glyph *glyph, QFontEng if (glyph == Q_NULLPTR) return QImage(); - QImage::Format format; - int bytesPerLine; + QImage::Format format = QImage::Format_Invalid; + int bytesPerLine = -1; switch (glyphFormat) { case QFontEngine::Format_Mono: format = QImage::Format_Mono; diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 5bc9fe3c7f..32e40b9f4d 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -789,7 +789,7 @@ QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &te \li Qt::TextSingleLine ignores newline characters. \li Qt::TextExpandTabs expands tabs (see below) \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined. - \li Qt::TextWordBreak breaks the text to fit the rectangle. + \li Qt::TextWordWrap breaks the text to fit the rectangle. \endlist If Qt::TextExpandTabs is set in \a flags, then: if \a tabArray is @@ -1573,7 +1573,7 @@ QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString& \li Qt::TextSingleLine ignores newline characters. \li Qt::TextExpandTabs expands tabs (see below) \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined. - \li Qt::TextWordBreak breaks the text to fit the rectangle. + \li Qt::TextWordWrap breaks the text to fit the rectangle. \endlist These flags are defined in the \l{Qt::TextFlag} enum. diff --git a/src/gui/text/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp index dc32405f36..84819fd52e 100644 --- a/src/gui/text/qfontsubset.cpp +++ b/src/gui/text/qfontsubset.cpp @@ -1159,7 +1159,6 @@ QByteArray QFontSubset::toTruetype() const qreal ppem = fontEngine->fontDef.pixelSize; #define TO_TTF(x) qRound(x * 2048. / ppem) - QVector<QTtfGlyph> glyphs; QFontEngine::Properties properties = fontEngine->properties(); // initialize some stuff needed in createWidthArray @@ -1194,12 +1193,13 @@ QByteArray QFontSubset::toTruetype() const font.maxp.maxCompositeContours = 0; font.maxp.maxComponentElements = 0; font.maxp.maxComponentDepth = 0; - font.maxp.numGlyphs = nGlyphs(); - - + const int numGlyphs = nGlyphs(); + font.maxp.numGlyphs = numGlyphs; + QVector<QTtfGlyph> glyphs; + glyphs.reserve(numGlyphs); uint sumAdvances = 0; - for (int i = 0; i < nGlyphs(); ++i) { + for (int i = 0; i < numGlyphs; ++i) { glyph_t g = glyph_indices.at(i); QPainterPath path; glyph_metrics_t metric; diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 0fd5f510c7..59f13581dd 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -607,8 +607,7 @@ QByteArray QRawFont::fontTable(const char *tagName) const if (!d->isValid()) return QByteArray(); - const quint32 *tagId = reinterpret_cast<const quint32 *>(tagName); - return d->fontEngine->getSfntTable(qToBigEndian(*tagId)); + return d->fontEngine->getSfntTable(MAKE_TAG(tagName[0], tagName[1], tagName[2], tagName[3])); } /*! diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 1c924175e2..d0c2779a65 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1059,7 +1059,7 @@ void QTextEngine::shapeText(int item) const #ifdef QT_ENABLE_HARFBUZZ_NG if (Q_LIKELY(qt_useHarfbuzzNG())) - si.num_glyphs = shapeTextWithHarfbuzzNG(si, string, itemLength, fontEngine, itemBoundaries, kerningEnabled); + si.num_glyphs = shapeTextWithHarfbuzzNG(si, string, itemLength, fontEngine, itemBoundaries, kerningEnabled, letterSpacing != 0); else #endif si.num_glyphs = shapeTextWithHarfbuzz(si, string, itemLength, fontEngine, itemBoundaries, kerningEnabled); @@ -1121,7 +1121,13 @@ QT_BEGIN_INCLUDE_NAMESPACE QT_END_INCLUDE_NAMESPACE -int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const +int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, + const ushort *string, + int itemLength, + QFontEngine *fontEngine, + const QVector<uint> &itemBoundaries, + bool kerningEnabled, + bool hasLetterSpacing) const { uint glyphs_shaped = 0; @@ -1135,7 +1141,8 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st hb_segment_properties_t props = HB_SEGMENT_PROPERTIES_DEFAULT; props.direction = si.analysis.bidiLevel % 2 ? HB_DIRECTION_RTL : HB_DIRECTION_LTR; - props.script = hb_qt_script_to_script(QChar::Script(si.analysis.script)); + QChar::Script script = QChar::Script(si.analysis.script); + props.script = hb_qt_script_to_script(script); // ### props.language = hb_language_get_default_for_script(props.script); for (int k = 0; k < itemBoundaries.size(); k += 3) { @@ -1168,10 +1175,19 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st Q_ASSERT(hb_font); hb_qt_font_set_use_design_metrics(hb_font, option.useDesignMetrics() ? uint(QFontEngine::DesignMetrics) : 0); // ### - const hb_feature_t features[1] = { - { HB_TAG('k','e','r','n'), !!kerningEnabled, 0, uint(-1) } - }; - const int num_features = 1; + // Ligatures are incompatible with custom letter spacing, so when a letter spacing is set, + // we disable them for writing systems where they are purely cosmetic. + bool scriptRequiresOpenType = ((script >= QChar::Script_Syriac && script <= QChar::Script_Sinhala) + || script == QChar::Script_Khmer || script == QChar::Script_Nko); + + bool dontLigate = hasLetterSpacing && !scriptRequiresOpenType; + const hb_feature_t features[5] = { + { HB_TAG('k','e','r','n'), !!kerningEnabled, 0, uint(-1) }, + { HB_TAG('l','i','g','a'), !dontLigate, 0, uint(-1) }, + { HB_TAG('c','l','i','g'), !dontLigate, 0, uint(-1) }, + { HB_TAG('d','l','i','g'), !dontLigate, 0, uint(-1) }, + { HB_TAG('h','l','i','g'), !dontLigate, 0, uint(-1) } }; + const int num_features = dontLigate ? 5 : 1; const char *const *shaper_list = Q_NULLPTR; #if defined(Q_OS_DARWIN) @@ -2731,8 +2747,7 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int QFixed ellipsisWidth; QString ellipsisText; { - QFontEngine *fe = fnt.d->engineForScript(QChar::Script_Common); - QFontEngine *engine = fe->type() == QFontEngine::Multi ? static_cast<QFontEngineMulti *>(fe)->engine(0) : fe; + QFontEngine *engine = fnt.d->engineForScript(QChar::Script_Common); QChar ellipsisChar(0x2026); diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 39c228fd52..7e507bba2d 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -643,7 +643,13 @@ private: void addRequiredBoundaries() const; void shapeText(int item) const; #ifdef QT_ENABLE_HARFBUZZ_NG - int shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const; + int shapeTextWithHarfbuzzNG(const QScriptItem &si, + const ushort *string, + int itemLength, + QFontEngine *fontEngine, + const QVector<uint> &itemBoundaries, + bool kerningEnabled, + bool hasLetterSpacing) const; #endif int shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const; diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index f8f41bb53d..77da01be3f 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -1926,13 +1926,7 @@ QVector<QCss::Declaration> standardDeclarationForNode(const QTextHtmlParserNode decl.d->propertyId = QCss::FontFamily; QVector<QCss::Value> values; val.type = QCss::Value::String; - val.variant = QLatin1String("Courier New"); - values << val; - val.type = QCss::Value::TermOperatorComma; - val.variant = QVariant(); - values << val; - val.type = QCss::Value::String; - val.variant = QLatin1String("courier"); + val.variant = QFontDatabase::systemFont(QFontDatabase::FixedFont).family(); values << val; decl.d->values = values; decl.d->inheritable = true; diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 9e2a23a7f7..bc9c452ff7 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2141,6 +2141,7 @@ static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine, QGlyphRunPrivate *d = QGlyphRunPrivate::get(glyphRun); int rangeStart = textPosition; + logClusters += textPosition; while (*logClusters != glyphsStart && rangeStart < textPosition + textLength) { ++logClusters; ++rangeStart; @@ -2325,16 +2326,16 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const if (mainFontEngine->type() == QFontEngine::Multi) { QFontEngineMulti *multiFontEngine = static_cast<QFontEngineMulti *>(mainFontEngine); - int end = rtl ? glyphLayout.numGlyphs : 0; - int start = rtl ? end : 0; - int which = glyphLayout.glyphs[rtl ? start - 1 : end] >> 24; - for (; (rtl && start > 0) || (!rtl && end < glyphLayout.numGlyphs); + int start = rtl ? glyphLayout.numGlyphs : 0; + int end = start - 1; + int which = glyphLayout.glyphs[rtl ? start - 1 : end + 1] >> 24; + for (; (rtl && start > 0) || (!rtl && end < glyphLayout.numGlyphs - 1); rtl ? --start : ++end) { - const int e = glyphLayout.glyphs[rtl ? start - 1 : end] >> 24; + const int e = glyphLayout.glyphs[rtl ? start - 1 : end + 1] >> 24; if (e == which) continue; - QGlyphLayout subLayout = glyphLayout.mid(start, end - start); + QGlyphLayout subLayout = glyphLayout.mid(start, end - start + 1); multiFontEngine->ensureEngineAt(which); QGlyphRun::GlyphRunFlags subFlags = flags; @@ -2358,13 +2359,13 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const } if (rtl) - end = start; + end = start - 1; else - start = end; + start = end + 1; which = e; } - QGlyphLayout subLayout = glyphLayout.mid(start, end - start); + QGlyphLayout subLayout = glyphLayout.mid(start, end - start + 1); multiFontEngine->ensureEngineAt(which); QGlyphRun::GlyphRunFlags subFlags = flags; diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index a0f05523e3..f1b0a844c8 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -554,9 +554,8 @@ qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket) if (c == '\n') { // check for possible header endings. As per HTTP rfc, // the header endings will be marked by CRLFCRLF. But - // we will allow CRLFCRLF, CRLFLF, LFLF - if (fragment.endsWith("\r\n\r\n") - || fragment.endsWith("\r\n\n") + // we will allow CRLFCRLF, CRLFLF, LFCRLF, LFLF + if (fragment.endsWith("\n\r\n") || fragment.endsWith("\n\n")) allHeaders = true; diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index e8ed73fdac..4e09fd9110 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -175,7 +175,7 @@ private: }; -class QHttpNetworkReplyPrivate : public QObjectPrivate, public QHttpNetworkHeaderPrivate +class Q_AUTOTEST_EXPORT QHttpNetworkReplyPrivate : public QObjectPrivate, public QHttpNetworkHeaderPrivate { public: QHttpNetworkReplyPrivate(const QUrl &newUrl = QUrl()); diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp index b0e366d2f8..c9700e972a 100644 --- a/src/network/access/qhttpthreaddelegate.cpp +++ b/src/network/access/qhttpthreaddelegate.cpp @@ -122,7 +122,7 @@ static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy) { QString result; QUrl copy = url; - QString scheme = copy.scheme().toLower(); + QString scheme = copy.scheme(); bool isEncrypted = scheme == QLatin1String("https"); copy.setPort(copy.port(isEncrypted ? 443 : 80)); if (scheme == QLatin1String("preconnect-http")) { diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 0e5870a235..28553e19e6 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -1119,42 +1119,40 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera Q_D(QNetworkAccessManager); bool isLocalFile = req.url().isLocalFile(); - QString scheme = req.url().scheme().toLower(); + QString scheme = req.url().scheme(); // fast path for GET on file:// URLs // The QNetworkAccessFileBackend will right now only be used for PUT - if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation) - && (isLocalFile || scheme == QLatin1String("qrc") -#if defined(Q_OS_ANDROID) + if (op == QNetworkAccessManager::GetOperation + || op == QNetworkAccessManager::HeadOperation) { + if (isLocalFile +#ifdef Q_OS_ANDROID || scheme == QLatin1String("assets") #endif - )) { - return new QNetworkReplyFileImpl(this, req, op); - } + || scheme == QLatin1String("qrc")) { + return new QNetworkReplyFileImpl(this, req, op); + } - if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation) - && scheme == QLatin1String("data")) { - return new QNetworkReplyDataImpl(this, req, op); - } + if (scheme == QLatin1String("data")) + return new QNetworkReplyDataImpl(this, req, op); - // A request with QNetworkRequest::AlwaysCache does not need any bearer management - QNetworkRequest::CacheLoadControl mode = - static_cast<QNetworkRequest::CacheLoadControl>( - req.attribute(QNetworkRequest::CacheLoadControlAttribute, + // A request with QNetworkRequest::AlwaysCache does not need any bearer management + QNetworkRequest::CacheLoadControl mode = + static_cast<QNetworkRequest::CacheLoadControl>( + req.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt()); - if (mode == QNetworkRequest::AlwaysCache - && (op == QNetworkAccessManager::GetOperation - || op == QNetworkAccessManager::HeadOperation)) { - // FIXME Implement a QNetworkReplyCacheImpl instead, see QTBUG-15106 - QNetworkReplyImpl *reply = new QNetworkReplyImpl(this); - QNetworkReplyImplPrivate *priv = reply->d_func(); - priv->manager = this; - priv->backend = new QNetworkAccessCacheBackend(); - priv->backend->manager = this->d_func(); - priv->backend->setParent(reply); - priv->backend->reply = priv; - priv->setup(op, req, outgoingData); - return reply; + if (mode == QNetworkRequest::AlwaysCache) { + // FIXME Implement a QNetworkReplyCacheImpl instead, see QTBUG-15106 + QNetworkReplyImpl *reply = new QNetworkReplyImpl(this); + QNetworkReplyImplPrivate *priv = reply->d_func(); + priv->manager = this; + priv->backend = new QNetworkAccessCacheBackend(); + priv->backend->manager = this->d_func(); + priv->backend->setParent(reply); + priv->backend->reply = priv; + priv->setup(op, req, outgoingData); + return reply; + } } #ifndef QT_NO_BEARERMANAGEMENT diff --git a/src/network/access/qnetworkcookiejar.cpp b/src/network/access/qnetworkcookiejar.cpp index 39f94a451f..97e637ff5f 100644 --- a/src/network/access/qnetworkcookiejar.cpp +++ b/src/network/access/qnetworkcookiejar.cpp @@ -218,7 +218,7 @@ QList<QNetworkCookie> QNetworkCookieJar::cookiesForUrl(const QUrl &url) const Q_D(const QNetworkCookieJar); const QDateTime now = QDateTime::currentDateTimeUtc(); QList<QNetworkCookie> result; - bool isEncrypted = url.scheme().toLower() == QLatin1String("https"); + bool isEncrypted = url.scheme() == QLatin1String("https"); // scan our cookies for something that matches QList<QNetworkCookie>::ConstIterator it = d->allCookies.constBegin(), diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 04d391a14c..3120f29c03 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -628,7 +628,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq httpRequest.setUrl(url); httpRequest.setRedirectCount(newHttpRequest.maximumRedirectsAllowed()); - QString scheme = url.scheme().toLower(); + QString scheme = url.scheme(); bool ssl = (scheme == QLatin1String("https") || scheme == QLatin1String("preconnect-https")); q->setAttribute(QNetworkRequest::ConnectionEncryptedAttribute, ssl); @@ -676,18 +676,19 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq if (newHttpRequest.attribute(QNetworkRequest::FollowRedirectsAttribute).toBool()) httpRequest.setFollowRedirects(true); - bool loadedFromCache = false; httpRequest.setPriority(convert(newHttpRequest.priority())); switch (operation) { case QNetworkAccessManager::GetOperation: httpRequest.setOperation(QHttpNetworkRequest::Get); - loadedFromCache = loadFromCacheIfAllowed(httpRequest); + if (loadFromCacheIfAllowed(httpRequest)) + return; // no need to send the request! :) break; case QNetworkAccessManager::HeadOperation: httpRequest.setOperation(QHttpNetworkRequest::Head); - loadedFromCache = loadFromCacheIfAllowed(httpRequest); + if (loadFromCacheIfAllowed(httpRequest)) + return; // no need to send the request! :) break; case QNetworkAccessManager::PostOperation: @@ -719,10 +720,6 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq break; // can't happen } - if (loadedFromCache) { - return; // no need to send the request! :) - } - QList<QByteArray> headers = newHttpRequest.rawHeaderList(); if (resumeOffset != 0) { if (headers.contains("Range")) { @@ -750,10 +747,10 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq foreach (const QByteArray &header, headers) httpRequest.setHeaderField(header, newHttpRequest.rawHeader(header)); - if (newHttpRequest.attribute(QNetworkRequest::HttpPipeliningAllowedAttribute).toBool() == true) + if (newHttpRequest.attribute(QNetworkRequest::HttpPipeliningAllowedAttribute).toBool()) httpRequest.setPipeliningAllowed(true); - if (request.attribute(QNetworkRequest::SpdyAllowedAttribute).toBool() == true) + if (request.attribute(QNetworkRequest::SpdyAllowedAttribute).toBool()) httpRequest.setSPDYAllowed(true); if (static_cast<QNetworkRequest::LoadControl> @@ -761,7 +758,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Manual) httpRequest.setWithCredentials(false); - if (request.attribute(QNetworkRequest::EmitAllUploadProgressSignalsAttribute).toBool() == true) + if (request.attribute(QNetworkRequest::EmitAllUploadProgressSignalsAttribute).toBool()) emitAllUploadProgressSignals = true; @@ -1749,10 +1746,8 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation() QMetaObject::invokeMethod(q, "_q_finished", synchronous ? Qt::DirectConnection : Qt::QueuedConnection); return; } -#endif if (!start(request)) { -#ifndef QT_NO_BEARERMANAGEMENT // backend failed to start because the session state is not Connected. // QNetworkAccessManager will call reply->backend->start() again for us when the session // state changes. @@ -1774,29 +1769,25 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation() QMetaObject::invokeMethod(q, "_q_finished", synchronous ? Qt::DirectConnection : Qt::QueuedConnection); return; } + } else if (session) { + QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)), + q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), + Qt::QueuedConnection); + } #else + if (!start(request)) { qWarning("Backend start failed"); QMetaObject::invokeMethod(q, "_q_error", synchronous ? Qt::DirectConnection : Qt::QueuedConnection, Q_ARG(QNetworkReply::NetworkError, QNetworkReply::UnknownNetworkError), Q_ARG(QString, QCoreApplication::translate("QNetworkReply", "backend start error."))); QMetaObject::invokeMethod(q, "_q_finished", synchronous ? Qt::DirectConnection : Qt::QueuedConnection); return; -#endif - } else { -#ifndef QT_NO_BEARERMANAGEMENT - if (session) - QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)), - q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection); -#endif } +#endif // QT_NO_BEARERMANAGEMENT if (synchronous) { state = Finished; q_func()->setFinished(true); - } else { - if (state != Finished) { - - } } } diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 558e015ae4..f5010198f3 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -798,10 +798,10 @@ static QByteArray headerValue(QNetworkRequest::KnownHeaders header, const QVaria return QByteArray(); } -static QNetworkRequest::KnownHeaders parseHeaderName(const QByteArray &headerName) +static int parseHeaderName(const QByteArray &headerName) { if (headerName.isEmpty()) - return QNetworkRequest::KnownHeaders(-1); + return -1; switch (tolower(headerName.at(0))) { case 'c': @@ -833,7 +833,7 @@ static QNetworkRequest::KnownHeaders parseHeaderName(const QByteArray &headerNam break; } - return QNetworkRequest::KnownHeaders(-1); // nothing found + return -1; // nothing found } static QVariant parseHttpDate(const QByteArray &raw) @@ -1005,8 +1005,10 @@ void QNetworkHeadersPrivate::setRawHeaderInternal(const QByteArray &key, const Q void QNetworkHeadersPrivate::parseAndSetHeader(const QByteArray &key, const QByteArray &value) { // is it a known header? - QNetworkRequest::KnownHeaders parsedKey = parseHeaderName(key); - if (parsedKey != QNetworkRequest::KnownHeaders(-1)) { + const int parsedKeyAsInt = parseHeaderName(key); + if (parsedKeyAsInt != -1) { + const QNetworkRequest::KnownHeaders parsedKey + = static_cast<QNetworkRequest::KnownHeaders>(parsedKeyAsInt); if (value.isNull()) { cookedHeaders.remove(parsedKey); } else if (parsedKey == QNetworkRequest::ContentLengthHeader diff --git a/src/network/network.pro b/src/network/network.pro index 4cced923f7..cdea190222 100644 --- a/src/network/network.pro +++ b/src/network/network.pro @@ -11,13 +11,8 @@ DEFINES += QT_NO_USING_NAMESPACE #DEFINES += QUDPSOCKET_DEBUG QUDPSERVER_DEBUG win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x64000000 -MODULE_PLUGIN_TYPES = \ - bearer - QMAKE_DOCS = $$PWD/doc/qtnetwork.qdocconf -load(qt_module) - include(access/access.pri) include(bearer/bearer.pri) include(kernel/kernel.pri) @@ -36,3 +31,7 @@ MODULE_PLUGIN_TYPES = \ bearer ANDROID_PERMISSIONS += \ android.permission.ACCESS_NETWORK_STATE + +MODULE_PLUGIN_TYPES = \ + bearer +load(qt_module) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 385146bb95..e60c821da6 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -2149,8 +2149,10 @@ bool QAbstractSocket::waitForReadyRead(int msecs) return false; } - Q_ASSERT(d->socketEngine); do { + if (state() != ConnectedState) + return false; + bool readyToRead = false; bool readyToWrite = false; if (!d->socketEngine->waitForReadOrWrite(&readyToRead, &readyToWrite, true, !d->writeBuffer.isEmpty(), @@ -2172,9 +2174,6 @@ bool QAbstractSocket::waitForReadyRead(int msecs) if (readyToWrite) d->canWriteNotification(); - - if (state() != ConnectedState) - return false; } while (msecs == -1 || qt_subtract_from_timeout(msecs, stopWatch.elapsed()) > 0); return false; } diff --git a/src/network/socket/qlocalserver_win.cpp b/src/network/socket/qlocalserver_win.cpp index 265f894972..06ad62f548 100644 --- a/src/network/socket/qlocalserver_win.cpp +++ b/src/network/socket/qlocalserver_win.cpp @@ -192,6 +192,9 @@ bool QLocalServerPrivate::addListener() memset(&listener.overlapped, 0, sizeof(listener.overlapped)); listener.overlapped.hEvent = eventHandle; + + // Beware! ConnectNamedPipe will reset the eventHandle to non-signaled. + // Callers of addListener must check all listeners for connections. if (!ConnectNamedPipe(listener.handle, &listener.overlapped)) { switch (GetLastError()) { case ERROR_IO_PENDING: @@ -199,7 +202,6 @@ bool QLocalServerPrivate::addListener() break; case ERROR_PIPE_CONNECTED: listener.connected = true; - SetEvent(eventHandle); break; default: CloseHandle(listener.handle); @@ -251,6 +253,8 @@ bool QLocalServerPrivate::listen(const QString &name) for (int i = 0; i < SYSTEM_MAX_PENDING_SOCKETS; ++i) if (!addListener()) return false; + + _q_onNewConnection(); return true; } @@ -264,37 +268,43 @@ void QLocalServerPrivate::_q_onNewConnection() { Q_Q(QLocalServer); DWORD dummy; - - // Reset first, otherwise we could reset an event which was asserted - // immediately after we checked the conn status. - ResetEvent(eventHandle); - - // Testing shows that there is indeed absolutely no guarantee which listener gets - // a client connection first, so there is no way around polling all of them. - for (int i = 0; i < listeners.size(); ) { - HANDLE handle = listeners[i].handle; - if (listeners[i].connected - || GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE)) - { - listeners.removeAt(i); - - addListener(); - - if (pendingConnections.size() > maxPendingConnections) - connectionEventNotifier->setEnabled(false); - - // Make this the last thing so connected slots can wreak the least havoc - q->incomingConnection((quintptr)handle); - } else { - if (GetLastError() != ERROR_IO_INCOMPLETE) { - q->close(); - setError(QLatin1String("QLocalServerPrivate::_q_onNewConnection")); - return; + bool tryAgain; + do { + tryAgain = false; + + // Reset first, otherwise we could reset an event which was asserted + // immediately after we checked the conn status. + ResetEvent(eventHandle); + + // Testing shows that there is indeed absolutely no guarantee which listener gets + // a client connection first, so there is no way around polling all of them. + for (int i = 0; i < listeners.size(); ) { + HANDLE handle = listeners[i].handle; + if (listeners[i].connected + || GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE)) + { + listeners.removeAt(i); + + addListener(); + + if (pendingConnections.size() > maxPendingConnections) + connectionEventNotifier->setEnabled(false); + else + tryAgain = true; + + // Make this the last thing so connected slots can wreak the least havoc + q->incomingConnection((quintptr)handle); + } else { + if (GetLastError() != ERROR_IO_INCOMPLETE) { + q->close(); + setError(QLatin1String("QLocalServerPrivate::_q_onNewConnection")); + return; + } + + ++i; } - - ++i; } - } + } while (tryAgain); } void QLocalServerPrivate::closeServer() diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index ca0a8b95d5..7b6be9ebf9 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -294,19 +294,6 @@ static inline QAbstractSocket::SocketType qt_socket_getType(qintptr socketDescri return QAbstractSocket::UnknownSocketType; } -/*! \internal - -*/ -static inline int qt_socket_getMaxMsgSize(qintptr socketDescriptor) -{ - int value = 0; - QT_SOCKLEN_T valueSize = sizeof(value); - if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *) &value, &valueSize) != 0) { - WS_ERROR_DEBUG(WSAGetLastError()); - } - return value; -} - // MS Transport Provider IOCTL to control // reporting PORT_UNREACHABLE messages // on UDP sockets via recv/WSARecv/etc. diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index dd47dfc45f..8caa56ee5b 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -390,6 +390,10 @@ bool QSslSocketBackendPrivate::initSslContext() if (!ace.isEmpty() && !QHostAddress().setAddress(tlsHostName) && !(configuration.sslOptions & QSsl::SslOptionDisableServerNameIndication)) { + // We don't send the trailing dot from the host header if present see + // https://tools.ietf.org/html/rfc6066#section-3 + if (ace.endsWith('.')) + ace.chop(1); if (!q_SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, ace.data())) qCWarning(lcSsl, "could not set SSL_CTRL_SET_TLSEXT_HOSTNAME, Server Name Indication disabled"); } @@ -639,10 +643,12 @@ void QSslSocketPrivate::resetDefaultCiphers() // Unconditionally exclude ADH and AECDH ciphers since they offer no MITM protection if (!ciph.name().toLower().startsWith(QLatin1String("adh")) && !ciph.name().toLower().startsWith(QLatin1String("exp-adh")) && - !ciph.name().toLower().startsWith(QLatin1String("aecdh"))) + !ciph.name().toLower().startsWith(QLatin1String("aecdh"))) { ciphers << ciph; - if (ciph.usedBits() >= 128) - defaultCiphers << ciph; + + if (ciph.usedBits() >= 128) + defaultCiphers << ciph; + } } } } diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h index f27c8eb1f3..4085ae6b3f 100644 --- a/src/network/ssl/qsslsocket_openssl_p.h +++ b/src/network/ssl/qsslsocket_openssl_p.h @@ -131,7 +131,7 @@ public: unsigned int tlsPskClientCallback(const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len); #ifdef Q_OS_WIN void fetchCaRootForCert(const QSslCertificate &cert); - void _q_caRootLoaded(QSslCertificate,QSslCertificate); + void _q_caRootLoaded(QSslCertificate,QSslCertificate) Q_DECL_OVERRIDE; #endif Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions); diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 9c62d41d3e..007f73c45f 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -8,8 +8,6 @@ irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused QMAKE_DOCS = $$PWD/doc/qtopengl.qdocconf -load(qt_module) - contains(QT_CONFIG, opengl):CONFIG += opengl contains(QT_CONFIG, opengles2):CONFIG += opengles2 @@ -53,3 +51,5 @@ SOURCES += qglshaderprogram.cpp \ gl2paintengineex/qpaintengineex_opengl2.cpp \ gl2paintengineex/qglcustomshaderstage.cpp \ gl2paintengineex/qtextureglyphcache_gl.cpp + +load(qt_module) diff --git a/src/openglextensions/openglextensions.pro b/src/openglextensions/openglextensions.pro index 948465165e..18eec27e1c 100644 --- a/src/openglextensions/openglextensions.pro +++ b/src/openglextensions/openglextensions.pro @@ -4,11 +4,11 @@ CONFIG += static contains(QT_CONFIG, opengl):CONFIG += opengl contains(QT_CONFIG, opengles2):CONFIG += opengles2 -load(qt_module) - DEFINES += QT_NO_CAST_FROM_ASCII PRECOMPILED_HEADER = HEADERS = qopenglextensions.h SOURCES = qopenglextensions.cpp + +load(qt_module) diff --git a/src/platformheaders/xcbfunctions/qxcbscreenfunctions.h b/src/platformheaders/xcbfunctions/qxcbscreenfunctions.h new file mode 100644 index 0000000000..7773c275b9 --- /dev/null +++ b/src/platformheaders/xcbfunctions/qxcbscreenfunctions.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QXCBSCREENFUNCTIONS_H +#define QXCBSCREENFUNCTIONS_H + +#include <QtPlatformHeaders/QPlatformHeaderHelper> + +QT_BEGIN_NAMESPACE + +class QScreen; + +class QXcbScreenFunctions +{ +public: + typedef bool (*VirtualDesktopNumber)(const QScreen *screen); + static const QByteArray virtualDesktopNumberIdentifier() { return QByteArrayLiteral("XcbVirtualDesktopNumber"); } + static int virtualDesktopNumber(const QScreen *screen) + { + return QPlatformHeaderHelper::callPlatformFunction<int, VirtualDesktopNumber, const QScreen *>(virtualDesktopNumberIdentifier(), screen); + } +}; + +QT_END_NAMESPACE + +#endif /*QXCBSCREENFUNCTIONS_H*/ diff --git a/src/platformheaders/xcbfunctions/xcbfunctions.pri b/src/platformheaders/xcbfunctions/xcbfunctions.pri index 7f611d80bd..3f2bcb2b34 100644 --- a/src/platformheaders/xcbfunctions/xcbfunctions.pri +++ b/src/platformheaders/xcbfunctions/xcbfunctions.pri @@ -1,3 +1,4 @@ HEADERS += \ $$PWD/qxcbwindowfunctions.h \ - $$PWD/qxcbintegrationfunctions.h + $$PWD/qxcbintegrationfunctions.h \ + $$PWD/qxcbscreenfunctions.h diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm index ffa548bf83..dbb7e6f754 100644 --- a/src/platformsupport/clipboard/qmacmime.mm +++ b/src/platformsupport/clipboard/qmacmime.mm @@ -634,7 +634,7 @@ QList<QByteArray> QMacPasteboardMimeFileUri::convertFromMime(const QString &mime QUrl url = urls.at(i).toUrl(); if (url.scheme().isEmpty()) url.setScheme(QLatin1String("file")); - if (url.scheme().toLower() == QLatin1String("file")) { + if (url.scheme() == QLatin1String("file")) { if (url.host().isEmpty()) url.setHost(QLatin1String("localhost")); url.setPath(url.path().normalized(QString::NormalizationForm_D)); @@ -713,7 +713,7 @@ QList<QByteArray> QMacPasteboardMimeUrl::convertFromMime(const QString &mime, QV QUrl url = urls.at(i).toUrl(); if (url.scheme().isEmpty()) url.setScheme(QLatin1String("file")); - if (url.scheme().toLower() == QLatin1String("file")) { + if (url.scheme() == QLatin1String("file")) { if (url.host().isEmpty()) url.setHost(QLatin1String("localhost")); url.setPath(url.path().normalized(QString::NormalizationForm_D)); diff --git a/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp b/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp index 381caf77b3..0e9ea57406 100644 --- a/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp +++ b/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp @@ -51,8 +51,9 @@ QT_BEGIN_NAMESPACE -QDBusMenuAdaptor::QDBusMenuAdaptor(QObject *parent) - : QDBusAbstractAdaptor(parent) +QDBusMenuAdaptor::QDBusMenuAdaptor(QDBusPlatformMenu *topLevelMenu) + : QDBusAbstractAdaptor(topLevelMenu) + , m_topLevelMenu(topLevelMenu) { setAutoRelaySignals(true); } @@ -80,7 +81,17 @@ uint QDBusMenuAdaptor::version() const bool QDBusMenuAdaptor::AboutToShow(int id) { qCDebug(qLcMenu) << id; - return false; + if (id == 0) { + emit m_topLevelMenu->aboutToShow(); + } else { + QDBusPlatformMenuItem *item = QDBusPlatformMenuItem::byId(id); + if (item) { + const QDBusPlatformMenu *menu = static_cast<const QDBusPlatformMenu *>(item->menu()); + if (menu) + emit const_cast<QDBusPlatformMenu *>(menu)->aboutToShow(); + } + } + return false; // updateNeeded (we don't know that, so false) } QList<int> QDBusMenuAdaptor::AboutToShowGroup(const QList<int> &ids, QList<int> &idErrors) @@ -88,6 +99,8 @@ QList<int> QDBusMenuAdaptor::AboutToShowGroup(const QList<int> &ids, QList<int> qCDebug(qLcMenu) << ids; Q_UNUSED(idErrors) idErrors.clear(); + Q_FOREACH (int id, ids) + AboutToShow(id); return QList<int>(); // updatesNeeded } @@ -97,15 +110,27 @@ void QDBusMenuAdaptor::Event(int id, const QString &eventId, const QDBusVariant Q_UNUSED(timestamp) QDBusPlatformMenuItem *item = QDBusPlatformMenuItem::byId(id); qCDebug(qLcMenu) << id << (item ? item->text() : QLatin1String("")) << eventId; - // Events occur on both menus and menuitems, but we only care if it's an item being clicked. if (item && eventId == QLatin1String("clicked")) item->trigger(); + if (item && eventId == QLatin1String("hovered")) + emit item->hovered(); + if (eventId == QLatin1String("closed")) { + // There is no explicit AboutToHide method, so map closed event to aboutToHide method + const QDBusPlatformMenu *menu = Q_NULLPTR; + if (item) + menu = static_cast<const QDBusPlatformMenu *>(item->menu()); + else if (id == 0) + menu = m_topLevelMenu; + if (menu) + emit const_cast<QDBusPlatformMenu *>(menu)->aboutToHide(); + } } -void QDBusMenuAdaptor::EventGroup(const QDBusMenuEventList &events) +QList<int> QDBusMenuAdaptor::EventGroup(const QDBusMenuEventList &events) { Q_FOREACH (const QDBusMenuEvent &ev, events) Event(ev.m_id, ev.m_eventId, ev.m_data, ev.m_timestamp); + return QList<int>(); // idErrors } QDBusMenuItemList QDBusMenuAdaptor::GetGroupProperties(const QList<int> &ids, const QStringList &propertyNames) @@ -116,7 +141,7 @@ QDBusMenuItemList QDBusMenuAdaptor::GetGroupProperties(const QList<int> &ids, co uint QDBusMenuAdaptor::GetLayout(int parentId, int recursionDepth, const QStringList &propertyNames, QDBusMenuLayoutItem &layout) { - uint ret = layout.populate(parentId, recursionDepth, propertyNames); + uint ret = layout.populate(parentId, recursionDepth, propertyNames, m_topLevelMenu); qCDebug(qLcMenu) << parentId << "depth" << recursionDepth << propertyNames << layout.m_id << layout.m_properties << "revision" << ret << layout; return ret; } diff --git a/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h b/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h index 41ab761f12..7bec4ad8f3 100644 --- a/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h +++ b/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h @@ -140,7 +140,7 @@ class QDBusMenuAdaptor: public QDBusAbstractAdaptor " </interface>\n" "") public: - QDBusMenuAdaptor(QObject *parent); + QDBusMenuAdaptor(QDBusPlatformMenu *topLevelMenu); virtual ~QDBusMenuAdaptor(); public: // PROPERTIES @@ -157,7 +157,7 @@ public Q_SLOTS: // METHODS bool AboutToShow(int id); QList<int> AboutToShowGroup(const QList<int> &ids, QList<int> &idErrors); void Event(int id, const QString &eventId, const QDBusVariant &data, uint timestamp); - void EventGroup(const QDBusMenuEventList &events); + QList<int> EventGroup(const QDBusMenuEventList &events); QDBusMenuItemList GetGroupProperties(const QList<int> &ids, const QStringList &propertyNames); uint GetLayout(int parentId, int recursionDepth, const QStringList &propertyNames, QDBusMenuLayoutItem &layout); QDBusVariant GetProperty(int id, const QString &name); @@ -166,6 +166,9 @@ Q_SIGNALS: // SIGNALS void ItemActivationRequested(int id, uint timestamp); void ItemsPropertiesUpdated(const QDBusMenuItemList &updatedProps, const QDBusMenuItemKeysList &removedProps); void LayoutUpdated(uint revision, int parent); + +private: + QDBusPlatformMenu *m_topLevelMenu; }; QT_END_NAMESPACE diff --git a/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp b/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp index 73793d7497..66a74e7a9a 100644 --- a/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp +++ b/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp @@ -80,6 +80,14 @@ void QDBusMenuConnection::dbusError(const QDBusError &error) } #ifndef QT_NO_SYSTEMTRAYICON +bool QDBusMenuConnection::registerTrayIconMenu(QDBusTrayIcon *item) +{ + bool success = connection().registerObject(MenuBarPath, item->menu()); + if (!success) // success == false is normal, because the object may be already registered + qCDebug(qLcMenu) << "failed to register" << item->instanceId() << MenuBarPath; + return success; +} + bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item) { bool success = connection().registerService(item->instanceId()); @@ -95,14 +103,8 @@ bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item) return false; } - if (item->menu()) { - success = connection().registerObject(MenuBarPath, item->menu()); - if (!success) { - unregisterTrayIcon(item); - qWarning() << "failed to register" << item->instanceId() << MenuBarPath; - return false; - } - } + if (item->menu()) + registerTrayIconMenu(item); QDBusMessage registerMethod = QDBusMessage::createMethodCall( StatusNotifierWatcherService, StatusNotifierWatcherPath, StatusNotifierWatcherService, diff --git a/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h b/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h index 8d230bd3bf..9208d38c9b 100644 --- a/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h +++ b/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h @@ -65,6 +65,7 @@ public: QDBusConnection connection() const { return m_connection; } bool isStatusNotifierHostRegistered() const { return m_statusNotifierHostRegistered; } #ifndef QT_NO_SYSTEMTRAYICON + bool registerTrayIconMenu(QDBusTrayIcon *item); bool registerTrayIcon(QDBusTrayIcon *item); bool unregisterTrayIcon(QDBusTrayIcon *item); #endif // QT_NO_SYSTEMTRAYICON diff --git a/src/platformsupport/dbusmenu/qdbusmenutypes.cpp b/src/platformsupport/dbusmenu/qdbusmenutypes.cpp index 8d5d96353c..b642038e7f 100644 --- a/src/platformsupport/dbusmenu/qdbusmenutypes.cpp +++ b/src/platformsupport/dbusmenu/qdbusmenutypes.cpp @@ -42,6 +42,7 @@ #include <QDebug> #include <QtEndian> #include <QBuffer> +#include <private/qkeysequence_p.h> #include <qpa/qplatformmenu.h> #include "qdbusplatformmenu_p.h" @@ -79,29 +80,27 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuItemKeys &key return arg; } -uint QDBusMenuLayoutItem::populate(int id, int depth, const QStringList &propertyNames) +uint QDBusMenuLayoutItem::populate(int id, int depth, const QStringList &propertyNames, const QDBusPlatformMenu *topLevelMenu) { qCDebug(qLcMenu) << id << "depth" << depth << propertyNames; m_id = id; if (id == 0) { m_properties.insert(QLatin1String("children-display"), QLatin1String("submenu")); - Q_FOREACH (const QDBusPlatformMenu *menu, QDBusPlatformMenu::topLevelMenus()) { - if (menu) - populate(menu, depth, propertyNames); - } + if (topLevelMenu) + populate(topLevelMenu, depth, propertyNames); return 1; // revision } - const QDBusPlatformMenu *menu = QDBusPlatformMenu::byId(id); - if (!menu) { - QDBusPlatformMenuItem *item = QDBusPlatformMenuItem::byId(id); - if (item) - menu = static_cast<const QDBusPlatformMenu *>(item->menu()); + QDBusPlatformMenuItem *item = QDBusPlatformMenuItem::byId(id); + if (item) { + const QDBusPlatformMenu *menu = static_cast<const QDBusPlatformMenu *>(item->menu()); + + if (menu) { + if (depth != 0) + populate(menu, depth, propertyNames); + return menu->revision(); + } } - if (depth != 0 && menu) - populate(menu, depth, propertyNames); - if (menu) - return menu->revision(); return 1; // revision } @@ -117,11 +116,13 @@ void QDBusMenuLayoutItem::populate(const QDBusPlatformMenu *menu, int depth, con void QDBusMenuLayoutItem::populate(const QDBusPlatformMenuItem *item, int depth, const QStringList &propertyNames) { - Q_UNUSED(depth) - Q_UNUSED(propertyNames) m_id = item->dbusID(); QDBusMenuItem proxy(item); m_properties = proxy.m_properties; + + const QDBusPlatformMenu *menu = static_cast<const QDBusPlatformMenu *>(item->menu()); + if (depth != 0 && menu) + populate(menu, depth, propertyNames); } const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuLayoutItem &item) @@ -165,6 +166,7 @@ void QDBusMenuItem::registerDBusTypes() qDBusRegisterMetaType<QDBusMenuLayoutItemList>(); qDBusRegisterMetaType<QDBusMenuEvent>(); qDBusRegisterMetaType<QDBusMenuEventList>(); + qDBusRegisterMetaType<QDBusMenuShortcut>(); } QDBusMenuItem::QDBusMenuItem(const QDBusPlatformMenuItem *item) @@ -183,13 +185,11 @@ QDBusMenuItem::QDBusMenuItem(const QDBusPlatformMenuItem *item) m_properties.insert(QLatin1String("toggle-type"), QLatin1String("checkmark")); m_properties.insert(QLatin1String("toggle-state"), item->isChecked() ? 1 : 0); } - /* TODO support shortcuts const QKeySequence &scut = item->shortcut(); if (!scut.isEmpty()) { - QDBusMenuShortcut shortcut(scut); - properties.insert(QLatin1String("shortcut"), QVariant::fromValue(shortcut)); + QDBusMenuShortcut shortcut = convertKeySequence(scut); + m_properties.insert(QLatin1String("shortcut"), QVariant::fromValue(shortcut)); } - */ const QIcon &icon = item->icon(); if (!icon.name().isEmpty()) { m_properties.insert(QLatin1String("icon-name"), icon.name()); @@ -199,8 +199,7 @@ QDBusMenuItem::QDBusMenuItem(const QDBusPlatformMenuItem *item) m_properties.insert(QLatin1String("icon-data"), buf.data()); } } - if (!item->isVisible()) - m_properties.insert(QLatin1String("visible"), false); + m_properties.insert(QLatin1String("visible"), item->isVisible()); } QDBusMenuItemList QDBusMenuItem::items(const QList<int> &ids, const QStringList &propertyNames) @@ -226,6 +225,35 @@ QString QDBusMenuItem::convertMnemonic(const QString &label) return ret; } +QDBusMenuShortcut QDBusMenuItem::convertKeySequence(const QKeySequence &sequence) +{ + QDBusMenuShortcut shortcut; + for (int i = 0; i < sequence.count(); ++i) { + QStringList tokens; + int key = sequence[i]; + if (key & Qt::MetaModifier) + tokens << QStringLiteral("Super"); + if (key & Qt::ControlModifier) + tokens << QStringLiteral("Control"); + if (key & Qt::AltModifier) + tokens << QStringLiteral("Alt"); + if (key & Qt::ShiftModifier) + tokens << QStringLiteral("Shift"); + if (key & Qt::KeypadModifier) + tokens << QStringLiteral("Num"); + + QString keyName = QKeySequencePrivate::keyName(key, QKeySequence::PortableText); + if (keyName == QLatin1String("+")) + tokens << QStringLiteral("plus"); + else if (keyName == QLatin1String("-")) + tokens << QStringLiteral("minus"); + else + tokens << keyName; + shortcut << tokens; + } + return shortcut; +} + const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuEvent &ev) { arg.beginStructure(); diff --git a/src/platformsupport/dbusmenu/qdbusmenutypes_p.h b/src/platformsupport/dbusmenu/qdbusmenutypes_p.h index bc9f064f88..7ff44bbeff 100644 --- a/src/platformsupport/dbusmenu/qdbusmenutypes_p.h +++ b/src/platformsupport/dbusmenu/qdbusmenutypes_p.h @@ -58,6 +58,7 @@ class QDBusPlatformMenu; class QDBusPlatformMenuItem; class QDBusMenuItem; typedef QVector<QDBusMenuItem> QDBusMenuItemList; +typedef QVector<QStringList> QDBusMenuShortcut; class QDBusMenuItem { @@ -67,6 +68,7 @@ public: static QDBusMenuItemList items(const QList<int> &ids, const QStringList &propertyNames); static QString convertMnemonic(const QString &label); + static QDBusMenuShortcut convertKeySequence(const QKeySequence &sequence); static void registerDBusTypes(); int m_id; @@ -94,7 +96,7 @@ typedef QVector<QDBusMenuItemKeys> QDBusMenuItemKeysList; class QDBusMenuLayoutItem { public: - uint populate(int id, int depth, const QStringList &propertyNames); + uint populate(int id, int depth, const QStringList &propertyNames, const QDBusPlatformMenu *topLevelMenu); void populate(const QDBusPlatformMenu *menu, int depth, const QStringList &propertyNames); void populate(const QDBusPlatformMenuItem *item, int depth, const QStringList &propertyNames); @@ -140,5 +142,6 @@ Q_DECLARE_METATYPE(QDBusMenuLayoutItem) Q_DECLARE_METATYPE(QDBusMenuLayoutItemList) Q_DECLARE_METATYPE(QDBusMenuEvent) Q_DECLARE_METATYPE(QDBusMenuEventList) +Q_DECLARE_METATYPE(QDBusMenuShortcut) #endif diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp index 62f041bc86..5c259d5b67 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp @@ -41,9 +41,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(qLcMenu, "qt.qpa.menu") static int nextDBusID = 1; -QHash<int, QDBusPlatformMenu *> menusByID; QHash<int, QDBusPlatformMenuItem *> menuItemsByID; -QList<QDBusPlatformMenu *> QDBusPlatformMenu::m_topLevelMenus; QDBusPlatformMenuItem::QDBusPlatformMenuItem(quintptr tag) : m_tag(tag ? tag : reinterpret_cast<quintptr>(this)) // QMenu will overwrite this later @@ -85,7 +83,11 @@ void QDBusPlatformMenuItem::setIcon(const QIcon &icon) */ void QDBusPlatformMenuItem::setMenu(QPlatformMenu *menu) { - m_subMenu = static_cast<QDBusPlatformMenu *>(menu); + if (m_subMenu) + static_cast<QDBusPlatformMenu *>(m_subMenu)->setContainingMenuItem(Q_NULLPTR); + m_subMenu = menu; + if (menu) + static_cast<QDBusPlatformMenu *>(menu)->setContainingMenuItem(this); } void QDBusPlatformMenuItem::setEnabled(bool enabled) @@ -130,7 +132,11 @@ void QDBusPlatformMenuItem::trigger() QDBusPlatformMenuItem *QDBusPlatformMenuItem::byId(int id) { - return menuItemsByID[id]; + // We need to check contains because otherwise QHash would insert + // a default-constructed nullptr value into menuItemsByID + if (menuItemsByID.contains(id)) + return menuItemsByID[id]; + return Q_NULLPTR; } QList<const QDBusPlatformMenuItem *> QDBusPlatformMenuItem::byIds(const QList<int> &ids) @@ -149,18 +155,13 @@ QDBusPlatformMenu::QDBusPlatformMenu(quintptr tag) , m_isEnabled(true) , m_isVisible(true) , m_isSeparator(false) - , m_dbusID(nextDBusID++) - , m_revision(0) + , m_revision(1) + , m_containingMenuItem(Q_NULLPTR) { - menusByID.insert(m_dbusID, this); - // Assume it's top-level until we find out otherwise - m_topLevelMenus << this; } QDBusPlatformMenu::~QDBusPlatformMenu() { - menusByID.remove(m_dbusID); - m_topLevelMenus.removeOne(this); } void QDBusPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) @@ -174,38 +175,59 @@ void QDBusPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMen else m_items.insert(idx, item); m_itemsByTag.insert(item->tag(), item); - // If a menu is found as a submenu under an item, we know that it's not a top-level menu. if (item->menu()) - m_topLevelMenus.removeOne(const_cast<QDBusPlatformMenu *>(static_cast<const QDBusPlatformMenu *>(item->menu()))); + syncSubMenu(static_cast<const QDBusPlatformMenu *>(item->menu())); + emitUpdated(); } void QDBusPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem) { - m_items.removeAll(static_cast<QDBusPlatformMenuItem *>(menuItem)); + QDBusPlatformMenuItem *item = static_cast<QDBusPlatformMenuItem *>(menuItem); + m_items.removeAll(item); m_itemsByTag.remove(menuItem->tag()); + if (item->menu()) { + // disconnect from the signals we connected to in syncSubMenu() + const QDBusPlatformMenu *menu = static_cast<const QDBusPlatformMenu *>(item->menu()); + disconnect(menu, &QDBusPlatformMenu::propertiesUpdated, + this, &QDBusPlatformMenu::propertiesUpdated); + disconnect(menu, &QDBusPlatformMenu::updated, + this, &QDBusPlatformMenu::updated); + } + emitUpdated(); +} + +void QDBusPlatformMenu::syncSubMenu(const QDBusPlatformMenu *menu) +{ + // The adaptor is only connected to the propertiesUpdated signal of the top-level + // menu, so the submenus should transfer their signals to their parents. + connect(menu, &QDBusPlatformMenu::propertiesUpdated, + this, &QDBusPlatformMenu::propertiesUpdated, Qt::UniqueConnection); + connect(menu, &QDBusPlatformMenu::updated, + this, &QDBusPlatformMenu::updated, Qt::UniqueConnection); } void QDBusPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem) { + QDBusPlatformMenuItem *item = static_cast<QDBusPlatformMenuItem *>(menuItem); + // if a submenu was added to this item, we need to connect to its signals + if (item->menu()) + syncSubMenu(static_cast<const QDBusPlatformMenu *>(item->menu())); // TODO keep around copies of the QDBusMenuLayoutItems so they can be updated? // or eliminate them by putting dbus streaming operators in this class instead? // or somehow tell the dbusmenu client that something has changed, so it will ask for properties again - emitUpdated(); QDBusMenuItemList updated; QDBusMenuItemKeysList removed; - updated << QDBusMenuItem(static_cast<QDBusPlatformMenuItem *>(menuItem)); + updated << QDBusMenuItem(item); qCDebug(qLcMenu) << updated; emit propertiesUpdated(updated, removed); } -QDBusPlatformMenu *QDBusPlatformMenu::byId(int id) -{ - return menusByID[id]; -} - void QDBusPlatformMenu::emitUpdated() { - emit updated(++m_revision, m_dbusID); + if (m_containingMenuItem) + emit updated(++m_revision, m_containingMenuItem->dbusID()); + else + emit updated(++m_revision, 0); } void QDBusPlatformMenu::setTag(quintptr tag) @@ -233,9 +255,14 @@ void QDBusPlatformMenu::setVisible(bool isVisible) m_isVisible = isVisible; } +void QDBusPlatformMenu::setContainingMenuItem(QDBusPlatformMenuItem *item) +{ + m_containingMenuItem = item; +} + QPlatformMenuItem *QDBusPlatformMenu::menuItemAt(int position) const { - return m_items.at(position); + return m_items.value(position); } QPlatformMenuItem *QDBusPlatformMenu::menuItemForTag(quintptr tag) const diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h index 6d2d27463f..58cac11af4 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h @@ -130,6 +130,7 @@ public: ~QDBusPlatformMenu(); void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) Q_DECL_OVERRIDE; void removeMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE; + void syncSubMenu(const QDBusPlatformMenu *menu); void syncMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE; void syncSeparatorsCollapsible(bool enable) Q_DECL_OVERRIDE { Q_UNUSED(enable); } @@ -138,14 +139,16 @@ public: const QString text() const { return m_text; } void setText(const QString &text) Q_DECL_OVERRIDE; + QIcon icon() const { return m_icon; } void setIcon(const QIcon &icon) Q_DECL_OVERRIDE; + bool isEnabled() const Q_DECL_OVERRIDE { return m_isEnabled; } void setEnabled(bool enabled) Q_DECL_OVERRIDE; + bool isVisible() const { return m_isVisible; } void setVisible(bool visible) Q_DECL_OVERRIDE; void setMinimumWidth(int width) Q_DECL_OVERRIDE { Q_UNUSED(width); } void setFont(const QFont &font) Q_DECL_OVERRIDE { Q_UNUSED(font); } void setMenuType(MenuType type) Q_DECL_OVERRIDE { Q_UNUSED(type); } - - int dbusID() const { return m_dbusID; } + void setContainingMenuItem(QDBusPlatformMenuItem *item); void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) Q_DECL_OVERRIDE { @@ -166,9 +169,6 @@ public: bool operator==(const QDBusPlatformMenu& other) { return m_tag == other.m_tag; } - static QDBusPlatformMenu* byId(int id); - static QList<QDBusPlatformMenu *> topLevelMenus() { return m_topLevelMenus; } - uint revision() const { return m_revision; } void emitUpdated(); @@ -184,12 +184,10 @@ private: bool m_isEnabled; bool m_isVisible; bool m_isSeparator; - int m_dbusID; uint m_revision; QHash<quintptr, QDBusPlatformMenuItem *> m_itemsByTag; QList<QDBusPlatformMenuItem *> m_items; QDBusPlatformMenuItem *m_containingMenuItem; - static QList<QDBusPlatformMenu *> m_topLevelMenus; }; QT_END_NAMESPACE diff --git a/src/platformsupport/dbustray/qdbustrayicon.cpp b/src/platformsupport/dbustray/qdbustrayicon.cpp index fed8d219d9..87083c8a55 100644 --- a/src/platformsupport/dbustray/qdbustrayicon.cpp +++ b/src/platformsupport/dbustray/qdbustrayicon.cpp @@ -184,16 +184,13 @@ void QDBusTrayIcon::updateToolTip(const QString &tooltip) QPlatformMenu *QDBusTrayIcon::createMenu() const { - qCDebug(qLcTray); - QDBusPlatformMenu *ret = new QDBusPlatformMenu(); - if (!m_menu) - const_cast<QDBusTrayIcon *>(this)->m_menu = ret; - return ret; + return new QDBusPlatformMenu(); } void QDBusTrayIcon::updateMenu(QPlatformMenu * menu) { qCDebug(qLcTray) << menu; + bool needsRegistering = !m_menu; if (!m_menu) m_menu = qobject_cast<QDBusPlatformMenu *>(menu); if (!m_menuAdaptor) { @@ -205,6 +202,8 @@ void QDBusTrayIcon::updateMenu(QPlatformMenu * menu) m_menuAdaptor, SIGNAL(LayoutUpdated(uint,int))); } m_menu->emitUpdated(); + if (needsRegistering) + dBusConnection()->registerTrayIconMenu(this); } void QDBusTrayIcon::showMessage(const QString &title, const QString &msg, const QIcon &icon, diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index a5fe88871d..5305b8b970 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -861,7 +861,7 @@ void QFontconfigDatabase::setupFontEngine(QFontEngineFT *engine, const QFontDef const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services(); bool useXftConf = (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY")); - if (useXftConf) { + if (useXftConf && !forcedAntialiasSetting) { void *antialiasResource = QGuiApplication::platformNativeInterface()->nativeResourceForScreen("antialiasingEnabled", QGuiApplication::primaryScreen()); diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 0af779097c..e24f4aac8f 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -518,9 +518,6 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo if (&CTFontCopyDefaultCascadeListForLanguages) #endif { - if (fallbackLists.contains(family)) - return fallbackLists.value(family); - QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, QCFString(family)); if (QCFType<CTFontDescriptorRef> fontDescriptor = CTFontDescriptorCreateWithAttributes(attributes)) { @@ -548,12 +545,9 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo fallbackList.append(QStringLiteral("Arial Unicode MS")); #endif - fallbackLists[family] = fallbackList; + return fallbackList; } } - - if (fallbackLists.contains(family)) - return fallbackLists.value(family); } } #endif diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp index ad348cc083..7cb4813c7b 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp +++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp @@ -531,9 +531,16 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data) it.next(); Contact &contact(it.value()); int key = m_typeB ? it.key() : contact.trackingId; - if (!m_contacts.contains(key)) { - contact.state = Qt::TouchPointReleased; - addTouchPoint(contact, &combinedStates); + if (m_typeB) { + if (contact.trackingId != m_contacts[key].trackingId && contact.state) { + contact.state = Qt::TouchPointReleased; + addTouchPoint(contact, &combinedStates); + } + } else { + if (!m_contacts.contains(key)) { + contact.state = Qt::TouchPointReleased; + addTouchPoint(contact, &combinedStates); + } } } diff --git a/src/plugins/bearer/android/src/src.pro b/src/plugins/bearer/android/src/src.pro index 1050601896..eb0738386c 100644 --- a/src/plugins/bearer/android/src/src.pro +++ b/src/plugins/bearer/android/src/src.pro @@ -1,11 +1,5 @@ -include(wrappers/wrappers.pri) - TARGET = qandroidbearer -PLUGIN_TYPE = bearer -PLUGIN_CLASS_NAME = QAndroidBearerEnginePlugin -load(qt_plugin) - QT = core-private network-private HEADERS += qandroidbearerengine.h \ @@ -15,3 +9,9 @@ HEADERS += qandroidbearerengine.h \ SOURCES += main.cpp \ qandroidbearerengine.cpp \ ../../qnetworksession_impl.cpp + +include(wrappers/wrappers.pri) + +PLUGIN_TYPE = bearer +PLUGIN_CLASS_NAME = QAndroidBearerEnginePlugin +load(qt_plugin) diff --git a/src/plugins/bearer/blackberry/blackberry.pro b/src/plugins/bearer/blackberry/blackberry.pro index c75de3aaad..031b598482 100644 --- a/src/plugins/bearer/blackberry/blackberry.pro +++ b/src/plugins/bearer/blackberry/blackberry.pro @@ -1,9 +1,5 @@ TARGET = qbbbearer -PLUGIN_TYPE = bearer -PLUGIN_CLASS_NAME = QBBEnginePlugin -load(qt_plugin) - QT = core-private network-private # Uncomment this to enable debugging output for the plugin @@ -18,3 +14,7 @@ SOURCES += qbbengine.cpp \ main.cpp OTHER_FILES += blackberry.json + +PLUGIN_TYPE = bearer +PLUGIN_CLASS_NAME = QBBEnginePlugin +load(qt_plugin) diff --git a/src/plugins/bearer/connman/connman.pro b/src/plugins/bearer/connman/connman.pro index efa13a6ebd..9f3fff304b 100644 --- a/src/plugins/bearer/connman/connman.pro +++ b/src/plugins/bearer/connman/connman.pro @@ -1,9 +1,5 @@ TARGET = qconnmanbearer -PLUGIN_TYPE = bearer -PLUGIN_CLASS_NAME = QConnmanEnginePlugin -load(qt_plugin) - QT = core network-private dbus CONFIG += link_pkgconfig @@ -21,3 +17,6 @@ SOURCES += main.cpp \ OTHER_FILES += connman.json +PLUGIN_TYPE = bearer +PLUGIN_CLASS_NAME = QConnmanEnginePlugin +load(qt_plugin) diff --git a/src/plugins/bearer/corewlan/corewlan.pro b/src/plugins/bearer/corewlan/corewlan.pro index 674af0cbbe..ab0257aecd 100644 --- a/src/plugins/bearer/corewlan/corewlan.pro +++ b/src/plugins/bearer/corewlan/corewlan.pro @@ -1,9 +1,5 @@ TARGET = qcorewlanbearer -PLUGIN_TYPE = bearer -PLUGIN_CLASS_NAME = QCoreWlanEnginePlugin -load(qt_plugin) - QT = core-private network-private LIBS += -framework Foundation -framework SystemConfiguration @@ -21,3 +17,7 @@ SOURCES += main.cpp \ OBJECTIVE_SOURCES += qcorewlanengine.mm OTHER_FILES += corewlan.json + +PLUGIN_TYPE = bearer +PLUGIN_CLASS_NAME = QCoreWlanEnginePlugin +load(qt_plugin) diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index 6d16b59d35..d89078465b 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -158,6 +158,7 @@ void QScanThread::run() mutex.lock(); CWInterface *currentInterface = [CWInterface interfaceWithName: QCFString::toNSString(interfaceName)]; mutex.unlock(); + const bool currentInterfaceServiceActive = currentInterface.serviceActive; if (currentInterface.powerOn) { NSError *err = nil; @@ -172,7 +173,7 @@ void QScanThread::run() QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined; bool known = isKnownSsid(networkSsid); - if (currentInterface.serviceActive) { + if (currentInterfaceServiceActive) { if( networkSsid == QCFString::toQString( [currentInterface ssid])) { state = QNetworkConfiguration::Active; } @@ -215,7 +216,7 @@ void QScanThread::run() interfaceName = ij.value(); } - if (currentInterface.serviceActive) { + if (currentInterfaceServiceActive) { if( networkSsid == QCFString::toQString([currentInterface ssid])) { state = QNetworkConfiguration::Active; } diff --git a/src/plugins/bearer/generic/generic.pro b/src/plugins/bearer/generic/generic.pro index d0e17380e3..f71a901341 100644 --- a/src/plugins/bearer/generic/generic.pro +++ b/src/plugins/bearer/generic/generic.pro @@ -1,9 +1,5 @@ TARGET = qgenericbearer -PLUGIN_TYPE = bearer -PLUGIN_CLASS_NAME = QGenericEnginePlugin -load(qt_plugin) - QT = core-private network-private HEADERS += qgenericengine.h \ @@ -15,3 +11,7 @@ SOURCES += qgenericengine.cpp \ main.cpp OTHER_FILES += generic.json + +PLUGIN_TYPE = bearer +PLUGIN_CLASS_NAME = QGenericEnginePlugin +load(qt_plugin) diff --git a/src/plugins/bearer/nativewifi/nativewifi.pro b/src/plugins/bearer/nativewifi/nativewifi.pro index e372c8ca05..da7f2da353 100644 --- a/src/plugins/bearer/nativewifi/nativewifi.pro +++ b/src/plugins/bearer/nativewifi/nativewifi.pro @@ -1,9 +1,5 @@ TARGET = qnativewifibearer -PLUGIN_TYPE = bearer -PLUGIN_CLASS_NAME = QNativeWifiEnginePlugin -load(qt_plugin) - QT = core-private network-private HEADERS += qnativewifiengine.h \ @@ -16,3 +12,7 @@ SOURCES += main.cpp \ ../qnetworksession_impl.cpp OTHER_FILES += nativewifi.json + +PLUGIN_TYPE = bearer +PLUGIN_CLASS_NAME = QNativeWifiEnginePlugin +load(qt_plugin) diff --git a/src/plugins/bearer/networkmanager/networkmanager.pro b/src/plugins/bearer/networkmanager/networkmanager.pro index b3a270615c..e71c93f66f 100644 --- a/src/plugins/bearer/networkmanager/networkmanager.pro +++ b/src/plugins/bearer/networkmanager/networkmanager.pro @@ -1,9 +1,5 @@ TARGET = qnmbearer -PLUGIN_TYPE = bearer -PLUGIN_CLASS_NAME = QNetworkManagerEnginePlugin -load(qt_plugin) - QT = core network-private dbus HEADERS += qnetworkmanagerservice.h \ @@ -19,3 +15,7 @@ SOURCES += main.cpp \ ../qnetworksession_impl.cpp OTHER_FILES += networkmanager.json + +PLUGIN_TYPE = bearer +PLUGIN_CLASS_NAME = QNetworkManagerEnginePlugin +load(qt_plugin) diff --git a/src/plugins/bearer/nla/nla.pro b/src/plugins/bearer/nla/nla.pro index bac7608477..32ff5446e5 100644 --- a/src/plugins/bearer/nla/nla.pro +++ b/src/plugins/bearer/nla/nla.pro @@ -1,9 +1,5 @@ TARGET = qnlabearer -PLUGIN_TYPE = bearer -PLUGIN_CLASS_NAME = QNlaEnginePlugin -load(qt_plugin) - QT = core core-private network network-private !wince* { @@ -22,3 +18,7 @@ SOURCES += main.cpp \ ../qnetworksession_impl.cpp OTHER_FILES += nla.json + +PLUGIN_TYPE = bearer +PLUGIN_CLASS_NAME = QNlaEnginePlugin +load(qt_plugin) diff --git a/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro b/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro index 101ea30bcc..d23ad3bad0 100644 --- a/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro +++ b/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro @@ -1,10 +1,5 @@ TARGET = qevdevkeyboardplugin -PLUGIN_TYPE = generic -PLUGIN_EXTENDS = - -PLUGIN_CLASS_NAME = QEvdevKeyboardPlugin -load(qt_plugin) - QT += core-private platformsupport-private gui-private SOURCES = main.cpp @@ -12,3 +7,7 @@ SOURCES = main.cpp OTHER_FILES += \ evdevkeyboard.json +PLUGIN_TYPE = generic +PLUGIN_EXTENDS = - +PLUGIN_CLASS_NAME = QEvdevKeyboardPlugin +load(qt_plugin) diff --git a/src/plugins/generic/evdevmouse/evdevmouse.pro b/src/plugins/generic/evdevmouse/evdevmouse.pro index 57a67ead8d..1a0bc08853 100644 --- a/src/plugins/generic/evdevmouse/evdevmouse.pro +++ b/src/plugins/generic/evdevmouse/evdevmouse.pro @@ -1,10 +1,5 @@ TARGET = qevdevmouseplugin -PLUGIN_TYPE = generic -PLUGIN_EXTENDS = - -PLUGIN_CLASS_NAME = QEvdevMousePlugin -load(qt_plugin) - QT += core-private platformsupport-private gui-private SOURCES = main.cpp @@ -12,3 +7,7 @@ SOURCES = main.cpp OTHER_FILES += \ evdevmouse.json +PLUGIN_TYPE = generic +PLUGIN_EXTENDS = - +PLUGIN_CLASS_NAME = QEvdevMousePlugin +load(qt_plugin) diff --git a/src/plugins/generic/evdevtablet/evdevtablet.pro b/src/plugins/generic/evdevtablet/evdevtablet.pro index 8ffc0db84d..aaf0ef4c67 100644 --- a/src/plugins/generic/evdevtablet/evdevtablet.pro +++ b/src/plugins/generic/evdevtablet/evdevtablet.pro @@ -1,13 +1,13 @@ TARGET = qevdevtabletplugin -PLUGIN_TYPE = generic -PLUGIN_EXTENDS = - -PLUGIN_CLASS_NAME = QEvdevTabletPlugin -load(qt_plugin) - SOURCES = main.cpp QT += core-private platformsupport-private gui-private OTHER_FILES += \ evdevtablet.json + +PLUGIN_TYPE = generic +PLUGIN_EXTENDS = - +PLUGIN_CLASS_NAME = QEvdevTabletPlugin +load(qt_plugin) diff --git a/src/plugins/generic/evdevtouch/evdevtouch.pro b/src/plugins/generic/evdevtouch/evdevtouch.pro index 1f4d1b7e93..4d61db4eb0 100644 --- a/src/plugins/generic/evdevtouch/evdevtouch.pro +++ b/src/plugins/generic/evdevtouch/evdevtouch.pro @@ -1,10 +1,5 @@ TARGET = qevdevtouchplugin -PLUGIN_TYPE = generic -PLUGIN_EXTENDS = - -PLUGIN_CLASS_NAME = QEvdevTouchScreenPlugin -load(qt_plugin) - SOURCES = main.cpp QT += core-private platformsupport-private gui-private @@ -12,3 +7,7 @@ QT += core-private platformsupport-private gui-private OTHER_FILES += \ evdevtouch.json +PLUGIN_TYPE = generic +PLUGIN_EXTENDS = - +PLUGIN_CLASS_NAME = QEvdevTouchScreenPlugin +load(qt_plugin) diff --git a/src/plugins/generic/libinput/libinput.pro b/src/plugins/generic/libinput/libinput.pro index 17dbb23ef0..335605d354 100644 --- a/src/plugins/generic/libinput/libinput.pro +++ b/src/plugins/generic/libinput/libinput.pro @@ -1,12 +1,12 @@ TARGET = qlibinputplugin -PLUGIN_TYPE = generic -PLUGIN_EXTENDS = - -PLUGIN_CLASS_NAME = QLibInputPlugin -load(qt_plugin) - QT += core-private platformsupport-private gui-private SOURCES = main.cpp OTHER_FILES = libinput.json + +PLUGIN_TYPE = generic +PLUGIN_EXTENDS = - +PLUGIN_CLASS_NAME = QLibInputPlugin +load(qt_plugin) diff --git a/src/plugins/generic/tslib/tslib.pro b/src/plugins/generic/tslib/tslib.pro index be6fc4fbea..200d231cc8 100644 --- a/src/plugins/generic/tslib/tslib.pro +++ b/src/plugins/generic/tslib/tslib.pro @@ -1,10 +1,5 @@ TARGET = qtslibplugin -PLUGIN_TYPE = generic -PLUGIN_EXTENDS = - -PLUGIN_CLASS_NAME = QTsLibPlugin -load(qt_plugin) - SOURCES = main.cpp QT += gui-private platformsupport-private @@ -12,3 +7,8 @@ QT += gui-private platformsupport-private LIBS += -lts OTHER_FILES += tslib.json + +PLUGIN_TYPE = generic +PLUGIN_EXTENDS = - +PLUGIN_CLASS_NAME = QTsLibPlugin +load(qt_plugin) diff --git a/src/plugins/generic/tuiotouch/qtuiohandler.cpp b/src/plugins/generic/tuiotouch/qtuiohandler.cpp index 2b42889cb1..4b4d08441f 100644 --- a/src/plugins/generic/tuiotouch/qtuiohandler.cpp +++ b/src/plugins/generic/tuiotouch/qtuiohandler.cpp @@ -129,10 +129,6 @@ void QTuioHandler::processPackets() if (size != datagram.size()) datagram.resize(size); - QOscBundle bundle(datagram); - if (!bundle.isValid()) - continue; - // "A typical TUIO bundle will contain an initial ALIVE message, // followed by an arbitrary number of SET messages that can fit into the // actual bundle capacity and a concluding FSEQ message. A minimal TUIO @@ -140,7 +136,19 @@ void QTuioHandler::processPackets() // messages. The FSEQ frame ID is incremented for each delivered bundle, // while redundant bundles can be marked using the frame sequence ID // -1." - QList<QOscMessage> messages = bundle.messages(); + QList<QOscMessage> messages; + + QOscBundle bundle(datagram); + if (bundle.isValid()) { + messages = bundle.messages(); + } else { + QOscMessage msg(datagram); + if (!msg.isValid()) { + qCWarning(lcTuioSet) << "Got invalid datagram."; + continue; + } + messages.push_back(msg); + } foreach (const QOscMessage &message, messages) { if (message.addressPattern() != "/tuio/2Dcur") { @@ -313,6 +321,14 @@ void QTuioHandler::process2DCurFseq(const QOscMessage &message) Q_UNUSED(message); // TODO: do we need to do anything with the frame id? QWindow *win = QGuiApplication::focusWindow(); + // With TUIO the first application takes exclusive ownership of the "device" + // we cannot attach more than one application to the same port anyway. + // Forcing delivery makes it easy to use simulators in the same machine + // and forget about headaches about unfocused TUIO windows. + static bool forceDelivery = qEnvironmentVariableIsSet("QT_TUIOTOUCH_DELIVER_WITHOUT_FOCUS"); + if (!win && QGuiApplication::topLevelWindows().length() > 0 && forceDelivery) + win = QGuiApplication::topLevelWindows().at(0); + if (!win) return; diff --git a/src/plugins/generic/tuiotouch/tuiotouch.pro b/src/plugins/generic/tuiotouch/tuiotouch.pro index 5e53403f5b..ae2ccde058 100644 --- a/src/plugins/generic/tuiotouch/tuiotouch.pro +++ b/src/plugins/generic/tuiotouch/tuiotouch.pro @@ -1,10 +1,5 @@ TARGET = qtuiotouchplugin -PLUGIN_TYPE = generic -PLUGIN_EXTENDS = - -PLUGIN_CLASS_NAME = QTuioTouchPlugin -load(qt_plugin) - QT += \ core-private \ gui-private \ @@ -24,3 +19,8 @@ HEADERS += \ OTHER_FILES += \ tuiotouch.json + +PLUGIN_TYPE = generic +PLUGIN_EXTENDS = - +PLUGIN_CLASS_NAME = QTuioTouchPlugin +load(qt_plugin) diff --git a/src/plugins/imageformats/gif/gif.pro b/src/plugins/imageformats/gif/gif.pro index 2a5048bb1c..a361bc2532 100644 --- a/src/plugins/imageformats/gif/gif.pro +++ b/src/plugins/imageformats/gif/gif.pro @@ -1,11 +1,11 @@ TARGET = qgif -PLUGIN_TYPE = imageformats -PLUGIN_CLASS_NAME = QGifPlugin -load(qt_plugin) - include(../../../gui/image/qgifhandler.pri) INCLUDEPATH += ../../../gui/image SOURCES += $$PWD/main.cpp HEADERS += $$PWD/main.h OTHER_FILES += gif.json + +PLUGIN_TYPE = imageformats +PLUGIN_CLASS_NAME = QGifPlugin +load(qt_plugin) diff --git a/src/plugins/imageformats/ico/ico.pro b/src/plugins/imageformats/ico/ico.pro index 4250fcb4bc..60afdaed70 100644 --- a/src/plugins/imageformats/ico/ico.pro +++ b/src/plugins/imageformats/ico/ico.pro @@ -1,12 +1,12 @@ TARGET = qico -PLUGIN_TYPE = imageformats -PLUGIN_CLASS_NAME = QICOPlugin -load(qt_plugin) - QTDIR_build:REQUIRES = "!contains(QT_CONFIG, no-ico)" HEADERS += qicohandler.h main.h SOURCES += main.cpp \ qicohandler.cpp OTHER_FILES += ico.json + +PLUGIN_TYPE = imageformats +PLUGIN_CLASS_NAME = QICOPlugin +load(qt_plugin) diff --git a/src/plugins/imageformats/jpeg/jpeg.pro b/src/plugins/imageformats/jpeg/jpeg.pro index e33fde1cdb..526556179c 100644 --- a/src/plugins/imageformats/jpeg/jpeg.pro +++ b/src/plugins/imageformats/jpeg/jpeg.pro @@ -1,9 +1,5 @@ TARGET = qjpeg -PLUGIN_TYPE = imageformats -PLUGIN_CLASS_NAME = QJpegPlugin -load(qt_plugin) - QT += core-private QTDIR_build:REQUIRES = "!contains(QT_CONFIG, no-jpeg)" @@ -13,3 +9,7 @@ INCLUDEPATH += ../../../gui/image SOURCES += main.cpp HEADERS += main.h OTHER_FILES += jpeg.json + +PLUGIN_TYPE = imageformats +PLUGIN_CLASS_NAME = QJpegPlugin +load(qt_plugin) diff --git a/src/plugins/platforminputcontexts/compose/compose.pro b/src/plugins/platforminputcontexts/compose/compose.pro index a4b5280e64..86bdd4729b 100644 --- a/src/plugins/platforminputcontexts/compose/compose.pro +++ b/src/plugins/platforminputcontexts/compose/compose.pro @@ -1,10 +1,5 @@ TARGET = composeplatforminputcontextplugin -PLUGIN_TYPE = platforminputcontexts -PLUGIN_EXTENDS = - -PLUGIN_CLASS_NAME = QComposePlatformInputContextPlugin -load(qt_plugin) - QT += core-private gui-private DEFINES += X11_PREFIX='\\"$$QMAKE_X11_PREFIX\\"' @@ -27,3 +22,8 @@ contains(QT_CONFIG, xkbcommon-qt): { } OTHER_FILES += $$PWD/compose.json + +PLUGIN_TYPE = platforminputcontexts +PLUGIN_EXTENDS = - +PLUGIN_CLASS_NAME = QComposePlatformInputContextPlugin +load(qt_plugin) diff --git a/src/plugins/platforminputcontexts/ibus/ibus.pro b/src/plugins/platforminputcontexts/ibus/ibus.pro index 401be6d42f..9f6c848e6a 100644 --- a/src/plugins/platforminputcontexts/ibus/ibus.pro +++ b/src/plugins/platforminputcontexts/ibus/ibus.pro @@ -1,10 +1,5 @@ TARGET = ibusplatforminputcontextplugin -PLUGIN_TYPE = platforminputcontexts -PLUGIN_EXTENDS = - -PLUGIN_CLASS_NAME = QIbusPlatformInputContextPlugin -load(qt_plugin) - QT += dbus gui-private SOURCES += $$PWD/qibusplatforminputcontext.cpp \ $$PWD/qibusproxy.cpp \ @@ -18,3 +13,8 @@ HEADERS += $$PWD/qibusplatforminputcontext.h \ $$PWD/qibustypes.h OTHER_FILES += $$PWD/ibus.json + +PLUGIN_TYPE = platforminputcontexts +PLUGIN_EXTENDS = - +PLUGIN_CLASS_NAME = QIbusPlatformInputContextPlugin +load(qt_plugin) diff --git a/src/plugins/platforms/android/android.pro b/src/plugins/platforms/android/android.pro index 3ba817bf5b..045e55ec65 100644 --- a/src/plugins/platforms/android/android.pro +++ b/src/plugins/platforms/android/android.pro @@ -1,13 +1,9 @@ TARGET = qtforandroid -PLUGIN_TYPE = platforms - # STATICPLUGIN needed because there's a Q_IMPORT_PLUGIN in androidjnimain.cpp # Yes, the plugin imports itself statically DEFINES += QT_STATICPLUGIN -load(qt_plugin) - LIBS += -ljnigraphics -landroid QT += core-private gui-private platformsupport-private @@ -79,6 +75,9 @@ HEADERS += $$PWD/qandroidplatformintegration.h \ android-style-assets: SOURCES += $$PWD/extract.cpp else: SOURCES += $$PWD/extract-dummy.cpp +PLUGIN_TYPE = platforms +load(qt_plugin) + #Non-standard install directory, QTBUG-29859 DESTDIR = $$DESTDIR/android target.path = $${target.path}/android diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index ba0e6b001a..05d0bb4094 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -1,10 +1,5 @@ TARGET = qcocoa -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = QCocoaIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) - OBJECTIVE_SOURCES += main.mm \ qcocoaintegration.mm \ qcocoatheme.mm \ @@ -112,3 +107,8 @@ OTHER_FILES += cocoa.json # Window debug support #DEFINES += QT_COCOA_ENABLE_WINDOW_DEBUG + +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QCocoaIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm index 624220ae5e..d2bb3c9cfd 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm @@ -195,6 +195,8 @@ NSString *macSubrole(QAccessibleInterface *interface) QAccessible::State s = interface->state(); if (s.searchEdit) return NSAccessibilitySearchFieldSubrole; + if (s.passwordEdit) + return NSAccessibilitySecureTextFieldSubrole; return nil; } @@ -349,18 +351,23 @@ id getValueAttribute(QAccessibleInterface *interface) const QAccessible::Role qtrole = interface->role(); if (qtrole == QAccessible::EditableText) { if (QAccessibleTextInterface *textInterface = interface->textInterface()) { - // VoiceOver will read out the entire text string at once when returning - // text as a value. For large text edits the size of the returned string - // needs to be limited and text range attributes need to be used instead. - // NSTextEdit returns the first sentence as the value, Do the same here: + int begin = 0; int end = textInterface->characterCount(); - // ### call to textAfterOffset hangs. Booo! - //if (textInterface->characterCount() > 0) - // textInterface->textAfterOffset(0, QAccessible2::SentenceBoundary, &begin, &end); - - QString text = textInterface->text(begin, end); - //qDebug() << "text" << begin << end << text; + QString text; + if (interface->state().passwordEdit) { + // return round password replacement chars + text = QString(end, QChar(kBulletUnicode)); + } else { + // VoiceOver will read out the entire text string at once when returning + // text as a value. For large text edits the size of the returned string + // needs to be limited and text range attributes need to be used instead. + // NSTextEdit returns the first sentence as the value, Do the same here: + // ### call to textAfterOffset hangs. Booo! + //if (textInterface->characterCount() > 0) + // textInterface->textAfterOffset(0, QAccessible2::SentenceBoundary, &begin, &end); + text = textInterface->text(begin, end); + } return QCFString::toNSString(text); } } diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h index 5a199de4a5..934f68ad18 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.h +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h @@ -51,7 +51,11 @@ public: QPaintDevice *paintDevice() Q_DECL_OVERRIDE; void flush(QWindow *widget, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; +#ifndef QT_NO_OPENGL QImage toImage() const Q_DECL_OVERRIDE; +#else + QImage toImage() const; // No QPlatformBackingStore::toImage() for NO_OPENGL builds. +#endif void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE; bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE; void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 6bec6b191d..91d4b2706b 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -422,14 +422,18 @@ void QCocoaIntegration::updateScreens() } siblings << screen; } + + // Set virtual siblings list. All screens in mScreens are siblings, because we ignored the + // mirrors. Note that some of the screens we update the siblings list for here may be deleted + // below, but update anyway to keep the to-be-deleted screens out of the siblings list. + foreach (QCocoaScreen* screen, mScreens) + screen->setVirtualSiblings(siblings); + // Now the leftovers in remainingScreens are no longer current, so we can delete them. foreach (QCocoaScreen* screen, remainingScreens) { mScreens.removeOne(screen); destroyScreen(screen); } - // All screens in mScreens are siblings, because we ignored the mirrors. - foreach (QCocoaScreen* screen, mScreens) - screen->setVirtualSiblings(siblings); } QCocoaScreen *QCocoaIntegration::screenAtIndex(int index) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index eccc5230b5..5064d89585 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -75,8 +75,6 @@ public: inline NSMenu *nsMenu() const { return m_nativeMenu; } - inline NSMenuItem *nsMenuItem() const - { return m_nativeItem; } inline bool isVisible() const { return m_visible; } @@ -85,11 +83,9 @@ public: QList<QCocoaMenuItem *> items() const; QList<QCocoaMenuItem *> merged() const; - void setMenuBar(QCocoaMenuBar *menuBar); - QCocoaMenuBar *menuBar() const; - void setContainingMenuItem(QCocoaMenuItem *menuItem); - QCocoaMenuItem *containingMenuItem() const; + void setAttachedItem(NSMenuItem *item); + NSMenuItem *attachedItem() const; private: QCocoaMenuItem *itemOrNull(int index) const; @@ -97,13 +93,10 @@ private: QList<QCocoaMenuItem *> m_menuItems; NSMenu *m_nativeMenu; - NSMenuItem *m_nativeItem; - NSObject *m_delegate; + NSMenuItem *m_attachedItem; bool m_enabled; bool m_visible; quintptr m_tag; - QCocoaMenuBar *m_menuBar; - QCocoaMenuItem *m_containingMenuItem; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index ad491855ff..21a3799859 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -96,6 +96,28 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); return self; } +- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu +{ + Q_ASSERT(m_menu->nsMenu() == menu); + return m_menu->items().count(); +} + +- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel +{ + Q_UNUSED(index); + Q_ASSERT(m_menu->nsMenu() == menu); + if (shouldCancel) { + // TODO detach all submenus + return NO; + } + + QCocoaMenuItem *menuItem = reinterpret_cast<QCocoaMenuItem *>(item.tag); + if (m_menu->items().contains(menuItem)) { + if (QCocoaMenu *itemSubmenu = menuItem->menu()) + itemSubmenu->setAttachedItem(item); + } + return YES; +} - (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item { @@ -228,20 +250,16 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); QT_BEGIN_NAMESPACE QCocoaMenu::QCocoaMenu() : + m_attachedItem(0), m_enabled(true), m_visible(true), - m_tag(0), - m_menuBar(0), - m_containingMenuItem(0) + m_tag(0) { QMacAutoReleasePool pool; - m_delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this]; - m_nativeItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; m_nativeMenu = [[NSMenu alloc] initWithTitle:@"Untitled"]; [m_nativeMenu setAutoenablesItems:YES]; - m_nativeMenu.delegate = (QCocoaMenuDelegate *) m_delegate; - [m_nativeItem setSubmenu:m_nativeMenu]; + m_nativeMenu.delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this]; } QCocoaMenu::~QCocoaMenu() @@ -251,14 +269,11 @@ QCocoaMenu::~QCocoaMenu() SET_COCOA_MENU_ANCESTOR(item, 0); } - if (m_containingMenuItem) - m_containingMenuItem->clearMenu(this); - QMacAutoReleasePool pool; - [m_nativeItem setSubmenu:nil]; + NSObject *delegate = m_nativeMenu.delegate; + m_nativeMenu.delegate = nil; + [delegate release]; [m_nativeMenu release]; - [m_delegate release]; - [m_nativeItem release]; } void QCocoaMenu::setText(const QString &text) @@ -266,7 +281,6 @@ void QCocoaMenu::setText(const QString &text) QMacAutoReleasePool pool; QString stripped = qt_mac_removeAmpersandEscapes(text); [m_nativeMenu setTitle:QCFString::toNSString(stripped)]; - [m_nativeItem setTitle:QCFString::toNSString(stripped)]; } void QCocoaMenu::setMinimumWidth(int width) @@ -307,17 +321,13 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem * void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem) { - [item->nsItem() setTarget:m_delegate]; + item->nsItem().target = m_nativeMenu.delegate; if (!item->menu()) [item->nsItem() setAction:@selector(itemFired:)]; if (item->isMerged()) return; - if ([item->nsItem() menu]) { - qWarning("Menu item is already in a menu, remove it from the other menu first before inserting"); - return; - } // if the item we're inserting before is merged, skip along until // we find a non-merged real item to insert ahead of. while (beforeItem && beforeItem->isMerged()) { @@ -445,12 +455,11 @@ void QCocoaMenu::setEnabled(bool enabled) bool QCocoaMenu::isEnabled() const { - return [m_nativeItem isEnabled]; + return m_attachedItem ? [m_attachedItem isEnabled] : m_enabled; } void QCocoaMenu::setVisible(bool visible) { - [m_nativeItem setSubmenu:(visible ? m_nativeMenu : nil)]; m_visible = visible; } @@ -587,8 +596,6 @@ void QCocoaMenu::syncModalState(bool modal) if (!m_enabled) modal = true; - [m_nativeItem setEnabled:!modal]; - foreach (QCocoaMenuItem *item, m_menuItems) { if (item->menu()) { // recurse into submenus item->menu()->syncModalState(modal); @@ -599,25 +606,24 @@ void QCocoaMenu::syncModalState(bool modal) } } -void QCocoaMenu::setMenuBar(QCocoaMenuBar *menuBar) +void QCocoaMenu::setAttachedItem(NSMenuItem *item) { - m_menuBar = menuBar; - SET_COCOA_MENU_ANCESTOR(this, menuBar); -} + if (item == m_attachedItem) + return; -QCocoaMenuBar *QCocoaMenu::menuBar() const -{ - return m_menuBar; -} + if (m_attachedItem) + m_attachedItem.submenu = nil; + + m_attachedItem = item; + + if (m_attachedItem) + m_attachedItem.submenu = m_nativeMenu; -void QCocoaMenu::setContainingMenuItem(QCocoaMenuItem *menuItem) -{ - m_containingMenuItem = menuItem; } -QCocoaMenuItem *QCocoaMenu::containingMenuItem() const +NSMenuItem *QCocoaMenu::attachedItem() const { - return m_containingMenuItem; + return m_attachedItem; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h index d5f75abf34..e84da7aeb0 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.h +++ b/src/plugins/platforms/cocoa/qcocoamenubar.h @@ -71,10 +71,10 @@ private: static QCocoaMenuBar *findGlobalMenubar(); bool shouldDisable(QCocoaWindow *active) const; - void insertNativeMenu(QCocoaMenu *menu, QCocoaMenu *beforeMenu); - void removeNativeMenu(QCocoaMenu *menu); - QList<QCocoaMenu*> m_menus; + NSMenuItem *nativeItemForMenu(QCocoaMenu *menu) const; + + QList<QPointer<QCocoaMenu> > m_menus; NSMenu *m_nativeMenu; QCocoaWindow *m_window; }; diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index 1a516f874b..ac4d29fc52 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -51,7 +51,6 @@ static inline QCocoaMenuLoader *getMenuLoader() return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)]; } - QCocoaMenuBar::QCocoaMenuBar() : m_window(0) { @@ -68,11 +67,20 @@ QCocoaMenuBar::~QCocoaMenuBar() #ifdef QT_COCOA_ENABLE_MENU_DEBUG qDebug() << "~QCocoaMenuBar" << this; #endif + foreach (QCocoaMenu *menu, m_menus) { + if (!menu) + continue; + NSMenuItem *item = nativeItemForMenu(menu); + if (menu->attachedItem() == item) + menu->setAttachedItem(nil); + } + [m_nativeMenu release]; static_menubars.removeOne(this); if (m_window && m_window->menubar() == this) { m_window->setMenubar(0); + // Delete the children first so they do not cause // the native menu items to be hidden after // the menu bar was updated @@ -81,24 +89,6 @@ QCocoaMenuBar::~QCocoaMenuBar() } } -void QCocoaMenuBar::insertNativeMenu(QCocoaMenu *menu, QCocoaMenu *beforeMenu) -{ - QMacAutoReleasePool pool; - - if (beforeMenu) { - NSUInteger nativeIndex = [m_nativeMenu indexOfItem:beforeMenu->nsMenuItem()]; - [m_nativeMenu insertItem: menu->nsMenuItem() atIndex: nativeIndex]; - } else { - [m_nativeMenu addItem: menu->nsMenuItem()]; - } - - menu->setMenuBar(this); - syncMenu(static_cast<QPlatformMenu *>(menu)); - if (menu->isVisible()) { - [m_nativeMenu setSubmenu: menu->nsMenu() forItem: menu->nsMenuItem()]; - } -} - void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *before) { QCocoaMenu *menu = static_cast<QCocoaMenu *>(platformMenu); @@ -107,31 +97,40 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor qDebug() << "QCocoaMenuBar" << this << "insertMenu" << menu << "before" << before; #endif - if (m_menus.contains(menu)) { + if (m_menus.contains(QPointer<QCocoaMenu>(menu))) { qWarning("This menu already belongs to the menubar, remove it first"); return; } - if (beforeMenu && !m_menus.contains(beforeMenu)) { + if (beforeMenu && !m_menus.contains(QPointer<QCocoaMenu>(beforeMenu))) { qWarning("The before menu does not belong to the menubar"); return; } - m_menus.insert(beforeMenu ? m_menus.indexOf(beforeMenu) : m_menus.size(), menu); - if (!menu->menuBar()) - insertNativeMenu(menu, beforeMenu); - if (m_window && m_window->window()->isActive()) - updateMenuBarImmediately(); -} + int insertionIndex = beforeMenu ? m_menus.indexOf(beforeMenu) : m_menus.size(); + m_menus.insert(insertionIndex, menu); + + { + QMacAutoReleasePool pool; + NSMenuItem *item = [[[NSMenuItem alloc] init] autorelease]; + item.tag = reinterpret_cast<NSInteger>(menu); + + if (beforeMenu) { + // QMenuBar::toNSMenu() exposes the native menubar and + // the user could have inserted its own items in there. + // Same remark applies to removeMenu(). + NSMenuItem *beforeItem = nativeItemForMenu(beforeMenu); + NSInteger nativeIndex = [m_nativeMenu indexOfItem:beforeItem]; + [m_nativeMenu insertItem:item atIndex:nativeIndex]; + } else { + [m_nativeMenu addItem:item]; + } + } -void QCocoaMenuBar::removeNativeMenu(QCocoaMenu *menu) -{ - QMacAutoReleasePool pool; + syncMenu(menu); - if (menu->menuBar() == this) - menu->setMenuBar(0); - NSUInteger realIndex = [m_nativeMenu indexOfItem:menu->nsMenuItem()]; - [m_nativeMenu removeItemAtIndex: realIndex]; + if (m_window && m_window->window()->isActive()) + updateMenuBarImmediately(); } void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu) @@ -141,8 +140,17 @@ void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu) qWarning("Trying to remove a menu that does not belong to the menubar"); return; } + + NSMenuItem *item = nativeItemForMenu(menu); + if (menu->attachedItem() == item) + menu->setAttachedItem(nil); m_menus.removeOne(menu); - removeNativeMenu(menu); + + QMacAutoReleasePool pool; + + // See remark in insertMenu(). + NSInteger nativeIndex = [m_nativeMenu indexOfItem:item]; + [m_nativeMenu removeItemAtIndex:nativeIndex]; } void QCocoaMenuBar::syncMenu(QPlatformMenu *menu) @@ -164,7 +172,16 @@ void QCocoaMenuBar::syncMenu(QPlatformMenu *menu) break; } } - [cocoaMenu->nsMenuItem() setHidden:shouldHide]; + + nativeItemForMenu(cocoaMenu).hidden = shouldHide; +} + +NSMenuItem *QCocoaMenuBar::nativeItemForMenu(QCocoaMenu *menu) const +{ + if (!menu) + return nil; + + return [m_nativeMenu itemWithTag:reinterpret_cast<NSInteger>(menu)]; } void QCocoaMenuBar::handleReparent(QWindow *newParentWindow) @@ -291,24 +308,16 @@ void QCocoaMenuBar::updateMenuBarImmediately() qDebug() << "QCocoaMenuBar" << "updateMenuBarImmediately" << cw; #endif bool disableForModal = mb->shouldDisable(cw); - // force a sync? - foreach (QCocoaMenu *m, mb->m_menus) { - mb->syncMenu(m); - m->syncModalState(disableForModal); - } - // reparent shared menu items if necessary. - // We browse the list in reverse order to be sure that the next items are redrawn before the current ones, - // in this way we are sure that "beforeMenu" (see below) is part of the native menu before "m" is redraw - for (int i = mb->m_menus.size() - 1; i >= 0; i--) { - QCocoaMenu *m = mb->m_menus.at(i); - QCocoaMenuBar *menuBar = m->menuBar(); - if (menuBar != mb) { - QCocoaMenu *beforeMenu = i < (mb->m_menus.size() - 1) ? mb->m_menus.at(i + 1) : 0; - if (menuBar) - menuBar->removeNativeMenu(m); - mb->insertNativeMenu(m, beforeMenu); - } + foreach (QCocoaMenu *menu, mb->m_menus) { + if (!menu) + continue; + NSMenuItem *item = mb->nativeItemForMenu(menu); + menu->setAttachedItem(item); + SET_COCOA_MENU_ANCESTOR(menu, mb); + // force a sync? + mb->syncMenu(menu); + menu->syncModalState(disableForModal); } QCocoaMenuLoader *loader = getMenuLoader(); diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h index 289f38fd18..ada4b13df1 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.h +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h @@ -40,17 +40,10 @@ //#define QT_COCOA_ENABLE_MENU_DEBUG -#ifdef __OBJC__ -#define QT_FORWARD_DECLARE_OBJC_CLASS(__KLASS__) @class __KLASS__ -#else -#define QT_FORWARD_DECLARE_OBJC_CLASS(__KLASS__) typedef struct objc_object __KLASS__ -#endif - -QT_FORWARD_DECLARE_OBJC_CLASS(NSMenuItem); -QT_FORWARD_DECLARE_OBJC_CLASS(NSMenu); -QT_FORWARD_DECLARE_OBJC_CLASS(NSObject); -QT_FORWARD_DECLARE_OBJC_CLASS(NSView); - +Q_FORWARD_DECLARE_OBJC_CLASS(NSMenuItem); +Q_FORWARD_DECLARE_OBJC_CLASS(NSMenu); +Q_FORWARD_DECLARE_OBJC_CLASS(NSObject); +Q_FORWARD_DECLARE_OBJC_CLASS(NSView); QT_BEGIN_NAMESPACE @@ -94,7 +87,6 @@ public: inline bool isSeparator() const { return m_isSeparator; } QCocoaMenu *menu() const { return m_menu; } - void clearMenu(QCocoaMenu *menu); MenuRole effectiveRole() const; private: @@ -106,7 +98,7 @@ private: QString m_text; bool m_textSynced; QIcon m_icon; - QCocoaMenu *m_menu; + QPointer<QCocoaMenu> m_menu; bool m_isVisible; bool m_enabled; bool m_isSeparator; diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 0f551bcd7d..e274448620 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -134,15 +134,12 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu) if (m_menu) { if (COCOA_MENU_ANCESTOR(m_menu) == this) SET_COCOA_MENU_ANCESTOR(m_menu, 0); - if (m_menu->containingMenuItem() == this) - m_menu->setContainingMenuItem(0); } QMacAutoReleasePool pool; m_menu = static_cast<QCocoaMenu *>(menu); if (m_menu) { SET_COCOA_MENU_ANCESTOR(m_menu, this); - m_menu->setContainingMenuItem(this); } else { // we previously had a menu, but no longer // clear out our item so the nexy sync() call builds a new one @@ -151,12 +148,6 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu) } } -void QCocoaMenuItem::clearMenu(QCocoaMenu *menu) -{ - if (menu == m_menu) - m_menu = 0; -} - void QCocoaMenuItem::setVisible(bool isVisible) { m_isVisible = isVisible; @@ -218,14 +209,6 @@ NSMenuItem *QCocoaMenuItem::sync() m_native = nil; } - if (m_menu) { - if (m_native != m_menu->nsMenuItem()) { - [m_native release]; - m_native = [m_menu->nsMenuItem() retain]; - [m_native setTag:reinterpret_cast<NSInteger>(this)]; - } - } - if ((m_role != NoRole && !m_textSynced) || m_merged) { NSMenuItem *mergeItem = nil; QCocoaMenuLoader *loader = getMenuLoader(); diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm index 93f8b2ba6f..48f2f72b7e 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm @@ -143,6 +143,7 @@ static QMacPaletteMap mac_widget_colors[] = { QMacPaletteMap(QPlatformTheme::LabelPalette, kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive), QMacPaletteMap(QPlatformTheme::GroupBoxPalette, kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive), QMacPaletteMap(QPlatformTheme::MenuPalette, kThemeTextColorMenuItemActive, kThemeTextColorMenuItemDisabled), + QMacPaletteMap(QPlatformTheme::MenuBarPalette, kThemeTextColorMenuItemActive, kThemeTextColorMenuItemDisabled), //### TODO: The zeros below gives white-on-black text. QMacPaletteMap(QPlatformTheme::TextEditPalette, 0, 0), QMacPaletteMap(QPlatformTheme::TextLineEditPalette, 0, 0), @@ -167,7 +168,8 @@ QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes() pal.setColor(QPalette::Disabled, QPalette::WindowText, qc); pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc); } - if (mac_widget_colors[i].paletteRole == QPlatformTheme::MenuPalette) { + if (mac_widget_colors[i].paletteRole == QPlatformTheme::MenuPalette + || mac_widget_colors[i].paletteRole == QPlatformTheme::MenuBarPalette) { qc = qt_mac_colorForTheme(kThemeBrushMenuBackground); pal.setBrush(QPalette::Background, qc); qc = qt_mac_colorForThemeTextColor(kThemeTextColorMenuItemActive); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 00cb43c940..e4cd57a115 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -409,6 +409,7 @@ QCocoaWindow::~QCocoaWindow() #endif QMacAutoReleasePool pool; + [m_nsWindow makeFirstResponder:nil]; [m_nsWindow setContentView:nil]; [m_nsWindow.helper detachFromPlatformWindow]; if (m_isNSWindowChild) { @@ -990,7 +991,15 @@ void QCocoaWindow::raise() [parentNSWindow removeChildWindow:m_nsWindow]; [parentNSWindow addChildWindow:m_nsWindow ordered:NSWindowAbove]; } else { - [m_nsWindow orderFront: m_nsWindow]; + { + // Clean up autoreleased temp objects from orderFront immediately. + // Failure to do so has been observed to cause leaks also beyond any outer + // autorelease pool (for example around a complete QWindow + // construct-show-raise-hide-delete cyle), counter to expected autoreleasepool + // behavior. + QMacAutoReleasePool pool; + [m_nsWindow orderFront: m_nsWindow]; + } static bool raiseProcess = qt_mac_resolveOption(true, "QT_MAC_SET_RAISE_PROCESS"); if (raiseProcess) { ProcessSerialNumber psn; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 0d80333e65..90a7004938 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -356,6 +356,8 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; if (m_platformWindow->m_nsWindow && geometry == m_platformWindow->geometry()) return; + const bool isResize = geometry.size() != m_platformWindow->geometry().size(); + // It can happen that self.window is nil (if we are changing // styleMask from/to borderless and content view is being re-parented) // - this results in an invalid coordinates. @@ -385,7 +387,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; // calles, which Qt and Qt applications do not excpect. if (!m_platformWindow->m_inSetGeometry) QWindowSystemInterface::flushWindowSystemEvents(); - else + else if (isResize) m_backingStore = 0; } } @@ -1405,6 +1407,10 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) momentumPhase == NSEventPhaseEnded || momentumPhase == NSEventPhaseCancelled) { ph = Qt::ScrollEnd; m_scrolling = false; + } else if (phase == NSEventPhaseNone && momentumPhase == NSEventPhaseNone) { + ph = Qt::NoScrollPhase; + if (!QGuiApplicationPrivate::scrollNoPhaseAllowed) + ph = Qt::ScrollUpdate; } QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers, ph, source); diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm index edd1d656f0..000a9c46c8 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm @@ -470,7 +470,6 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va d->embedFonts = value.toBool(); break; case PPK_Resolution: { - // TODO It appears the old code didn't actually set the resolution??? Can we delete all this??? int bestResolution = 0; int dpi = value.toInt(); int bestDistance = INT_MAX; @@ -486,7 +485,17 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va } } } - PMSessionValidatePageFormat(d->session(), d->format(), kPMDontWantBoolean); + PMResolution resolution; + resolution.hRes = resolution.vRes = bestResolution; + if (PMPrinterSetOutputResolution(d->m_printDevice->macPrinter(), d->settings(), &resolution) == noErr) { + // Setting the resolution succeeded. + // Now try to read the actual resolution selected by the OS. + if (PMPrinterGetOutputResolution(d->m_printDevice->macPrinter(), d->settings(), &d->resolution) != noErr) { + // Reading the resolution somehow failed; d->resolution is in undefined state. + // So use the value which was acceptable to PMPrinterSetOutputResolution. + d->resolution = resolution; + } + } break; } case PPK_CollateCopies: diff --git a/src/plugins/platforms/direct2d/direct2d.pro b/src/plugins/platforms/direct2d/direct2d.pro index 8f2ccc3aa6..005a4da6db 100644 --- a/src/plugins/platforms/direct2d/direct2d.pro +++ b/src/plugins/platforms/direct2d/direct2d.pro @@ -1,10 +1,5 @@ TARGET = qdirect2d -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = QWindowsDirect2DIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) - QT *= core-private QT *= gui-private QT *= platformsupport-private @@ -40,3 +35,8 @@ HEADERS += \ qwindowsdirect2dwindow.h OTHER_FILES += direct2d.json + +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QWindowsDirect2DIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp index 40709fc3d0..f12649e55e 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp @@ -63,6 +63,10 @@ QWindowsDirect2DPaintDevice::QWindowsDirect2DPaintDevice(QWindowsDirect2DBitmap { } +QWindowsDirect2DPaintDevice::~QWindowsDirect2DPaintDevice() +{ +} + QPaintEngine *QWindowsDirect2DPaintDevice::paintEngine() const { Q_D(const QWindowsDirect2DPaintDevice); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h index 702fd4178c..08fcbba015 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h @@ -50,6 +50,8 @@ class QWindowsDirect2DPaintDevice : public QPaintDevice public: QWindowsDirect2DPaintDevice(QWindowsDirect2DBitmap *bitmap, QInternal::PaintDeviceFlags flags, QWindowsDirect2DPaintEngine::Flags paintFlags = QWindowsDirect2DPaintEngine::NoFlag); + ~QWindowsDirect2DPaintDevice(); + QPaintEngine *paintEngine() const Q_DECL_OVERRIDE; int devType() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/directfb/directfb.pro b/src/plugins/platforms/directfb/directfb.pro index 89d8d42cea..5c81e0283a 100644 --- a/src/plugins/platforms/directfb/directfb.pro +++ b/src/plugins/platforms/directfb/directfb.pro @@ -1,10 +1,5 @@ TARGET = qdirectfb -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = QDirectFbIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) - QT += core-private gui-private platformsupport-private LIBS += $$QMAKE_LIBS_DIRECTFB @@ -51,3 +46,8 @@ contains(QT_CONFIG, directfb_egl) { CONFIG += qpa/genericunixfontdatabase OTHER_FILES += directfb.json + +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QDirectFbIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro index 2026b6a6c6..e2ebf9f7ee 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro @@ -1,9 +1,5 @@ TARGET = qeglfs-brcm-integration -PLUGIN_TYPE = egldeviceintegrations -PLUGIN_CLASS_NAME = QEglFSBrcmIntegrationPlugin -load(qt_plugin) - QT += core-private gui-private platformsupport-private eglfs_device_lib-private INCLUDEPATH += $$PWD/../.. @@ -21,3 +17,7 @@ SOURCES += $$PWD/qeglfsbrcmmain.cpp \ HEADERS += $$PWD/qeglfsbrcmintegration.h OTHER_FILES += $$PWD/eglfs_brcm.json + +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSBrcmIntegrationPlugin +load(qt_plugin) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro index e53793ce54..12ae0a13b1 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro @@ -1,9 +1,5 @@ TARGET = qeglfs-kms-integration -PLUGIN_TYPE = egldeviceintegrations -PLUGIN_CLASS_NAME = QEglFSKmsIntegrationPlugin -load(qt_plugin) - QT += core-private gui-private platformsupport-private eglfs_device_lib-private INCLUDEPATH += $$PWD/../.. @@ -29,3 +25,7 @@ HEADERS += $$PWD/qeglfskmsintegration.h \ $$PWD/qeglfskmscursor.h OTHER_FILES += $$PWD/eglfs_kms.json + +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSKmsIntegrationPlugin +load(qt_plugin) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro index 393ddd14a5..1932f861b9 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro @@ -1,9 +1,5 @@ TARGET = qeglfs-kms-egldevice-integration -PLUGIN_TYPE = egldeviceintegrations -PLUGIN_CLASS_NAME = QEglFSKmsEglDeviceIntegrationPlugin -load(qt_plugin) - QT += core-private gui-private platformsupport-private eglfs_device_lib-private INCLUDEPATH += $$PWD/../.. @@ -21,3 +17,7 @@ HEADERS += $$PWD/qeglfskmsegldeviceintegration.h OTHER_FILES += $$PWD/eglfs_kms_egldevice.json LIBS += -ldrm + +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSKmsEglDeviceIntegrationPlugin +load(qt_plugin) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp index f7450708ab..5c7b9fe96d 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp @@ -301,8 +301,13 @@ void QEglFSKmsEglDeviceIntegration::waitForVSync(QPlatformSurface *) const if (currentMode) drmModeFreeCrtc(currentMode); if (alreadySet) { - qCDebug(qLcEglfsKmsDebug, "Mode already set"); - return; + // Maybe detecting the DPMS mode could help here, but there are no properties + // exposed on the connector apparently. So rely on an env var for now. + static bool alwaysDoSet = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ALWAYS_SET_MODE"); + if (!alwaysDoSet) { + qCDebug(qLcEglfsKmsDebug, "Mode already set"); + return; + } } qCDebug(qLcEglfsKmsDebug, "Setting mode"); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro index 33f219db96..7fc4568ae3 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro @@ -1,9 +1,5 @@ TARGET = qeglfs-mali-integration -PLUGIN_TYPE = egldeviceintegrations -PLUGIN_CLASS_NAME = QEglFSMaliIntegrationPlugin -load(qt_plugin) - QT += core-private gui-private platformsupport-private eglfs_device_lib-private # Avoid X11 header collision @@ -19,3 +15,7 @@ SOURCES += $$PWD/qeglfsmalimain.cpp \ HEADERS += $$PWD/qeglfsmaliintegration.h OTHER_FILES += $$PWD/eglfs_mali.json + +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSMaliIntegrationPlugin +load(qt_plugin) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro index fc0533127c..6fac2f529a 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro @@ -1,9 +1,5 @@ TARGET = qeglfs-viv-integration -PLUGIN_TYPE = egldeviceintegrations -PLUGIN_CLASS_NAME = QEglFSVivIntegrationPlugin -load(qt_plugin) - QT += core-private gui-private platformsupport-private eglfs_device_lib-private INCLUDEPATH += $$PWD/../.. @@ -18,3 +14,7 @@ SOURCES += $$PWD/qeglfsvivmain.cpp \ HEADERS += $$PWD/qeglfsvivintegration.h OTHER_FILES += $$PWD/eglfs_viv.json + +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSVivIntegrationPlugin +load(qt_plugin) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro index 26b6a2e9ea..44f75c40e0 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro @@ -1,9 +1,5 @@ TARGET = qeglfs-viv-wl-integration -PLUGIN_TYPE = egldeviceintegrations -PLUGIN_CLASS_NAME = QEglFSVivWaylandIntegrationPlugin -load(qt_plugin) - QT += core-private gui-private platformsupport-private eglfs_device_lib-private INCLUDEPATH += $$PWD/../.. @@ -21,3 +17,7 @@ OTHER_FILES += $$PWD/eglfs_viv_wl.json CONFIG += link_pkgconfig PKGCONFIG_PRIVATE += wayland-server + +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSVivWaylandIntegrationPlugin +load(qt_plugin) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro index 86fefac8aa..83f0c74910 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro @@ -1,9 +1,5 @@ TARGET = qeglfs-x11-integration -PLUGIN_TYPE = egldeviceintegrations -PLUGIN_CLASS_NAME = QEglFSX11IntegrationPlugin -load(qt_plugin) - QT += core-private gui-private platformsupport-private eglfs_device_lib-private # Avoid X11 header collision @@ -21,3 +17,7 @@ SOURCES += $$PWD/qeglfsx11main.cpp \ HEADERS += $$PWD/qeglfsx11integration.h OTHER_FILES += $$PWD/eglfs_x11.json + +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSX11IntegrationPlugin +load(qt_plugin) diff --git a/src/plugins/platforms/eglfs/eglfs-plugin.pro b/src/plugins/platforms/eglfs/eglfs-plugin.pro index 0f493fdc01..a628cdccd9 100644 --- a/src/plugins/platforms/eglfs/eglfs-plugin.pro +++ b/src/plugins/platforms/eglfs/eglfs-plugin.pro @@ -1,12 +1,12 @@ TARGET = qeglfs -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = QEglFSIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) - QT += platformsupport-private eglfs_device_lib-private SOURCES += $$PWD/qeglfsmain.cpp OTHER_FILES += $$PWD/eglfs.json + +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QEglFSIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/eglfs/eglfs_device_lib.pro b/src/plugins/platforms/eglfs/eglfs_device_lib.pro index 4fe2ce4897..f784020fb6 100644 --- a/src/plugins/platforms/eglfs/eglfs_device_lib.pro +++ b/src/plugins/platforms/eglfs/eglfs_device_lib.pro @@ -6,8 +6,6 @@ TARGET = QtEglDeviceIntegration CONFIG += no_module_headers internal_module -load(qt_module) - QT += core-private gui-private platformsupport-private LIBS += $$QMAKE_LIBS_DYNLOAD @@ -52,3 +50,5 @@ INCLUDEPATH += $$PWD CONFIG += egl qpa/genericunixfontdatabase !contains(DEFINES, QT_NO_CURSOR): RESOURCES += $$PWD/cursor.qrc + +load(qt_module) diff --git a/src/plugins/platforms/haiku/haiku.pro b/src/plugins/platforms/haiku/haiku.pro index 87f31997a3..ea5bb632db 100644 --- a/src/plugins/platforms/haiku/haiku.pro +++ b/src/plugins/platforms/haiku/haiku.pro @@ -1,7 +1,4 @@ TARGET = qhaiku -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = QHaikuIntegrationPlugin -load(qt_plugin) QT += platformsupport-private core-private gui-private @@ -40,3 +37,7 @@ LIBS += -lbe OTHER_FILES += haiku.json include (../../../platformsupport/fontdatabases/fontdatabases.pri) + +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QHaikuIntegrationPlugin +load(qt_plugin) diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index bf7849b740..545db8c093 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -1,10 +1,5 @@ TARGET = qios -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = QIOSIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) - QT += core-private gui-private platformsupport-private LIBS += -framework Foundation -framework UIKit -framework QuartzCore -framework AssetsLibrary @@ -59,3 +54,8 @@ HEADERS = \ OTHER_FILES = \ quiview_textinput.mm \ quiview_accessibility.mm + +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QIOSIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/linuxfb/linuxfb.pro b/src/plugins/platforms/linuxfb/linuxfb.pro index 389d45c29c..b5de192346 100644 --- a/src/plugins/platforms/linuxfb/linuxfb.pro +++ b/src/plugins/platforms/linuxfb/linuxfb.pro @@ -1,10 +1,5 @@ TARGET = qlinuxfb -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = QLinuxFbIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) - QT += core-private gui-private platformsupport-private SOURCES = main.cpp qlinuxfbintegration.cpp qlinuxfbscreen.cpp @@ -13,3 +8,8 @@ HEADERS = qlinuxfbintegration.h qlinuxfbscreen.h CONFIG += qpa/genericunixfontdatabase OTHER_FILES += linuxfb.json + +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QLinuxFbIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/minimal/minimal.pro b/src/plugins/platforms/minimal/minimal.pro index 3ed4d2cdde..d6914026ae 100644 --- a/src/plugins/platforms/minimal/minimal.pro +++ b/src/plugins/platforms/minimal/minimal.pro @@ -1,10 +1,5 @@ TARGET = qminimal -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = QMinimalIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) - QT += core-private gui-private platformsupport-private SOURCES = main.cpp \ @@ -14,3 +9,8 @@ HEADERS = qminimalintegration.h \ qminimalbackingstore.h OTHER_FILES += minimal.json + +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QMinimalIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/minimalegl/minimalegl.pro b/src/plugins/platforms/minimalegl/minimalegl.pro index e78dcb8bc5..ac67249591 100644 --- a/src/plugins/platforms/minimalegl/minimalegl.pro +++ b/src/plugins/platforms/minimalegl/minimalegl.pro @@ -1,10 +1,5 @@ TARGET = qminimalegl -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = QMinimalEglIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) - QT += core-private gui-private platformsupport-private #DEFINES += QEGL_EXTRA_DEBUG @@ -29,3 +24,8 @@ CONFIG += egl qpa/genericunixfontdatabase OTHER_FILES += \ minimalegl.json + +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QMinimalEglIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/mirclient/mirclient.pro b/src/plugins/platforms/mirclient/mirclient.pro index 0851e8d719..d5d35f1632 100644 --- a/src/plugins/platforms/mirclient/mirclient.pro +++ b/src/plugins/platforms/mirclient/mirclient.pro @@ -1,10 +1,4 @@ -TARGET = mirclient -TEMPLATE = lib - -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = MirServerIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) +TARGET = qmirclient QT += core-private gui-private platformsupport-private dbus @@ -47,3 +41,8 @@ HEADERS = \ qmirclientscreen.h \ qmirclienttheme.h \ qmirclientwindow.h + +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = MirServerIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/offscreen/offscreen.pro b/src/plugins/platforms/offscreen/offscreen.pro index 94eeac6acc..999550a7e1 100644 --- a/src/plugins/platforms/offscreen/offscreen.pro +++ b/src/plugins/platforms/offscreen/offscreen.pro @@ -1,10 +1,5 @@ TARGET = qoffscreen -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = QOffscreenIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) - QT += core-private gui-private platformsupport-private SOURCES = main.cpp \ @@ -25,3 +20,8 @@ contains(QT_CONFIG, xlib):contains(QT_CONFIG, opengl):!contains(QT_CONFIG, openg } else { SOURCES += qoffscreenintegration_dummy.cpp } + +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QOffscreenIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/openwfd/openwf.pro b/src/plugins/platforms/openwfd/openwf.pro index 38bac057bd..152e4f57d7 100644 --- a/src/plugins/platforms/openwfd/openwf.pro +++ b/src/plugins/platforms/openwfd/openwf.pro @@ -1,10 +1,5 @@ TARGET = qopenwf -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = QOpenWFDIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) - QT += core-private gui-private platformsupport-private CONFIG += qpa/genericunixfontdatabase @@ -38,3 +33,7 @@ SOURCES += \ LIBS += -lWFD -lgbm -lGLESv2 -lEGL +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QOpenWFDIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/windows/accessible/comutils.cpp b/src/plugins/platforms/windows/accessible/comutils.cpp index 8ad732b0e7..acfab97899 100644 --- a/src/plugins/platforms/windows/accessible/comutils.cpp +++ b/src/plugins/platforms/windows/accessible/comutils.cpp @@ -58,15 +58,15 @@ static DATE QDateTimeToDATE(const QDateTime &dt) QDate date = dt.date(); QTime time = dt.time(); if (date.isValid() && !date.isNull()) { - stime.wDay = date.day(); - stime.wMonth = date.month(); - stime.wYear = date.year(); + stime.wDay = WORD(date.day()); + stime.wMonth = WORD(date.month()); + stime.wYear = WORD(date.year()); } if (time.isValid() && !time.isNull()) { - stime.wMilliseconds = time.msec(); - stime.wSecond = time.second(); - stime.wMinute = time.minute(); - stime.wHour = time.hour(); + stime.wMilliseconds = WORD(time.msec()); + stime.wSecond = WORD(time.second()); + stime.wMinute = WORD(time.minute()); + stime.wHour = WORD(time.hour()); } double vtime; @@ -92,8 +92,8 @@ bool QVariant2VARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeN proptype = QVariant::Double; } if (proptype != QVariant::Invalid && proptype != QVariant::UserType && proptype != qvar.type()) { - if (qvar.canConvert(proptype)) - qvar.convert(proptype); + if (qvar.canConvert(int(proptype))) + qvar.convert(int(proptype)); else qvar = QVariant(proptype); } @@ -272,348 +272,6 @@ bool QVariant2VARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeN } } break; -#if 0 // not a value with min/max semantics - case QVariant::Font: - if (out && arg.vt == (VT_DISPATCH|VT_BYREF)) { - if (*arg.ppdispVal) - (*arg.ppdispVal)->Release(); - *arg.ppdispVal = QFontToIFont(qvariant_cast<QFont>(qvar)); - } else { - arg.vt = VT_DISPATCH; - arg.pdispVal = QFontToIFont(qvariant_cast<QFont>(qvar)); - if (out) { - arg.ppdispVal = new IDispatch*(arg.pdispVal); - arg.vt |= VT_BYREF; - } - } - break; - case QVariant::Pixmap: - if (out && arg.vt == (VT_DISPATCH|VT_BYREF)) { - if (*arg.ppdispVal) - (*arg.ppdispVal)->Release(); - *arg.ppdispVal = QPixmapToIPicture(qvariant_cast<QPixmap>(qvar)); - } else { - arg.vt = VT_DISPATCH; - arg.pdispVal = QPixmapToIPicture(qvariant_cast<QPixmap>(qvar)); - if (out) { - arg.ppdispVal = new IDispatch*(arg.pdispVal); - arg.vt |= VT_BYREF; - } - } - break; - case QVariant::Cursor: - { -#ifndef QT_NO_CURSOR - int shape = qvariant_cast<QCursor>(qvar).shape(); - if (out && (arg.vt & VT_BYREF)) { - switch (arg.vt & ~VT_BYREF) { - case VT_I4: - *arg.plVal = shape; - break; - case VT_I2: - *arg.piVal = shape; - break; - case VT_UI4: - *arg.pulVal = shape; - break; - case VT_UI2: - *arg.puiVal = shape; - break; - case VT_INT: - *arg.pintVal = shape; - break; - case VT_UINT: - *arg.puintVal = shape; - break; - } - } else { - arg.vt = VT_I4; - arg.lVal = shape; - if (out) { - arg.plVal = new long(arg.lVal); - arg.vt |= VT_BYREF; - } - } -#endif - } - break; - - case QVariant::List: - { - const QList<QVariant> list = qvar.toList(); - const int count = list.count(); - VARTYPE vt = VT_VARIANT; - QVariant::Type listType = QVariant::LastType; // == QVariant - if (!typeName.isEmpty() && typeName.startsWith("QList<")) { - const QByteArray listTypeName = typeName.mid(6, typeName.length() - 7); // QList<int> -> int - listType = QVariant::nameToType(listTypeName); - } - - VARIANT variant; - void *pElement = &variant; - switch (listType) { - case QVariant::Int: - vt = VT_I4; - pElement = &variant.lVal; - break; - case QVariant::Double: - vt = VT_R8; - pElement = &variant.dblVal; - break; - case QVariant::DateTime: - vt = VT_DATE; - pElement = &variant.date; - break; - case QVariant::Bool: - vt = VT_BOOL; - pElement = &variant.boolVal; - break; - case QVariant::LongLong: -#if !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400 - vt = VT_I8; - pElement = &variant.llVal; -#else - vt = VT_CY; - pElement = &variant.cyVal; -#endif - break; - default: - break; - } - SAFEARRAY *array = 0; - bool is2D = false; - // If the first element in the array is a list the whole list is - // treated as a 2D array. The column count is taken from the 1st element. - if (count) { - QVariantList col = list.at(0).toList(); - int maxColumns = col.count(); - if (maxColumns) { - is2D = true; - SAFEARRAYBOUND rgsabound[2] = { {0} }; - rgsabound[0].cElements = count; - rgsabound[1].cElements = maxColumns; - array = SafeArrayCreate(VT_VARIANT, 2, rgsabound); - LONG rgIndices[2]; - for (LONG i = 0; i < count; ++i) { - rgIndices[0] = i; - QVariantList columns = list.at(i).toList(); - int columnCount = qMin(maxColumns, columns.count()); - for (LONG j = 0; j < columnCount; ++j) { - QVariant elem = columns.at(j); - VariantInit(&variant); - QVariant2VARIANT(elem, variant, elem.typeName()); - rgIndices[1] = j; - SafeArrayPutElement(array, rgIndices, pElement); - clearVARIANT(&variant); - } - } - - } - } - if (!is2D) { - array = SafeArrayCreateVector(vt, 0, count); - for (LONG index = 0; index < count; ++index) { - QVariant elem = list.at(index); - if (listType != QVariant::LastType) - elem.convert(listType); - VariantInit(&variant); - QVariant2VARIANT(elem, variant, elem.typeName()); - SafeArrayPutElement(array, &index, pElement); - clearVARIANT(&variant); - } - } - if (out && arg.vt == (VT_ARRAY|vt|VT_BYREF)) { - if (*arg.pparray) - SafeArrayDestroy(*arg.pparray); - *arg.pparray = array; - } else { - arg.vt = VT_ARRAY|vt; - arg.parray = array; - if (out) { - arg.pparray = new SAFEARRAY*(arg.parray); - arg.vt |= VT_BYREF; - } - } - } - break; - - case QVariant::StringList: - { - const QStringList list = qvar.toStringList(); - const int count = list.count(); - SAFEARRAY *array = SafeArrayCreateVector(VT_BSTR, 0, count); - for (LONG index = 0; index < count; ++index) { - QString elem = list.at(index); - BSTR bstr = QStringToBSTR(elem); - SafeArrayPutElement(array, &index, bstr); - SysFreeString(bstr); - } - - if (out && arg.vt == (VT_ARRAY|VT_BSTR|VT_BYREF)) { - if (*arg.pparray) - SafeArrayDestroy(*arg.pparray); - *arg.pparray = array; - } else { - arg.vt = VT_ARRAY|VT_BSTR; - arg.parray = array; - if (out) { - arg.pparray = new SAFEARRAY*(arg.parray); - arg.vt |= VT_BYREF; - } - } - } - break; - - case QVariant::ByteArray: - { - const QByteArray bytes = qvar.toByteArray(); - const uint count = bytes.count(); - SAFEARRAY *array = SafeArrayCreateVector(VT_UI1, 0, count); - if (count) { - const char *data = bytes.constData(); - char *dest; - SafeArrayAccessData(array, (void **)&dest); - memcpy(dest, data, count); - SafeArrayUnaccessData(array); - } - - if (out && arg.vt == (VT_ARRAY|VT_UI1|VT_BYREF)) { - if (*arg.pparray) - SafeArrayDestroy(*arg.pparray); - *arg.pparray = array; - } else { - arg.vt = VT_ARRAY|VT_UI1; - arg.parray = array; - if (out) { - arg.pparray = new SAFEARRAY*(arg.parray); - arg.vt |= VT_BYREF; - } - } - } - break; - -#ifdef QAX_SERVER - case QVariant::Rect: - case QVariant::Size: - case QVariant::Point: - { - typedef HRESULT(WINAPI* PGetRecordInfoFromTypeInfo)(ITypeInfo *, IRecordInfo **); - static PGetRecordInfoFromTypeInfo pGetRecordInfoFromTypeInfo = 0; - static bool resolved = false; - if (!resolved) { - QSystemLibrary oleaut32(QLatin1String("oleaut32")); - pGetRecordInfoFromTypeInfo = (PGetRecordInfoFromTypeInfo)oleaut32.resolve("GetRecordInfoFromTypeInfo"); - resolved = true; - } - if (!pGetRecordInfoFromTypeInfo) - break; - - ITypeInfo *typeInfo = 0; - IRecordInfo *recordInfo = 0; - CLSID clsid = qvar.type() == QVariant::Rect ? CLSID_QRect - :qvar.type() == QVariant::Size ? CLSID_QSize - :CLSID_QPoint; - qAxTypeLibrary->GetTypeInfoOfGuid(clsid, &typeInfo); - if (!typeInfo) - break; - pGetRecordInfoFromTypeInfo(typeInfo, &recordInfo); - typeInfo->Release(); - if (!recordInfo) - break; - - void *record = 0; - switch (qvar.type()) { - case QVariant::Rect: - { - QRect qrect(qvar.toRect()); - recordInfo->RecordCreateCopy(&qrect, &record); - } - break; - case QVariant::Size: - { - QSize qsize(qvar.toSize()); - recordInfo->RecordCreateCopy(&qsize, &record); - } - break; - case QVariant::Point: - { - QPoint qpoint(qvar.toPoint()); - recordInfo->RecordCreateCopy(&qpoint, &record); - } - break; - } - - arg.vt = VT_RECORD; - arg.pRecInfo = recordInfo, - arg.pvRecord = record; - if (out) { - qWarning("QVariant2VARIANT: out-parameter not supported for records"); - return false; - } - } - break; -#endif // QAX_SERVER - case QVariant::UserType: - { - QByteArray subType = qvar.typeName(); -#ifdef QAX_SERVER - if (subType.endsWith('*')) - subType.truncate(subType.length() - 1); -#endif - if (!qstrcmp(qvar.typeName(), "IDispatch*")) { - arg.vt = VT_DISPATCH; - arg.pdispVal = *(IDispatch**)qvar.data(); - if (arg.pdispVal) - arg.pdispVal->AddRef(); - if (out) { - qWarning("QVariant2VARIANT: out-parameter not supported for IDispatch"); - return false; - } - } else if (!qstrcmp(qvar.typeName(), "IDispatch**")) { - arg.vt = VT_DISPATCH; - arg.ppdispVal = *(IDispatch***)qvar.data(); - if (out) - arg.vt |= VT_BYREF; - } else if (!qstrcmp(qvar.typeName(), "IUnknown*")) { - arg.vt = VT_UNKNOWN; - arg.punkVal = *(IUnknown**)qvar.data(); - if (arg.punkVal) - arg.punkVal->AddRef(); - if (out) { - qWarning("QVariant2VARIANT: out-parameter not supported for IUnknown"); - return false; - } -#ifdef QAX_SERVER - } else if (qAxFactory()->metaObject(QString::fromLatin1(subType.constData()))) { - arg.vt = VT_DISPATCH; - void *user = *(void**)qvar.constData(); -// qVariantGet(qvar, user, qvar.typeName()); - if (!user) { - arg.pdispVal = 0; - } else { - qAxFactory()->createObjectWrapper(static_cast<QObject*>(user), &arg.pdispVal); - } - if (out) { - qWarning("QVariant2VARIANT: out-parameter not supported for subtype"); - return false; - } -#else - } else if (QMetaType::type(subType)) { - QAxObject *object = *(QAxObject**)qvar.constData(); -// qVariantGet(qvar, object, subType); - arg.vt = VT_DISPATCH; - object->queryInterface(IID_IDispatch, (void**)&arg.pdispVal); - if (out) { - qWarning("QVariant2VARIANT: out-parameter not supported for subtype"); - return false; - } -#endif - } else { - return false; - } - } - break; -#endif case QVariant::Invalid: // default-parameters not set if (out && arg.vt == (VT_ERROR|VT_BYREF)) { diff --git a/src/plugins/platforms/windows/accessible/comutils.h b/src/plugins/platforms/windows/accessible/comutils.h index 113d79d473..d5476aa6e8 100644 --- a/src/plugins/platforms/windows/accessible/comutils.h +++ b/src/plugins/platforms/windows/accessible/comutils.h @@ -47,14 +47,9 @@ class QVariant; // Originally QVariantToVARIANT copied from ActiveQt - renamed to avoid conflicts in static builds. bool QVariant2VARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out); -inline QString BSTRToQString(const BSTR &bstr) -{ - return QString((QChar*)bstr); -} - inline BSTR QStringToBSTR(const QString &str) { - return SysAllocStringLen((OLECHAR*)str.unicode(), str.length()); + return SysAllocStringLen(reinterpret_cast<const OLECHAR *>(str.unicode()), UINT(str.length())); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index 5ed8d30e67..7c0b0370b3 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -41,8 +41,16 @@ #include <QtGui/qguiapplication.h> #include <QtCore/qdebug.h> +#include <algorithm> + QT_BEGIN_NAMESPACE +template <class T> +static inline T *coTaskMemAllocArray(int size) +{ + return static_cast<T *>(::CoTaskMemAlloc(sizeof(T) * size_t(size))); +} + /**************************************************************\ * AccessibleApplication * **************************************************************/ @@ -52,7 +60,7 @@ HRESULT STDMETHODCALLTYPE AccessibleApplication::QueryInterface(REFIID id, LPVOI *iface = 0; if (id == IID_IUnknown) { qCDebug(lcQpaAccessibility) << "AccessibleApplication::QI(): IID_IUnknown"; - *iface = (IUnknown*)this; + *iface = static_cast<IUnknown *>(this); } else if (id == IID_IAccessibleApplication) { qCDebug(lcQpaAccessibility) << "AccessibleApplication::QI(): IID_IAccessibleApplication"; *iface = static_cast<IAccessibleApplication*>(this); @@ -122,7 +130,7 @@ HRESULT STDMETHODCALLTYPE AccessibleRelation::QueryInterface(REFIID id, LPVOID * { *iface = 0; if (id == IID_IUnknown || id == IID_IAccessibleRelation) - *iface = (IUnknown*)this; + *iface = static_cast<IUnknown *>(this); if (*iface) { AddRef(); @@ -200,7 +208,7 @@ HRESULT STDMETHODCALLTYPE AccessibleRelation::get_targets( /* [retval][out] */ long *nTargets) { - const int numTargets = qMin((int)maxTargets, m_targets.count()); + const int numTargets = qMin(int(maxTargets), m_targets.count()); for (int i = 0; i < numTargets; ++i) { QAccessibleInterface *iface = m_targets.at(i); IAccessible *iacc = QWindowsAccessibility::wrap(iface); @@ -229,42 +237,40 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::QueryInterface(REFIID id, LPVOI HRESULT hr = QWindowsMsaaAccessible::QueryInterface(id, iface); if (!SUCCEEDED(hr)) { if (id == IID_IServiceProvider) { - *iface = (IServiceProvider*)this; + *iface = static_cast<IServiceProvider *>(this); } else if (id == IID_IAccessible2) { - *iface = (IAccessible2*)this; + *iface = static_cast<IAccessible2 *>(this); } else if (id == IID_IAccessibleAction) { if (accessible->actionInterface()) - *iface = (IAccessibleAction*)this; + *iface = static_cast<IAccessibleAction *>(this); } else if (id == IID_IAccessibleComponent) { - *iface = (IAccessibleComponent*)this; + *iface = static_cast<IAccessibleComponent *>(this); } else if (id == IID_IAccessibleEditableText) { if (accessible->editableTextInterface() || accessible->role() == QAccessible::EditableText) { - *iface = (IAccessibleEditableText*)this; + *iface = static_cast<IAccessibleEditableText *>(this); } } else if (id == IID_IAccessibleHyperlink) { - //*iface = (IAccessibleHyperlink*)this; + //*iface = static_cast<IAccessibleHyperlink *>(this); } else if (id == IID_IAccessibleHypertext) { - //*iface = (IAccessibleHypertext*)this; + //*iface = static_cast<IAccessibleHypertext *>(this); } else if (id == IID_IAccessibleImage) { - //*iface = (IAccessibleImage*)this; - } else if (id == IID_IAccessibleRelation) { - *iface = (IAccessibleRelation*)this; + //*iface = static_cast<IAccessibleImage *>(this); } else if (id == IID_IAccessibleTable) { - //*iface = (IAccessibleTable*)this; // not supported + //*iface = static_cast<IAccessibleTable *>(this); // not supported } else if (id == IID_IAccessibleTable2) { if (accessible->tableInterface()) - *iface = (IAccessibleTable2*)this; + *iface = static_cast<IAccessibleTable2 *>(this); } else if (id == IID_IAccessibleTableCell) { if (accessible->tableCellInterface()) - *iface = (IAccessibleTableCell*)this; + *iface = static_cast<IAccessibleTableCell *>(this); } else if (id == IID_IAccessibleText) { if (accessible->textInterface()) - *iface = (IAccessibleText*)this; + *iface = static_cast<IAccessibleText *>(this); } else if (id == IID_IAccessibleValue) { if (accessible->valueInterface()) - *iface = (IAccessibleValue*)this; + *iface = static_cast<IAccessibleValue *>(this); } if (*iface) { AddRef(); @@ -593,9 +599,9 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_keyBinding(long actionIndex numBindings = keyBindings.count(); if (numBindings > 0) { // The IDL documents that the client must free with CoTaskMemFree - arrayOfBindingsToReturn = (BSTR*)::CoTaskMemAlloc(sizeof(BSTR) * numBindings); - for (int i = 0; i < numBindings; ++i) - arrayOfBindingsToReturn[i] = QStringToBSTR(keyBindings.at(i)); + arrayOfBindingsToReturn = coTaskMemAllocArray<BSTR>(numBindings); + std::transform(keyBindings.constBegin(), keyBindings.constEnd(), + arrayOfBindingsToReturn, QStringToBSTR); } } *keyBindings = arrayOfBindingsToReturn; @@ -668,7 +674,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_foreground(IA2Color *foregr return E_FAIL; // IA2Color is a typedef for long - *foreground = (IA2Color)accessible->foregroundColor().rgb(); + *foreground = static_cast<IA2Color>(accessible->foregroundColor().rgb()); return S_OK; } @@ -680,7 +686,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_background(IA2Color *backgr return E_FAIL; // IA2Color is a typedef for long - *background = (IA2Color)accessible->backgroundColor().rgb(); + *background = static_cast<IA2Color>(accessible->backgroundColor().rgb()); return S_OK; } @@ -754,7 +760,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::insertText(long offset, BSTR *t { QAccessibleInterface *accessible = accessibleInterface(); accessibleDebugClientCalls(accessible); - const QString txt(BSTRToQString(*text)); + const QString txt = QString::fromWCharArray(*text); if (QAccessibleEditableTextInterface *editableTextIface = accessible->editableTextInterface()) editableTextIface->insertText(offset, txt); else @@ -799,7 +805,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::replaceText(long startOffset, l { QAccessibleInterface *accessible = accessibleInterface(); accessibleDebugClientCalls(accessible); - const QString txt(BSTRToQString(*text)); + const QString txt = QString::fromWCharArray(*text); if (QAccessibleEditableTextInterface *editableTextIface = accessible->editableTextInterface()) editableTextIface->replaceText(startOffset, endOffset, txt); else @@ -972,12 +978,13 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedColumns(long **sele if (QAccessibleTableInterface *tableIface = tableInterface()) { const QList<int> selectedIndices = tableIface->selectedColumns(); - const int &count = selectedIndices.count(); - long *selected = (count ? (long*)::CoTaskMemAlloc(sizeof(long) * count) : (long*)0); - for (int i = 0; i < count; ++i) - selected[i] = selectedIndices.at(i); - *selectedColumns = selected; + const int count = selectedIndices.count(); *nColumns = count; + *selectedColumns = Q_NULLPTR; + if (count) { + *selectedColumns = coTaskMemAllocArray<long>(count); + std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), *selectedColumns); + } return count ? S_OK : S_FALSE; } return E_FAIL; @@ -993,12 +1000,13 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedRows(long **selecte if (QAccessibleTableInterface *tableIface = tableInterface()) { const QList<int> selectedIndices = tableIface->selectedRows(); - const int &count = selectedIndices.count(); - long *selected = (count ? (long*)::CoTaskMemAlloc(sizeof(long) * count) : (long*)0); - for (int i = 0; i < count; ++i) - selected[i] = selectedIndices.at(i); - *selectedRows = selected; + const int count = selectedIndices.count(); *nRows = count; + *selectedRows = Q_NULLPTR; + if (count) { + *selectedRows = coTaskMemAllocArray<long>(count); + std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), *selectedRows); + } return count ? S_OK : S_FALSE; } return E_FAIL; @@ -1198,10 +1206,10 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_rowColumnExtents(long *row, if (!accessible || !tableCellInterface()) return E_FAIL; - *row = (long)tableCellInterface()->rowIndex(); - *column = (long)tableCellInterface()->columnIndex(); - *rowExtents = (long)tableCellInterface()->rowExtent(); - *columnExtents = (long)tableCellInterface()->columnExtent(); + *row = tableCellInterface()->rowIndex(); + *column = tableCellInterface()->columnIndex(); + *rowExtents = tableCellInterface()->rowExtent(); + *columnExtents = tableCellInterface()->columnExtent(); *isSelected = tableCellInterface()->isSelected(); return S_OK; } @@ -1242,7 +1250,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_attributes(long offset, QAccessibleInterface *accessible = accessibleInterface(); accessibleDebugClientCalls(accessible); if (QAccessibleTextInterface *text = textInterface()) { - const QString attrs = text->attributes(offset, (int*)startOffset, (int*)endOffset); + const QString attrs = text->attributes(offset, reinterpret_cast<int *>(startOffset), + reinterpret_cast<int *>(endOffset)); *textAttributes = QStringToBSTR(attrs); return S_OK; } @@ -1314,7 +1323,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selection(long selectionInd QAccessibleInterface *accessible = accessibleInterface(); accessibleDebugClientCalls(accessible); if (QAccessibleTextInterface *text = textInterface()) { - text->selection(selectionIndex, (int*)startOffset, (int*)endOffset); + text->selection(selectionIndex, reinterpret_cast<int *>(startOffset), + reinterpret_cast<int *>(endOffset)); return S_OK; } return E_FAIL; @@ -1346,7 +1356,10 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_textBeforeOffset(long offse QAccessibleInterface *accessible = accessibleInterface(); accessibleDebugClientCalls(accessible); if (QAccessibleTextInterface *textIface = textInterface()) { - const QString txt = textIface->textBeforeOffset(offset, (QAccessible::TextBoundaryType)boundaryType, (int*)startOffset, (int*)endOffset); + const QString txt = + textIface->textBeforeOffset(offset, static_cast<QAccessible::TextBoundaryType>(boundaryType), + reinterpret_cast<int *>(startOffset), + reinterpret_cast<int *>(endOffset)); if (!txt.isEmpty()) { *text = QStringToBSTR(txt); return S_OK; @@ -1366,7 +1379,10 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_textAfterOffset( QAccessibleInterface *accessible = accessibleInterface(); accessibleDebugClientCalls(accessible); if (QAccessibleTextInterface *textIface = textInterface()) { - const QString txt = textIface->textAfterOffset(offset, (QAccessible::TextBoundaryType)boundaryType, (int*)startOffset, (int*)endOffset); + const QString txt = + textIface->textAfterOffset(offset, static_cast<QAccessible::TextBoundaryType>(boundaryType), + reinterpret_cast<int *>(startOffset), + reinterpret_cast<int *>(endOffset)); if (!txt.isEmpty()) { *text = QStringToBSTR(txt); return S_OK; @@ -1385,7 +1401,10 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_textAtOffset(long offset, QAccessibleInterface *accessible = accessibleInterface(); accessibleDebugClientCalls(accessible); if (QAccessibleTextInterface *textIface = textInterface()) { - const QString txt = textIface->textAtOffset(offset, (QAccessible::TextBoundaryType)boundaryType, (int*)startOffset, (int*)endOffset); + const QString txt = + textIface->textAtOffset(offset, static_cast<QAccessible::TextBoundaryType>(boundaryType), + reinterpret_cast<int *>(startOffset), + reinterpret_cast<int *>(endOffset)); if (!txt.isEmpty()) { *text = QStringToBSTR(txt); return S_OK; @@ -1624,7 +1643,7 @@ HRESULT QWindowsIA2Accessible::getRelationsHelper(IAccessibleRelation **relation QList<QAccessible::Relation> keys = relationMap.keys(); const int numRelations = keys.count(); if (relations) { - for (int i = startIndex; i < qMin(startIndex + (int)maxRelations, numRelations); ++i) { + for (int i = startIndex; i < qMin(startIndex + int(maxRelations), numRelations); ++i) { QAccessible::Relation relation = keys.at(i); QList<QAccessibleInterface*> targets = relationMap.values(relation); AccessibleRelation *rel = new AccessibleRelation(targets, relation); @@ -1650,12 +1669,13 @@ HRESULT QWindowsIA2Accessible::wrapListOfCells(const QList<QAccessibleInterface* { const int count = inputCells.count(); // Server allocates array - IUnknown **outputCells = count ? (IUnknown**)::CoTaskMemAlloc(sizeof(IUnknown*) * count ) : (IUnknown**)0; - for (int i = 0; i < count; ++i) - outputCells[i] = QWindowsAccessibility::wrap(inputCells.at(i)); - - *outputAccessibles = outputCells; *nCellCount = count; + *outputAccessibles = Q_NULLPTR; + if (count) { + *outputAccessibles = coTaskMemAllocArray<IUnknown *>(count); + std::transform(inputCells.constBegin(), inputCells.constEnd(), + *outputAccessibles, QWindowsAccessibility::wrap); + } return count > 0 ? S_OK : S_FALSE; } @@ -1699,12 +1719,12 @@ QByteArray QWindowsIA2Accessible::IIDToString(REFIID id) } // Q_STATIC_ASSERT(IA2_ROLE_CANVAS == QAccessible::Canvas); // ### Qt 6: make them the same -Q_STATIC_ASSERT(IA2_ROLE_COLOR_CHOOSER == QAccessible::ColorChooser); -Q_STATIC_ASSERT(IA2_ROLE_FOOTER == QAccessible::Footer); -Q_STATIC_ASSERT(IA2_ROLE_FORM == QAccessible::Form); -Q_STATIC_ASSERT(IA2_ROLE_HEADING == QAccessible::Heading); -Q_STATIC_ASSERT(IA2_ROLE_NOTE == QAccessible::Note); -Q_STATIC_ASSERT(IA2_ROLE_COMPLEMENTARY_CONTENT == QAccessible::ComplementaryContent); +Q_STATIC_ASSERT(IA2_ROLE_COLOR_CHOOSER == static_cast<IA2Role>(QAccessible::ColorChooser)); +Q_STATIC_ASSERT(IA2_ROLE_FOOTER == static_cast<IA2Role>(QAccessible::Footer)); +Q_STATIC_ASSERT(IA2_ROLE_FORM == static_cast<IA2Role>(QAccessible::Form)); +Q_STATIC_ASSERT(IA2_ROLE_HEADING == static_cast<IA2Role>(QAccessible::Heading)); +Q_STATIC_ASSERT(IA2_ROLE_NOTE == static_cast<IA2Role>(QAccessible::Note)); +Q_STATIC_ASSERT(IA2_ROLE_COMPLEMENTARY_CONTENT == static_cast<IA2Role>(QAccessible::ComplementaryContent)); QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp index 0437290dcb..3e96895bf9 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp @@ -167,7 +167,7 @@ void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) QPlatformNativeInterface *platform = QGuiApplication::platformNativeInterface(); if (!window->handle()) // Called before show(), no native window yet. return; - HWND hWnd = (HWND)platform->nativeResourceForWindow("handle", window); + const HWND hWnd = reinterpret_cast<HWND>(platform->nativeResourceForWindow("handle", window)); if (event->type() != QAccessible::MenuCommand && // MenuCommand is faked event->type() != QAccessible::ObjectDestroyed) { @@ -214,43 +214,23 @@ IAccessible *QWindowsAccessibility::wrap(QAccessibleInterface *acc) QWindowsIA2Accessible *wacc = new QWindowsIA2Accessible(acc); # endif IAccessible *iacc = 0; - wacc->QueryInterface(IID_IAccessible, (void**)&iacc); + wacc->QueryInterface(IID_IAccessible, reinterpret_cast<void **>(&iacc)); return iacc; #endif // defined(Q_OS_WINCE) } -/* -void QWindowsAccessibility::setRootObject(QObject *o) -{ - -} - -void QWindowsAccessibility::initialize() -{ - -} - -void QWindowsAccessibility::cleanup() -{ - -} - -*/ - bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult) { #if !defined(Q_OS_WINCE) if (static_cast<long>(lParam) == static_cast<long>(UiaRootObjectId)) { /* For UI Automation */ - } else if ((DWORD)lParam == DWORD(OBJID_CLIENT)) { + } else if (DWORD(lParam) == DWORD(OBJID_CLIENT)) { // Start handling accessibility internally QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true); -#if 1 // Ignoring all requests while starting up // ### Maybe QPA takes care of this??? if (QCoreApplication::startingUp() || QCoreApplication::closingDown()) return false; -#endif typedef LRESULT (WINAPI *PtrLresultFromObject)(REFIID, WPARAM, LPUNKNOWN); static PtrLresultFromObject ptrLresultFromObject = 0; @@ -258,7 +238,7 @@ bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, W if (!oleaccChecked) { oleaccChecked = true; - ptrLresultFromObject = (PtrLresultFromObject)QSystemLibrary::resolve(QLatin1String("oleacc"), "LresultFromObject"); + ptrLresultFromObject = reinterpret_cast<PtrLresultFromObject>(QSystemLibrary::resolve(QLatin1String("oleacc"), "LresultFromObject")); } if (ptrLresultFromObject) { diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h index a7113d4f68..5faf80f829 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h @@ -47,12 +47,7 @@ class QWindowsAccessibility : public QPlatformAccessibility public: QWindowsAccessibility(); static bool handleAccessibleObjectFromWindowRequest(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult); - virtual void notifyAccessibilityUpdate(QAccessibleEvent *event); - /* - virtual void setRootObject(QObject *o); - virtual void initialize(); - virtual void cleanup(); - */ + void notifyAccessibilityUpdate(QAccessibleEvent *event) Q_DECL_OVERRIDE; static IAccessible *wrap(QAccessibleInterface *acc); static QWindow *windowHelper(const QAccessibleInterface *iface); }; diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index 2189938248..4ecf78dbf6 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -94,9 +94,9 @@ HRESULT STDMETHODCALLTYPE QWindowsEnumerate::QueryInterface(REFIID id, LPVOID *i { *iface = 0; if (id == IID_IUnknown) - *iface = (IUnknown*)this; + *iface = static_cast<IUnknown *>(this); else if (id == IID_IEnumVARIANT) - *iface = (IEnumVARIANT*)this; + *iface = static_cast<IEnumVARIANT *>(this); if (*iface) { AddRef(); @@ -144,13 +144,13 @@ HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Next(unsigned long celt, VARIANT F ULONG l; for (l = 0; l < celt; l++) { VariantInit(&rgVar[l]); - if ((current+1) > (ULONG)array.size()) { + if (current + 1 > ULONG(array.size())) { *pCeltFetched = l; return S_FALSE; } rgVar[l].vt = VT_I4; - rgVar[l].lVal = array[(int)current]; + rgVar[l].lVal = array[int(current)]; ++current; } *pCeltFetched = l; @@ -166,8 +166,8 @@ HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Reset() HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Skip(unsigned long celt) { current += celt; - if (current > (ULONG)array.size()) { - current = array.size(); + if (current > ULONG(array.size())) { + current = ULONG(array.size()); return S_FALSE; } return S_OK; @@ -195,13 +195,13 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::QueryInterface(REFIID id, LPVO << strIID << ", iface:" << accessibleInterface(); } if (id == IID_IUnknown) { - *iface = (IUnknown*)(IDispatch*)this; + *iface = static_cast<IUnknown *>(static_cast<IDispatch *>(this)); } else if (id == IID_IDispatch) { - *iface = (IDispatch*)this; + *iface = static_cast<IDispatch *>(this); } else if (id == IID_IAccessible) { - *iface = (IAccessible*)this; + *iface = static_cast<IAccessible *>(this); } else if (id == IID_IOleWindow) { - *iface = (IOleWindow*)this; + *iface = static_cast<IOleWindow *>(this); } if (*iface) { diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json index 767eac161c..f7a8844611 100644 --- a/src/plugins/platforms/windows/openglblacklists/default.json +++ b/src/plugins/platforms/windows/openglblacklists/default.json @@ -78,6 +78,18 @@ "features": [ "disable_rotation" ] + }, + { + "id": 7, + "description": "AMD FirePro V5900 driver causes crashes in Direct3D on Windows.", + "vendor_id": "0x1002", + "device_id": ["0x6707"], + "os": { + "type": "win" + }, + "features": [ + "disable_angle" + ] } ] } diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp index af9d2a5969..a518c0bb83 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp +++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp @@ -93,7 +93,7 @@ void QWindowsBackingStore::flush(QWindow *window, const QRegion ®ion, SIZE size = {r.width(), r.height()}; POINT ptDst = {r.x(), r.y()}; POINT ptSrc = {0, 0}; - BLENDFUNCTION blend = {AC_SRC_OVER, 0, (BYTE)(255.0 * rw->opacity()), AC_SRC_ALPHA}; + BLENDFUNCTION blend = {AC_SRC_OVER, 0, BYTE(qRound(255.0 * rw->opacity())), AC_SRC_ALPHA}; if (QWindowsContext::user32dll.updateLayeredWindowIndirect) { RECT dirty = {dirtyRect.x(), dirtyRect.y(), dirtyRect.x() + dirtyRect.width(), dirtyRect.y() + dirtyRect.height()}; @@ -119,7 +119,7 @@ void QWindowsBackingStore::flush(QWindow *window, const QRegion ®ion, m_image->hdc(), br.x() + offset.x(), br.y() + offset.y(), SRCCOPY)) { const DWORD lastError = GetLastError(); // QTBUG-35926, QTBUG-29716: may fail after lock screen. if (lastError != ERROR_SUCCESS && lastError != ERROR_INVALID_HANDLE) - qErrnoWarning(lastError, "%s: BitBlt failed", __FUNCTION__); + qErrnoWarning(int(lastError), "%s: BitBlt failed", __FUNCTION__); } rw->releaseDC(); #ifndef Q_OS_WINCE diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp index 1071a2e038..930f901523 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.cpp +++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp @@ -51,9 +51,6 @@ QT_BEGIN_NAMESPACE -static const char formatTextPlainC[] = "text/plain"; -static const char formatTextHtmlC[] = "text/html"; - /*! \class QWindowsClipboard \brief Clipboard implementation. @@ -262,9 +259,9 @@ bool QWindowsClipboard::clipboardViewerWndProc(HWND hwnd, UINT message, WPARAM w switch (message) { case WM_CHANGECBCHAIN: { - const HWND toBeRemoved = (HWND)wParam; + const HWND toBeRemoved = reinterpret_cast<HWND>(wParam); if (toBeRemoved == m_nextClipboardViewer) { - m_nextClipboardViewer = (HWND)lParam; + m_nextClipboardViewer = reinterpret_cast<HWND>(lParam); } else { propagateClipboardMessage(message, wParam, lParam); } diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 4934b6c6e4..09c2f7df2e 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -89,20 +89,6 @@ Q_LOGGING_CATEGORY(lcQpaAccessibility, "qt.qpa.accessibility") int QWindowsContext::verbose = 0; -// Get verbosity of components from "foo:2,bar:3" -static inline int componentVerbose(const char *v, const char *keyWord) -{ - if (const char *k = strstr(v, keyWord)) { - k += qstrlen(keyWord); - if (*k == ':') { - ++k; - if (isdigit(*k)) - return *k - '0'; - } - } - return 0; -} - #if !defined(LANG_SYRIAC) # define LANG_SYRIAC 0x5a #endif @@ -115,10 +101,10 @@ static inline bool useRTL_Extensions(QSysInfo::WinVersion ver) if ((ver & QSysInfo::WV_NT_based) && (ver >= QSysInfo::WV_VISTA)) { // Since the IsValidLanguageGroup/IsValidLocale functions always return true on // Vista, check the Keyboard Layouts for enabling RTL. - if (const UINT nLayouts = GetKeyboardLayoutList(0, 0)) { + if (const int nLayouts = GetKeyboardLayoutList(0, 0)) { QScopedArrayPointer<HKL> lpList(new HKL[nLayouts]); GetKeyboardLayoutList(nLayouts, lpList.data()); - for (UINT i = 0; i < nLayouts; ++i) { + for (int i = 0; i < nLayouts; ++i) { switch (PRIMARYLANGID((quintptr)lpList[i])) { case LANG_ARABIC: case LANG_HEBREW: @@ -554,15 +540,15 @@ QString QWindowsContext::registerWindowClass(QString cname, // add an instance-specific ID, the address of the window proc. static int classExists = -1; - const HINSTANCE appInstance = (HINSTANCE)GetModuleHandle(0); + const HINSTANCE appInstance = static_cast<HINSTANCE>(GetModuleHandle(0)); if (classExists == -1) { WNDCLASS wcinfo; - classExists = GetClassInfo(appInstance, (wchar_t*)cname.utf16(), &wcinfo); + classExists = GetClassInfo(appInstance, reinterpret_cast<LPCWSTR>(cname.utf16()), &wcinfo); classExists = classExists && wcinfo.lpfnWndProc != proc; } if (classExists) - cname += QString::number((quintptr)proc); + cname += QString::number(reinterpret_cast<quintptr>(proc)); if (d->m_registeredWindowClassNames.contains(cname)) // already registered in our list return cname; @@ -582,13 +568,13 @@ QString QWindowsContext::registerWindowClass(QString cname, #ifndef Q_OS_WINCE wc.hbrBackground = brush; if (icon) { - wc.hIcon = (HICON)LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE); + wc.hIcon = static_cast<HICON>(LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE)); if (wc.hIcon) { int sw = GetSystemMetrics(SM_CXSMICON); int sh = GetSystemMetrics(SM_CYSMICON); - wc.hIconSm = (HICON)LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, sw, sh, 0); + wc.hIconSm = static_cast<HICON>(LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, sw, sh, 0)); } else { - wc.hIcon = (HICON)LoadImage(0, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + wc.hIcon = static_cast<HICON>(LoadImage(0, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED)); wc.hIconSm = 0; } } else { @@ -604,7 +590,7 @@ QString QWindowsContext::registerWindowClass(QString cname, #endif wc.lpszMenuName = 0; - wc.lpszClassName = (wchar_t*)cname.utf16(); + wc.lpszClassName = reinterpret_cast<LPCWSTR>(cname.utf16()); #ifndef Q_OS_WINCE ATOM atom = RegisterClassEx(&wc); #else @@ -624,10 +610,10 @@ QString QWindowsContext::registerWindowClass(QString cname, void QWindowsContext::unregisterWindowClasses() { - const HINSTANCE appInstance = (HINSTANCE)GetModuleHandle(0); + const HINSTANCE appInstance = static_cast<HINSTANCE>(GetModuleHandle(0)); foreach (const QString &name, d->m_registeredWindowClassNames) { - if (!UnregisterClass((wchar_t*)name.utf16(), appInstance) && QWindowsContext::verbose) + if (!UnregisterClass(reinterpret_cast<LPCWSTR>(name.utf16()), appInstance) && QWindowsContext::verbose) qErrnoWarning("UnregisterClass failed for '%s'", qPrintable(name)); } d->m_registeredWindowClassNames.clear(); @@ -643,11 +629,11 @@ QString QWindowsContext::windowsErrorMessage(unsigned long errorCode) QString rc = QString::fromLatin1("#%1: ").arg(errorCode); ushort *lpMsgBuf; - const int len = FormatMessage( + const DWORD len = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, errorCode, 0, (LPTSTR)&lpMsgBuf, 0, NULL); + NULL, errorCode, 0, reinterpret_cast<LPTSTR>(&lpMsgBuf), 0, NULL); if (len) { - rc = QString::fromUtf16(lpMsgBuf, len); + rc = QString::fromUtf16(lpMsgBuf, int(len)); LocalFree(lpMsgBuf); } else { rc += QString::fromLatin1("<unknown error>"); @@ -811,11 +797,11 @@ HWND QWindowsContext::createDummyWindow(const QString &classNameIn, if (!wndProc) wndProc = DefWindowProc; QString className = registerWindowClass(classNameIn, wndProc); - return CreateWindowEx(0, (wchar_t*)className.utf16(), + return CreateWindowEx(0, reinterpret_cast<LPCWSTR>(className.utf16()), windowName, style, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - HWND_MESSAGE, NULL, (HINSTANCE)GetModuleHandle(0), NULL); + HWND_MESSAGE, NULL, static_cast<HINSTANCE>(GetModuleHandle(0)), NULL); } #ifndef Q_OS_WINCE @@ -826,11 +812,11 @@ static inline QString errorMessageFromComError(const _com_error &comError) { TCHAR *message = Q_NULLPTR; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, comError.Error(), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), + NULL, DWORD(comError.Error()), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), message, 0, NULL); if (message) { const QString result = QString::fromWCharArray(message).trimmed(); - LocalFree((HLOCAL)message); + LocalFree(static_cast<HLOCAL>(message)); return result; } if (const WORD wCode = comError.WCode()) @@ -1078,7 +1064,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, platformWindow->handleMoved(); return true; case QtWindows::ResizeEvent: - platformWindow->handleResized((int)wParam); + platformWindow->handleResized(static_cast<int>(wParam)); return true; #ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_GETMINMAXINFO case QtWindows::QuerySizeHints: @@ -1217,7 +1203,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, sessionManager->setActive(false); sessionManager->allowsInteraction(); - bool endsession = (bool) wParam; + const bool endsession = wParam != 0; // we receive the message for each toplevel window included internal hidden ones, // but the aboutToQuit signal should be emitted only once. @@ -1284,7 +1270,7 @@ bool QWindowsContext::handleContextMenuEvent(QWindow *window, const MSG &msg) bool mouseTriggered = false; QPoint globalPos; QPoint pos; - if (msg.lParam != (int)0xffffffff) { + if (msg.lParam != int(0xffffffff)) { mouseTriggered = true; globalPos.setX(msg.pt.x); globalPos.setY(msg.pt.y); @@ -1292,8 +1278,8 @@ bool QWindowsContext::handleContextMenuEvent(QWindow *window, const MSG &msg) RECT clientRect; if (GetClientRect(msg.hwnd, &clientRect)) { - if (pos.x() < (int)clientRect.left || pos.x() >= (int)clientRect.right || - pos.y() < (int)clientRect.top || pos.y() >= (int)clientRect.bottom) + if (pos.x() < clientRect.left || pos.x() >= clientRect.right || + pos.y() < clientRect.top || pos.y() >= clientRect.bottom) { // This is the case that user has right clicked in the window's caption, // We should call DefWindowProc() to display a default shortcut menu diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index c769eb04a4..cda741c226 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -113,8 +113,8 @@ HCURSOR QWindowsCursor::createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot ICONINFO ii; ii.fIcon = 0; - ii.xHotspot = hotSpot.x(); - ii.yHotspot = hotSpot.y(); + ii.xHotspot = DWORD(hotSpot.x()); + ii.yHotspot = DWORD(hotSpot.y()); ii.hbmMask = im; ii.hbmColor = ic; @@ -142,8 +142,8 @@ static HCURSOR createBitmapCursor(const QImage &bbits, const QImage &mbits, QScopedArrayPointer<uchar> xMask(new uchar[height * n]); int x = 0; for (int i = 0; i < height; ++i) { - const uchar *bits = bbits.scanLine(i); - const uchar *mask = mbits.scanLine(i); + const uchar *bits = bbits.constScanLine(i); + const uchar *mask = mbits.constScanLine(i); for (int j = 0; j < n; ++j) { uchar b = bits[j]; uchar m = mask[j]; @@ -173,8 +173,8 @@ static HCURSOR createBitmapCursor(const QImage &bbits, const QImage &mbits, x += sysN; } else { int fillWidth = n > sysN ? sysN : n; - const uchar *bits = bbits.scanLine(i); - const uchar *mask = mbits.scanLine(i); + const uchar *bits = bbits.constScanLine(i); + const uchar *mask = mbits.constScanLine(i); for (int j = 0; j < fillWidth; ++j) { uchar b = bits[j]; uchar m = mask[j]; @@ -246,9 +246,10 @@ static QSize systemCursorSize(const QPlatformScreen *screen = Q_NULLPTR) return primaryScreenCursorSize; } +#if defined (Q_OS_WINCE) || defined (QT_NO_IMAGEFORMAT_PNG) + static inline QSize standardCursorSize() { return QSize(32, 32); } -#if defined (Q_OS_WINCE) || defined (QT_NO_IMAGEFORMAT_PNG) // Create pixmap cursors from data and scale the image if the cursor size is // higher than the standard 32. Note that bitmap cursors as produced by // createBitmapCursor() only work for standard sizes (32,48,64...), which does @@ -570,7 +571,7 @@ HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape, const for (const QWindowsStandardCursorMapping *s = standardCursors; s < sEnd; ++s) { if (s->shape == cursorShape) { #ifndef Q_OS_WINCE - return (HCURSOR)LoadImage(0, s->resource, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + return static_cast<HCURSOR>(LoadImage(0, s->resource, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED)); #else return LoadCursor(0, s->resource); #endif diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 9211fd1320..ca5b90b429 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -737,7 +737,7 @@ inline QUrl QWindowsFileDialogSharedData::directory() const inline void QWindowsFileDialogSharedData::setDirectory(const QUrl &d) { - QMutexLocker (&m_data->mutex); + QMutexLocker locker(&m_data->mutex); m_data->directory = d; } @@ -751,7 +751,7 @@ inline QString QWindowsFileDialogSharedData::selectedNameFilter() const inline void QWindowsFileDialogSharedData::setSelectedNameFilter(const QString &f) { - QMutexLocker (&m_data->mutex); + QMutexLocker locker(&m_data->mutex); m_data->selectedNameFilter = f; } @@ -771,13 +771,13 @@ inline QString QWindowsFileDialogSharedData::selectedFile() const inline void QWindowsFileDialogSharedData::setSelectedFiles(const QList<QUrl> &urls) { - QMutexLocker (&m_data->mutex); + QMutexLocker locker(&m_data->mutex); m_data->selectedFiles = urls; } inline void QWindowsFileDialogSharedData::fromOptions(const QSharedPointer<QFileDialogOptions> &o) { - QMutexLocker (&m_data->mutex); + QMutexLocker locker(&m_data->mutex); m_data->directory = o->initialDirectory(); m_data->selectedFiles = o->initiallySelectedFiles(); m_data->selectedNameFilter = o->initiallySelectedNameFilter(); @@ -1466,18 +1466,21 @@ public: }; // Return the first suffix from the name filter "Foo files (*.foo;*.bar)" -> "foo". +// Also handles the simple name filter case "*.txt" -> "txt" static inline QString suffixFromFilter(const QString &filter) { - int suffixPos = filter.indexOf(QLatin1String("(*.")); + int suffixPos = filter.indexOf(QLatin1String("*.")); if (suffixPos < 0) return QString(); - suffixPos += 3; + suffixPos += 2; int endPos = filter.indexOf(QLatin1Char(' '), suffixPos + 1); if (endPos < 0) endPos = filter.indexOf(QLatin1Char(';'), suffixPos + 1); if (endPos < 0) endPos = filter.indexOf(QLatin1Char(')'), suffixPos + 1); - return endPos >= 0 ? filter.mid(suffixPos, endPos - suffixPos) : QString(); + if (endPos < 0) + endPos = filter.size(); + return filter.mid(suffixPos, endPos - suffixPos); } void QWindowsNativeSaveFileDialog::setNameFilters(const QStringList &f) @@ -1584,11 +1587,6 @@ QWindowsNativeFileDialogBase *QWindowsNativeFileDialogBase::create(QFileDialogOp return result; } -static inline bool isQQuickWindow(const QWindow *w = 0) -{ - return w && w->inherits("QQuickWindow"); -} - /*! \class QWindowsFileDialogHelper \brief Helper for native Windows file dialogs @@ -1604,8 +1602,8 @@ class QWindowsFileDialogHelper : public QWindowsDialogHelperBase<QPlatformFileDi { public: QWindowsFileDialogHelper() {} - virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return false; } - virtual bool defaultNameFilterDisables() const + virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const Q_DECL_OVERRIDE { return false; } + virtual bool defaultNameFilterDisables() const Q_DECL_OVERRIDE { return false; } virtual void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE; virtual QUrl directory() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.h b/src/plugins/platforms/windows/qwindowsdialoghelpers.h index e0474fc456..2bc823452a 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.h +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.h @@ -64,9 +64,9 @@ public: ~QWindowsDialogHelperBase() { cleanupThread(); } void exec() Q_DECL_OVERRIDE; - virtual bool show(Qt::WindowFlags windowFlags, + bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, - QWindow *parent); + QWindow *parent) Q_DECL_OVERRIDE; void hide() Q_DECL_OVERRIDE; virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return true; } @@ -75,7 +75,7 @@ protected: QWindowsDialogHelperBase(); QWindowsNativeDialogBase *nativeDialog() const; inline bool hasNativeDialog() const { return m_nativeDialog; } - void timerEvent(QTimerEvent *); + void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE; private: virtual QWindowsNativeDialogBase *createNativeDialog() = 0; diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index 18e67ff1a3..150e135604 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -641,7 +641,7 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState, m_chosenEffect = DROPEFFECT_COPY; HGLOBAL hData = GlobalAlloc(0, sizeof(DWORD)); if (hData) { - DWORD *moveEffect = (DWORD *)GlobalLock(hData);; + DWORD *moveEffect = reinterpret_cast<DWORD *>(GlobalLock(hData)); *moveEffect = DROPEFFECT_MOVE; GlobalUnlock(hData); STGMEDIUM medium; @@ -649,7 +649,7 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState, medium.tymed = TYMED_HGLOBAL; medium.hGlobal = hData; FORMATETC format; - format.cfFormat = RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT); + format.cfFormat = CLIPFORMAT(RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT)); format.tymed = TYMED_HGLOBAL; format.ptd = 0; format.dwAspect = 1; diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index 65a9763be6..787a072a7a 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -187,9 +187,9 @@ bool QWindowsLibGLESv2::init() qCDebug(lcQpaGl) << "Qt: Using OpenGL ES 2.0 from" << dllName; #if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC) - m_lib = ::LoadLibraryW((const wchar_t *) QString::fromLatin1(dllName).utf16()); + m_lib = ::LoadLibraryW(reinterpret_cast<LPCWSTR>(QString::fromLatin1(dllName).utf16())); if (!m_lib) { - qErrnoWarning(::GetLastError(), "Failed to load %s", dllName); + qErrnoWarning(int(GetLastError()), "Failed to load %s", dllName); return false; } #endif // !QT_STATIC @@ -342,8 +342,8 @@ bool QWindowsLibGLESv2::init() return glBindTexture && glCreateShader && glClearDepthf; } -QWindowsEGLStaticContext::QWindowsEGLStaticContext(EGLDisplay display, int version) - : m_display(display), m_version(version) +QWindowsEGLStaticContext::QWindowsEGLStaticContext(EGLDisplay display) + : m_display(display) { } @@ -395,7 +395,7 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester: Q_UNUSED(preferredType) #endif if (display == EGL_NO_DISPLAY) - display = libEGL.eglGetDisplay((EGLNativeDisplayType)dc); + display = libEGL.eglGetDisplay(dc); if (!display) { qWarning("%s: Could not obtain EGL display", __FUNCTION__); return 0; @@ -410,7 +410,7 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester: } qCDebug(lcQpaGl) << __FUNCTION__ << "Created EGL display" << display << 'v' <<major << '.' << minor; - return new QWindowsEGLStaticContext(display, (major << 8) | minor); + return new QWindowsEGLStaticContext(display); } QWindowsEGLStaticContext::~QWindowsEGLStaticContext() @@ -427,8 +427,8 @@ QWindowsOpenGLContext *QWindowsEGLStaticContext::createContext(QOpenGLContext *c void *QWindowsEGLStaticContext::createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) { *err = 0; - EGLSurface surface = libEGL.eglCreateWindowSurface(m_display, (EGLConfig) nativeConfig, - (EGLNativeWindowType) nativeWindow, 0); + EGLSurface surface = libEGL.eglCreateWindowSurface(m_display, nativeConfig, + static_cast<EGLNativeWindowType>(nativeWindow), 0); if (surface == EGL_NO_SURFACE) { *err = libEGL.eglGetError(); qWarning("%s: Could not create the EGL window surface: 0x%x", __FUNCTION__, *err); @@ -439,7 +439,7 @@ void *QWindowsEGLStaticContext::createWindowSurface(void *nativeWindow, void *na void QWindowsEGLStaticContext::destroyWindowSurface(void *nativeSurface) { - libEGL.eglDestroySurface(m_display, (EGLSurface) nativeSurface); + libEGL.eglDestroySurface(m_display, nativeSurface); } QSurfaceFormat QWindowsEGLStaticContext::formatFromConfig(EGLDisplay display, EGLConfig config, @@ -990,7 +990,7 @@ EGLConfig QWindowsEGLContext::chooseConfig(const QSurfaceFormat &format) QVector<EGLConfig> configs(matching); QWindowsEGLStaticContext::libEGL.eglChooseConfig(display, configureAttributes.constData(), configs.data(), configs.size(), &matching); if (!cfg && matching > 0) - cfg = configs.first(); + cfg = configs.constFirst(); EGLint red = 0; EGLint green = 0; diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h index 555d633a78..6945939941 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.h +++ b/src/plugins/platforms/windows/qwindowseglcontext.h @@ -257,9 +257,9 @@ public: EGLDisplay display() const { return m_display; } - QWindowsOpenGLContext *createContext(QOpenGLContext *context); - void *moduleHandle() const { return libGLESv2.moduleHandle(); } - QOpenGLContext::OpenGLModuleType moduleType() const { return QOpenGLContext::LibGLES; } + QWindowsOpenGLContext *createContext(QOpenGLContext *context) Q_DECL_OVERRIDE; + void *moduleHandle() const Q_DECL_OVERRIDE { return libGLESv2.moduleHandle(); } + QOpenGLContext::OpenGLModuleType moduleType() const Q_DECL_OVERRIDE { return QOpenGLContext::LibGLES; } void *createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) Q_DECL_OVERRIDE; void destroyWindowSurface(void *nativeSurface) Q_DECL_OVERRIDE; @@ -270,10 +270,9 @@ public: static QWindowsLibGLESv2 libGLESv2; private: - QWindowsEGLStaticContext(EGLDisplay display, int version); + explicit QWindowsEGLStaticContext(EGLDisplay display); const EGLDisplay m_display; - const int m_version; //! majorVersion<<8 + minorVersion }; class QWindowsEGLContext : public QWindowsOpenGLContext diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index bf42ca190b..4be215ec8a 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -269,10 +269,10 @@ namespace { quint16 nameIds[requiredRecordCount] = { 1, 2, 3, 4, 6 }; int sizeOfHeader = sizeof(NameTable) + sizeof(NameRecord) * requiredRecordCount; - int newFamilyNameSize = newFamilyName.size() * sizeof(quint16); + int newFamilyNameSize = newFamilyName.size() * int(sizeof(quint16)); const QString regularString = QString::fromLatin1("Regular"); - int regularStringSize = regularString.size() * sizeof(quint16); + int regularStringSize = regularString.size() * int(sizeof(quint16)); // Align table size of table to 32 bits (pad with 0) int fullSize = ((sizeOfHeader + newFamilyNameSize + regularStringSize) & ~3) + 4; @@ -634,11 +634,24 @@ QDebug operator<<(QDebug d, const QFontDef &def) { QDebugStateSaver saver(d); d.nospace(); - d << "Family=" << def.family << " Stylename=" << def.styleName - << " pointsize=" << def.pointSize << " pixelsize=" << def.pixelSize - << " styleHint=" << def.styleHint << " weight=" << def.weight - << " stretch=" << def.stretch << " hintingPreference=" - << def.hintingPreference; + d.noquote(); + d << "QFontDef(Family=\"" << def.family << '"'; + if (!def.styleName.isEmpty()) + d << ", stylename=" << def.styleName; + d << ", pointsize=" << def.pointSize << ", pixelsize=" << def.pixelSize + << ", styleHint=" << def.styleHint << ", weight=" << def.weight + << ", stretch=" << def.stretch << ", hintingPreference=" + << def.hintingPreference << ')'; + return d; +} + +QDebug operator<<(QDebug d, const LOGFONT &lf) +{ + QDebugStateSaver saver(d); + d.nospace(); + d.noquote(); + d << "LOGFONT(\"" << QString::fromWCharArray(lf.lfFaceName) + << "\", lfWidth=" << lf.lfWidth << ", lfHeight=" << lf.lfHeight << ')'; return d; } #endif // !QT_NO_DEBUG_STREAM @@ -792,7 +805,7 @@ static QString getEnglishName(const uchar *table, quint32 bytes) length /= 2; i18n_name.resize(length); - QChar *uc = (QChar *) i18n_name.unicode(); + QChar *uc = const_cast<QChar *>(i18n_name.unicode()); const unsigned char *string = table + string_offset + offset; for (int i = 0; i < length; ++i) uc[i] = getUShort(string + 2*i); @@ -800,10 +813,10 @@ static QString getEnglishName(const uchar *table, quint32 bytes) // Apple Roman i18n_name.resize(length); - QChar *uc = (QChar *) i18n_name.unicode(); + QChar *uc = const_cast<QChar *>(i18n_name.unicode()); const unsigned char *string = table + string_offset + offset; for (int i = 0; i < length; ++i) - uc[i] = QLatin1Char(string[i]); + uc[i] = QLatin1Char(char(string[i])); } } } @@ -870,14 +883,13 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet, static const int SMOOTH_SCALABLE = 0xffff; const QString foundryName; // No such concept. - const NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric; - const bool fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH); - const bool ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE); - const bool scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); - const int size = scalable ? SMOOTH_SCALABLE : tm->tmHeight; - const QFont::Style style = tm->tmItalic ? QFont::StyleItalic : QFont::StyleNormal; + const bool fixed = !(textmetric->tmPitchAndFamily & TMPF_FIXED_PITCH); + const bool ttf = (textmetric->tmPitchAndFamily & TMPF_TRUETYPE); + const bool scalable = textmetric->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); + const int size = scalable ? SMOOTH_SCALABLE : textmetric->tmHeight; + const QFont::Style style = textmetric->tmItalic ? QFont::StyleItalic : QFont::StyleNormal; const bool antialias = false; - const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(tm->tmWeight); + const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(textmetric->tmWeight); const QFont::Stretch stretch = QFont::Unstretched; #ifndef QT_NO_DEBUG_OUTPUT @@ -957,18 +969,21 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet, return true; } -static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, - int type, LPARAM registerAlias) +static int QT_WIN_CALLBACK storeFont(const LOGFONT *logFont, const TEXTMETRIC *textmetric, + DWORD type, LPARAM lParam) { + const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont); const QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName); const uchar charSet = f->elfLogFont.lfCharSet; + const bool registerAlias = bool(lParam); - const FONTSIGNATURE signature = textmetric->ntmFontSig; - - // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is - // identical to a TEXTMETRIC except for the last four members, which we don't use - // anyway - addFontToDatabase(familyName, charSet, (TEXTMETRIC *)textmetric, &signature, type, registerAlias); + // NEWTEXTMETRICEX (passed for TT fonts) is a NEWTEXTMETRIC, which according + // to the documentation is identical to a TEXTMETRIC except for the last four + // members, which we don't use anyway + const FONTSIGNATURE *signature = Q_NULLPTR; + if (type & TRUETYPE_FONTTYPE) + signature = &reinterpret_cast<const NEWTEXTMETRICEX *>(textmetric)->ntmFontSig; + addFontToDatabase(familyName, charSet, textmetric, signature, type, registerAlias); // keep on enumerating return 1; @@ -987,7 +1002,7 @@ void QWindowsFontDatabase::populateFamily(const QString &familyName, bool regist familyName.toWCharArray(lf.lfFaceName); lf.lfFaceName[familyName.size()] = 0; lf.lfPitchAndFamily = 0; - EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont, (LPARAM)registerAlias, 0); + EnumFontFamiliesEx(dummy, &lf, storeFont, LPARAM(registerAlias), 0); ReleaseDC(0, dummy); } @@ -1008,9 +1023,11 @@ struct PopulateFamiliesContext }; } // namespace -static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *tm, int, LPARAM lparam) +static int QT_WIN_CALLBACK populateFontFamilies(const LOGFONT *logFont, const TEXTMETRIC *textmetric, + DWORD, LPARAM lparam) { // the "@family" fonts are just the same as "family". Ignore them. + const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont); const wchar_t *faceNameW = f->elfLogFont.lfFaceName; if (faceNameW[0] && faceNameW[0] != L'@' && wcsncmp(faceNameW, L"WST_", 4)) { const QString faceName = QString::fromWCharArray(faceNameW); @@ -1020,7 +1037,7 @@ static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICE context->seenSystemDefaultFont = true; // Register current font's english name as alias - const bool ttf = (tm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE); + const bool ttf = textmetric->tmPitchAndFamily & TMPF_TRUETYPE; if (ttf && localizedName(faceName)) { const QString englishName = getEnglishName(faceName); if (!englishName.isEmpty()) { @@ -1044,7 +1061,7 @@ void QWindowsFontDatabase::populateFontDatabase() lf.lfFaceName[0] = 0; lf.lfPitchAndFamily = 0; PopulateFamiliesContext context(QWindowsFontDatabase::systemDefaultFont().family()); - EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0); + EnumFontFamiliesEx(dummy, &lf, populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0); ReleaseDC(0, dummy); // Work around EnumFontFamiliesEx() not listing the system font. if (!context.seenSystemDefaultFont) @@ -1150,8 +1167,9 @@ QT_WARNING_POP DWORD count = 0; QByteArray newFontData = font.data(); - HANDLE fontHandle = AddFontMemResourceEx((void *)newFontData.constData(), newFontData.size(), 0, - &count); + HANDLE fontHandle = + AddFontMemResourceEx(const_cast<char *>(newFontData.constData()), + DWORD(newFontData.size()), 0, &count); if (count == 0 && fontHandle != 0) { RemoveFontMemResourceEx(fontHandle); fontHandle = 0; @@ -1369,8 +1387,9 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, return families; DWORD dummy = 0; - font.handle = AddFontMemResourceEx((void *)fontData.constData(), fontData.size(), 0, - &dummy); + font.handle = + AddFontMemResourceEx(const_cast<char *>(fontData.constData()), + DWORD(fontData.size()), 0, &dummy); if (font.handle == 0) return QStringList(); @@ -1743,24 +1762,35 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, lf.lfFaceName[nameSubstituteLength] = 0; } - IDWriteFont *directWriteFont = 0; - HRESULT hr = data->directWriteGdiInterop->CreateFontFromLOGFONT(&lf, &directWriteFont); - if (FAILED(hr)) { - qErrnoWarning("%s: CreateFontFromLOGFONT failed", __FUNCTION__); + HFONT hfont = CreateFontIndirect(&lf); + if (!hfont) { + qErrnoWarning("%s: CreateFontIndirect failed", __FUNCTION__); } else { + HGDIOBJ oldFont = SelectObject(data->hdc, hfont); + IDWriteFontFace *directWriteFontFace = NULL; - hr = directWriteFont->CreateFontFace(&directWriteFontFace); + HRESULT hr = data->directWriteGdiInterop->CreateFontFaceFromHdc(data->hdc, &directWriteFontFace); if (FAILED(hr)) { - qErrnoWarning("%s: CreateFontFace failed", __FUNCTION__); + const QString errorString = qt_error_string(int(hr)); + qWarning().noquote().nospace() << "DirectWrite: CreateFontFaceFromHDC() failed (" + << errorString << ") for " << request << ' ' << lf << " dpi=" << dpi; } else { QWindowsFontEngineDirectWrite *fedw = new QWindowsFontEngineDirectWrite(directWriteFontFace, request.pixelSize, data); - fedw->initFontInfo(request, dpi, directWriteFont); + + wchar_t n[64]; + GetTextFace(data->hdc, 64, n); + + QFontDef fontDef = request; + fontDef.family = QString::fromWCharArray(n); + + fedw->initFontInfo(fontDef, dpi); fe = fedw; } - directWriteFont->Release(); + SelectObject(data->hdc, oldFont); + DeleteObject(hfont); } } #endif // QT_NO_DIRECTWRITE diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index 684c44acf2..823c3e7c7b 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -392,14 +392,13 @@ static bool addFontToDatabase(const QString &faceName, static const int SMOOTH_SCALABLE = 0xffff; const QString foundryName; // No such concept. - const NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric; - const bool fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH); - const bool ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE); - const bool scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); - const int size = scalable ? SMOOTH_SCALABLE : tm->tmHeight; - const QFont::Style style = tm->tmItalic ? QFont::StyleItalic : QFont::StyleNormal; + const bool fixed = !(textmetric->tmPitchAndFamily & TMPF_FIXED_PITCH); + const bool ttf = (textmetric->tmPitchAndFamily & TMPF_TRUETYPE); + const bool scalable = textmetric->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); + const int size = scalable ? SMOOTH_SCALABLE : textmetric->tmHeight; + const QFont::Style style = textmetric->tmItalic ? QFont::StyleItalic : QFont::StyleNormal; const bool antialias = false; - const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(tm->tmWeight); + const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(textmetric->tmWeight); const QFont::Stretch stretch = QFont::Unstretched; #ifndef QT_NO_DEBUG_STREAM @@ -454,6 +453,8 @@ static bool addFontToDatabase(const QString &faceName, const FontKey *key = findFontKey(faceName, &index); if (!key) { key = findFontKey(fullName, &index); + if (!key && !registerAlias && englishName.isEmpty() && localizedName(faceName)) + englishName = getEnglishName(faceName); if (!key && !englishName.isEmpty()) key = findFontKey(englishName, &index); if (!key) @@ -514,19 +515,21 @@ static QByteArray getFntTable(HFONT hfont, uint tag) } #endif -static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, - int type, LPARAM) +static int QT_WIN_CALLBACK storeFont(const LOGFONT *logFont, const TEXTMETRIC *textmetric, + DWORD type, LPARAM) { - + const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont); const QString faceName = QString::fromWCharArray(f->elfLogFont.lfFaceName); const QString fullName = QString::fromWCharArray(f->elfFullName); const uchar charSet = f->elfLogFont.lfCharSet; - const FONTSIGNATURE signature = textmetric->ntmFontSig; - // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is - // identical to a TEXTMETRIC except for the last four members, which we don't use - // anyway - addFontToDatabase(faceName, fullName, charSet, (TEXTMETRIC *)textmetric, &signature, type, false); + // NEWTEXTMETRICEX (passed for TT fonts) is a NEWTEXTMETRIC, which according + // to the documentation is identical to a TEXTMETRIC except for the last four + // members, which we don't use anyway + const FONTSIGNATURE *signature = Q_NULLPTR; + if (type & TRUETYPE_FONTTYPE) + signature = &reinterpret_cast<const NEWTEXTMETRICEX *>(textmetric)->ntmFontSig; + addFontToDatabase(faceName, fullName, charSet, textmetric, signature, type, false); // keep on enumerating return 1; @@ -553,7 +556,7 @@ void QWindowsFontDatabaseFT::populateFamily(const QString &familyName) familyName.toWCharArray(lf.lfFaceName); lf.lfFaceName[familyName.size()] = 0; lf.lfPitchAndFamily = 0; - EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont, 0, 0); + EnumFontFamiliesEx(dummy, &lf, storeFont, 0, 0); ReleaseDC(0, dummy); } @@ -573,17 +576,20 @@ struct PopulateFamiliesContext // Delayed population of font families -static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *tm, int, LPARAM lparam) +static int QT_WIN_CALLBACK populateFontFamilies(const LOGFONT *logFont, const TEXTMETRIC *textmetric, + DWORD, LPARAM lparam) { + const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont); // the "@family" fonts are just the same as "family". Ignore them. const wchar_t *faceNameW = f->elfLogFont.lfFaceName; if (faceNameW[0] && faceNameW[0] != L'@' && wcsncmp(faceNameW, L"WST_", 4)) { // Register only font families for which a font file exists for delayed population + const bool ttf = textmetric->tmPitchAndFamily & TMPF_TRUETYPE; const QString faceName = QString::fromWCharArray(faceNameW); const FontKey *key = findFontKey(faceName); if (!key) { key = findFontKey(QString::fromWCharArray(f->elfFullName)); - if (!key && (tm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE) && localizedName(faceName)) + if (!key && ttf && localizedName(faceName)) key = findFontKey(getEnglishName(faceName)); } if (key) { @@ -593,7 +599,6 @@ static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICE context->seenSystemDefaultFont = true; // Register current font's english name as alias - const bool ttf = (tm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE); if (ttf && localizedName(faceName)) { const QString englishName = getEnglishName(faceName); if (!englishName.isEmpty()) { @@ -617,7 +622,7 @@ void QWindowsFontDatabaseFT::populateFontDatabase() lf.lfFaceName[0] = 0; lf.lfPitchAndFamily = 0; PopulateFamiliesContext context(QWindowsFontDatabase::systemDefaultFont().family()); - EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0); + EnumFontFamiliesEx(dummy, &lf, populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0); ReleaseDC(0, dummy); // Work around EnumFontFamiliesEx() not listing the system font if (!context.seenSystemDefaultFont) diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index bf62052ee5..a97062273f 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -31,11 +31,6 @@ ** ****************************************************************************/ -#if _WIN32_WINNT < 0x0500 -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0500 -#endif - #include "qwindowsintegration.h" #include "qwindowsfontengine.h" #include "qwindowsnativeimage.h" @@ -103,17 +98,6 @@ static void resolveGetCharWidthI() ptrGetCharWidthI = (PtrGetCharWidthI)QSystemLibrary::resolve(QStringLiteral("gdi32"), "GetCharWidthI"); } -static inline quint32 getUInt(unsigned char *p) -{ - quint32 val; - val = *p++ << 24; - val |= *p++ << 16; - val |= *p++ << 8; - val |= *p; - - return val; -} - static inline quint16 getUShort(unsigned char *p) { quint16 val; @@ -170,6 +154,12 @@ bool QWindowsFontEngine::hasEbdtTable() const return GetFontData(hdc, MAKE_TAG('E', 'B', 'D', 'T'), 0, 0, 0) != GDI_ERROR; } +static inline QString stringFromOutLineTextMetric(const OUTLINETEXTMETRIC *otm, PSTR offset) +{ + const uchar *p = reinterpret_cast<const uchar *>(otm) + quintptr(offset); + return QString::fromWCharArray(reinterpret_cast<const wchar_t *>(p)); +} + void QWindowsFontEngine::getCMap() { ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE) || hasCMapTable(); @@ -193,11 +183,12 @@ void QWindowsFontEngine::getCMap() _faceId.index = 0; if(cmap) { OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc); - designToDevice = QFixed((int)otm->otmEMSquare)/QFixed::fromReal(fontDef.pixelSize); - unitsPerEm = otm->otmEMSquare; - x_height = (int)otm->otmsXHeight; - loadKerningPairs(QFixed((int)otm->otmEMSquare)/int(otm->otmTextMetrics.tmHeight)); - _faceId.filename = QFile::encodeName(QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFullName))); + unitsPerEm = int(otm->otmEMSquare); + const QFixed unitsPerEmF(unitsPerEm); + designToDevice = unitsPerEmF / QFixed::fromReal(fontDef.pixelSize); + x_height = int(otm->otmsXHeight); + loadKerningPairs(unitsPerEmF / int(otm->otmTextMetrics.tmHeight)); + _faceId.filename = QFile::encodeName(stringFromOutLineTextMetric(otm, otm->otmpFullName)); lineWidth = otm->otmsUnderscoreSize; fsType = otm->otmfsType; free(otm); @@ -265,7 +256,6 @@ QWindowsFontEngine::QWindowsFontEngine(const QString &name, m_logfont(lf), ttf(0), hasOutline(0), - lw(0), cmap(0), cmapSize(0), lbearing(SHRT_MIN), @@ -399,9 +389,9 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape for(int i = 0; i < glyphs->numGlyphs; i++) { unsigned int glyph = glyphs->glyphs[i]; if(int(glyph) >= designAdvancesSize) { - int newSize = (glyph + 256) >> 8 << 8; - designAdvances = q_check_ptr((QFixed *)realloc(designAdvances, - newSize*sizeof(QFixed))); + const int newSize = int(glyph + 256) >> 8 << 8; + designAdvances = reinterpret_cast<QFixed *>(realloc(designAdvances, size_t(newSize) * sizeof(QFixed))); + Q_CHECK_PTR(designAdvances); for(int i = designAdvancesSize; i < newSize; ++i) designAdvances[i] = -1000000; designAdvancesSize = newSize; @@ -423,9 +413,9 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape unsigned int glyph = glyphs->glyphs[i]; if (glyph >= widthCacheSize) { - int newSize = (glyph + 256) >> 8 << 8; - widthCache = q_check_ptr((unsigned char *)realloc(widthCache, - newSize*sizeof(QFixed))); + const uint newSize = (glyph + 256) >> 8 << 8; + widthCache = reinterpret_cast<unsigned char *>(realloc(widthCache, newSize * sizeof(QFixed))); + Q_CHECK_PTR(widthCache); memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize); widthCacheSize = newSize; } @@ -445,7 +435,7 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape ++chrLen; } SIZE size = {0, 0}; - GetTextExtentPoint32(hdc, (wchar_t *)ch, chrLen, &size); + GetTextExtentPoint32(hdc, reinterpret_cast<const wchar_t *>(ch), chrLen, &size); width = size.cx; } else { calculateTTFGlyphWidth(hdc, glyph, width); @@ -453,7 +443,7 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape glyphs->advances[i] = width; // if glyph's within cache range, store it for later if (width > 0 && width < 0x100) - widthCache[glyph] = width; + widthCache[glyph] = uchar(width); } } @@ -494,10 +484,10 @@ bool QWindowsFontEngine::getOutlineMetrics(glyph_t glyph, const QTransform &t, g // results provided when transforming via MAT2 does not // match the glyphs that are drawn using a WorldTransform XFORM xform; - xform.eM11 = t.m11(); - xform.eM12 = t.m12(); - xform.eM21 = t.m21(); - xform.eM22 = t.m22(); + xform.eM11 = FLOAT(t.m11()); + xform.eM12 = FLOAT(t.m12()); + xform.eM21 = FLOAT(t.m21()); + xform.eM22 = FLOAT(t.m22()); xform.eDx = 0; xform.eDy = 0; SetGraphicsMode(hdc, GM_ADVANCED); @@ -519,7 +509,8 @@ bool QWindowsFontEngine::getOutlineMetrics(glyph_t glyph, const QTransform &t, g if (res != GDI_ERROR) { *metrics = glyph_metrics_t(gm.gmptGlyphOrigin.x, -gm.gmptGlyphOrigin.y, - (int)gm.gmBlackBoxX, (int)gm.gmBlackBoxY, gm.gmCellIncX, gm.gmCellIncY); + int(gm.gmBlackBoxX), int(gm.gmBlackBoxY), + gm.gmCellIncX, gm.gmCellIncY); return true; } else { return false; @@ -538,7 +529,7 @@ glyph_metrics_t QWindowsFontEngine::boundingBox(glyph_t glyph, const QTransform if (!ttf && !success) { // Bitmap fonts - wchar_t ch = glyph; + wchar_t ch = wchar_t(glyph); ABCFLOAT abc; GetCharABCWidthsFloat(hdc, ch, ch, &abc); int width = qRound(abc.abcfB); @@ -803,7 +794,7 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, return false; // #### obey scale *metric = glyph_metrics_t(gMetric.gmptGlyphOrigin.x, -gMetric.gmptGlyphOrigin.y, - (int)gMetric.gmBlackBoxX, (int)gMetric.gmBlackBoxY, + int(gMetric.gmBlackBoxX), int(gMetric.gmBlackBoxY), gMetric.gmCellIncX, gMetric.gmCellIncY); } #endif @@ -813,17 +804,15 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, if (ttf) glyphFormat |= GGO_GLYPH_INDEX; - int bufferSize = GDI_ERROR; - bufferSize = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat); - if ((DWORD)bufferSize == GDI_ERROR) { + const DWORD bufferSize = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat); + if (bufferSize == GDI_ERROR) return false; - } - void *dataBuffer = new char[bufferSize]; + char *dataBuffer = new char[bufferSize]; DWORD ret = GDI_ERROR; ret = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, bufferSize, dataBuffer, &mat); if (ret == GDI_ERROR) { - delete [](char *)dataBuffer; + delete [] dataBuffer; return false; } @@ -836,20 +825,18 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, } #endif - int offset = 0; - int headerOffset = 0; - TTPOLYGONHEADER *ttph = 0; + DWORD offset = 0; + DWORD headerOffset = 0; QPointF oset = position.toPointF(); while (headerOffset < bufferSize) { - ttph = (TTPOLYGONHEADER*)((char *)dataBuffer + headerOffset); + const TTPOLYGONHEADER *ttph = reinterpret_cast<const TTPOLYGONHEADER *>(dataBuffer + headerOffset); QPointF lastPoint(qt_to_qpointf(ttph->pfxStart, scale)); path->moveTo(lastPoint + oset); offset += sizeof(TTPOLYGONHEADER); - TTPOLYCURVE *curve; - while (offset<int(headerOffset + ttph->cb)) { - curve = (TTPOLYCURVE*)((char*)(dataBuffer) + offset); + while (offset < headerOffset + ttph->cb) { + const TTPOLYCURVE *curve = reinterpret_cast<const TTPOLYCURVE *>(dataBuffer + offset); switch (curve->wType) { case TT_PRIM_LINE: { for (int i=0; i<curve->cpfx; ++i) { @@ -894,7 +881,7 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, path->closeSubpath(); headerOffset += ttph->cb; } - delete [] (char*)dataBuffer; + delete [] dataBuffer; return true; } @@ -992,15 +979,15 @@ QFontEngine::Properties QWindowsFontEngine::properties() const Properties p; p.emSquare = unitsPerEm; p.italicAngle = otm->otmItalicAngle; - p.postscriptName = QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFamilyName)).toLatin1(); - p.postscriptName += QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpStyleName)).toLatin1(); - p.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(p.postscriptName); + const QByteArray name = stringFromOutLineTextMetric(otm, otm->otmpFamilyName).toLatin1() + + stringFromOutLineTextMetric(otm, otm->otmpStyleName).toLatin1(); + p.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(name); p.boundingBox = QRectF(otm->otmrcFontBox.left, -otm->otmrcFontBox.top, otm->otmrcFontBox.right - otm->otmrcFontBox.left, otm->otmrcFontBox.top - otm->otmrcFontBox.bottom); p.ascent = otm->otmAscent; p.descent = -otm->otmDescent; - p.leading = (int)otm->otmLineGap; + p.leading = int(otm->otmLineGap); p.capHeight = 0; p.lineWidth = otm->otmsUnderscoreSize; free(otm); @@ -1066,10 +1053,10 @@ QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph, XFORM xform; if (has_transformation) { - xform.eM11 = t.m11(); - xform.eM12 = t.m12(); - xform.eM21 = t.m21(); - xform.eM22 = t.m22(); + xform.eM11 = FLOAT(t.m11()); + xform.eM12 = FLOAT(t.m12()); + xform.eM21 = FLOAT(t.m21()); + xform.eM22 = FLOAT(t.m22()); xform.eDx = margin; xform.eDy = margin; @@ -1079,7 +1066,7 @@ QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph, SetWorldTransform(hdc, &xform); HGDIOBJ old_font = SelectObject(hdc, font); - int ggo_options = GGO_METRICS | (ttf ? GGO_GLYPH_INDEX : 0); + const UINT ggo_options = GGO_METRICS | (ttf ? GGO_GLYPH_INDEX : 0); GLYPHMETRICS tgm; MAT2 mat; memset(&mat, 0, sizeof(mat)); @@ -1093,13 +1080,13 @@ QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph, SelectObject(hdc, old_font); if (result == GDI_ERROR) { - const int errorCode = GetLastError(); + const int errorCode = int(GetLastError()); qErrnoWarning(errorCode, "QWinFontEngine: unable to query transformed glyph metrics (GetGlyphOutline() failed, error %d)...", errorCode); return 0; } - iw = tgm.gmBlackBoxX; - ih = tgm.gmBlackBoxY; + iw = int(tgm.gmBlackBoxX); + ih = int(tgm.gmBlackBoxY); xform.eDx -= tgm.gmptGlyphOrigin.x; xform.eDy += tgm.gmptGlyphOrigin.y; @@ -1136,11 +1123,11 @@ QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph, if (has_transformation) { SetGraphicsMode(hdc, GM_ADVANCED); SetWorldTransform(hdc, &xform); - ExtTextOut(hdc, 0, 0, options, 0, (LPCWSTR) &glyph, 1, 0); + ExtTextOut(hdc, 0, 0, options, 0, reinterpret_cast<LPCWSTR>(&glyph), 1, 0); } else #endif // !Q_OS_WINCE { - ExtTextOut(hdc, -gx + margin, -gy + margin, options, 0, (LPCWSTR) &glyph, 1, 0); + ExtTextOut(hdc, -gx + margin, -gy + margin, options, 0, reinterpret_cast<LPCWSTR>(&glyph), 1, 0); } SelectObject(hdc, old_font); @@ -1161,7 +1148,9 @@ glyph_metrics_t QWindowsFontEngine::alphaMapBoundingBox(glyph_t glyph, QFixed, c QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xform) { HFONT font = hfont; - if (m_fontEngineData->clearTypeEnabled) { + + bool clearTypeTemporarilyDisabled = (m_fontEngineData->clearTypeEnabled && m_logfont.lfQuality != NONANTIALIASED_QUALITY); + if (clearTypeTemporarilyDisabled) { LOGFONT lf = m_logfont; lf.lfQuality = ANTIALIASED_QUALITY; font = CreateFontIndirect(&lf); @@ -1169,7 +1158,7 @@ QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xfo QImage::Format mask_format = QWindowsNativeImage::systemFormat(); mask_format = QImage::Format_RGB32; - QWindowsNativeImage *mask = drawGDIGlyph(font, glyph, 0, xform, mask_format); + const QWindowsNativeImage *mask = drawGDIGlyph(font, glyph, 0, xform, mask_format); if (mask == 0) { if (m_fontEngineData->clearTypeEnabled) DeleteObject(font); @@ -1184,11 +1173,11 @@ QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xfo for (int y=0; y<mask->height(); ++y) { uchar *dest = alphaMap.scanLine(y); if (mask->image().format() == QImage::Format_RGB16) { - const qint16 *src = (qint16 *) ((const QImage &) mask->image()).scanLine(y); + const qint16 *src = reinterpret_cast<const qint16 *>(mask->image().constScanLine(y)); for (int x=0; x<mask->width(); ++x) dest[x] = 255 - qGray(src[x]); } else { - const uint *src = (uint *) ((const QImage &) mask->image()).scanLine(y); + const uint *src = reinterpret_cast<const uint *>(mask->image().constScanLine(y)); for (int x=0; x<mask->width(); ++x) { if (QWindowsNativeImage::systemFormat() == QImage::Format_RGB16) dest[x] = 255 - qGray(src[x]); @@ -1200,7 +1189,7 @@ QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xfo // Cleanup... delete mask; - if (m_fontEngineData->clearTypeEnabled) { + if (clearTypeTemporarilyDisabled) { DeleteObject(font); } @@ -1216,11 +1205,11 @@ QImage QWindowsFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed, const QTra UINT contrast; SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &contrast, 0); - SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) 1000, 0); + SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, reinterpret_cast<void *>(quintptr(1000)), 0); int margin = glyphMargin(QFontEngine::Format_A32); QWindowsNativeImage *mask = drawGDIGlyph(font, glyph, margin, t, QImage::Format_RGB32); - SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) quintptr(contrast), 0); + SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, reinterpret_cast<void *>(quintptr(contrast)), 0); if (mask == 0) return QImage(); @@ -1233,7 +1222,7 @@ QImage QWindowsFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed, const QTra QImage rgbMask(mask->width(), mask->height(), QImage::Format_RGB32); for (int y=0; y<mask->height(); ++y) { uint *dest = (uint *) rgbMask.scanLine(y); - const uint *src = (uint *) source.scanLine(y); + const uint *src = reinterpret_cast<const uint *>(source.constScanLine(y)); for (int x=0; x<mask->width(); ++x) { dest[x] = 0xffffffff - (0x00ffffff & src[x]); } diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h index 5317368455..47891a2830 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.h +++ b/src/plugins/platforms/windows/qwindowsfontengine.h @@ -144,7 +144,6 @@ private: uint hasUnreliableOutline : 1; uint cffTable : 1; TEXTMETRIC tm; - int lw; const unsigned char *cmap; int cmapSize; QByteArray cmapTable; diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index d99a6caecd..5b2e220fd6 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -33,15 +33,6 @@ #ifndef QT_NO_DIRECTWRITE -#if WINVER < 0x0600 -# undef WINVER -# define WINVER 0x0600 -#endif -#if _WIN32_WINNT < 0x0600 -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0600 -#endif - #include "qwindowsfontenginedirectwrite.h" #include "qwindowsfontdatabase.h" #include "qwindowscontext.h" @@ -493,7 +484,7 @@ QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed sub QImage alphaMap(im.width(), im.height(), QImage::Format_Alpha8); for (int y=0; y<im.height(); ++y) { - uint *src = (uint*) im.scanLine(y); + const uint *src = reinterpret_cast<const uint *>(im.constScanLine(y)); uchar *dst = alphaMap.scanLine(y); for (int x=0; x<im.width(); ++x) { *dst = 255 - (m_fontEngineData->pow_gamma[qGray(0xffffffff - *src)] * 255. / 2047.); @@ -648,71 +639,11 @@ QFontEngine *QWindowsFontEngineDirectWrite::cloneWithSize(qreal pixelSize) const return fontEngine; } -// Dynamically resolve GetUserDefaultLocaleName, which is available from Windows -// Vista onwards. ### fixme 5.7: Consider reverting to direct linking. -typedef int (WINAPI *GetUserDefaultLocaleNamePtr)(LPWSTR, int); - -static inline GetUserDefaultLocaleNamePtr resolveGetUserDefaultLocaleName() -{ - QSystemLibrary library(QStringLiteral("kernel32")); - return (GetUserDefaultLocaleNamePtr)library.resolve("GetUserDefaultLocaleName"); -} - void QWindowsFontEngineDirectWrite::initFontInfo(const QFontDef &request, - int dpi, IDWriteFont *font) + int dpi) { fontDef = request; - IDWriteFontFamily *fontFamily = NULL; - HRESULT hr = font->GetFontFamily(&fontFamily); - - IDWriteLocalizedStrings *familyNames = NULL; - if (SUCCEEDED(hr)) - hr = fontFamily->GetFamilyNames(&familyNames); - - UINT32 index = 0; - - if (SUCCEEDED(hr)) { - BOOL exists = false; - - wchar_t localeName[LOCALE_NAME_MAX_LENGTH]; - static const GetUserDefaultLocaleNamePtr getUserDefaultLocaleName = resolveGetUserDefaultLocaleName(); - const int defaultLocaleSuccess = getUserDefaultLocaleName - ? getUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH) : 0; - if (defaultLocaleSuccess) - hr = familyNames->FindLocaleName(localeName, &index, &exists); - - if (SUCCEEDED(hr) && !exists) - hr = familyNames->FindLocaleName(L"en-us", &index, &exists); - - if (!exists) - index = 0; - } - - // Get the family name. - if (SUCCEEDED(hr)) { - UINT32 length = 0; - - hr = familyNames->GetStringLength(index, &length); - - if (SUCCEEDED(hr)) { - QVarLengthArray<wchar_t, 128> name(length+1); - - hr = familyNames->GetString(index, name.data(), name.size()); - - if (SUCCEEDED(hr)) - fontDef.family = QString::fromWCharArray(name.constData()); - } - } - - if (familyNames != NULL) - familyNames->Release(); - if (fontFamily) - fontFamily->Release(); - - if (FAILED(hr)) - qErrnoWarning(hr, "initFontInfo: Failed to get family name"); - if (fontDef.pointSize < 0) fontDef.pointSize = fontDef.pixelSize * 72. / dpi; else if (fontDef.pixelSize == -1) diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h index 07e040ed33..91de871311 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h @@ -59,7 +59,7 @@ public: const QSharedPointer<QWindowsFontEngineData> &d); ~QWindowsFontEngineDirectWrite(); - void initFontInfo(const QFontDef &request, int dpi, IDWriteFont *font); + void initFontInfo(const QFontDef &request, int dpi); QFixed lineThickness() const Q_DECL_OVERRIDE; QFixed underlinePosition() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index 8d33e2f0db..2eaae6b726 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -1011,7 +1011,7 @@ QOpenGLStaticContext::QOpenGLStaticContext() : QByteArray QOpenGLStaticContext::getGlString(unsigned int which) { if (const GLubyte *s = opengl32.glGetString(which)) - return QByteArray((const char*)s); + return QByteArray(reinterpret_cast<const char*>(s)); return QByteArray(); } @@ -1238,7 +1238,7 @@ bool QWindowsGLContext::updateObtainedParams(HDC hdc, int *obtainedSwapInterval) bool hasRobustness = false; if (m_obtainedFormat.majorVersion() < 3) { - const char *exts = (const char *) QOpenGLStaticContext::opengl32.glGetString(GL_EXTENSIONS); + const char *exts = reinterpret_cast<const char *>(QOpenGLStaticContext::opengl32.glGetString(GL_EXTENSIONS)); hasRobustness = exts && strstr(exts, "GL_ARB_robustness"); } else { typedef const GLubyte * (APIENTRY *glGetStringi_t)(GLenum, GLuint); @@ -1247,7 +1247,7 @@ bool QWindowsGLContext::updateObtainedParams(HDC hdc, int *obtainedSwapInterval) GLint n = 0; QOpenGLStaticContext::opengl32.glGetIntegerv(GL_NUM_EXTENSIONS, &n); for (GLint i = 0; i < n; ++i) { - const char *p = (const char *) glGetStringi(GL_EXTENSIONS, i); + const char *p = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i)); if (p && !strcmp(p, "GL_ARB_robustness")) { hasRobustness = true; break; diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index 56b5561756..d3299db460 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -319,7 +319,9 @@ void QWindowsInputContext::invokeAction(QInputMethod::Action action, int cursorP // position. const HIMC himc = ImmGetContext(m_compositionContext.hwnd); const HWND imeWindow = ImmGetDefaultIMEWnd(m_compositionContext.hwnd); - SendMessage(imeWindow, m_WM_MSIME_MOUSE, MAKELONG(MAKEWORD(MK_LBUTTON, cursorPosition == 0 ? 2 : 1), cursorPosition), (LPARAM)himc); + const WPARAM mouseOperationCode = + MAKELONG(MAKEWORD(MK_LBUTTON, cursorPosition == 0 ? 2 : 1), cursorPosition); + SendMessage(imeWindow, m_WM_MSIME_MOUSE, mouseOperationCode, LPARAM(himc)); ImmReleaseContext(m_compositionContext.hwnd, himc); } @@ -328,7 +330,7 @@ static inline QString getCompositionString(HIMC himc, DWORD dwIndex) enum { bufferSize = 256 }; wchar_t buffer[bufferSize]; const int length = ImmGetCompositionString(himc, dwIndex, buffer, bufferSize * sizeof(wchar_t)); - return QString::fromWCharArray(buffer, length / sizeof(wchar_t)); + return QString::fromWCharArray(buffer, size_t(length) / sizeof(wchar_t)); } // Determine the converted string range as pair of start/length to be selected. @@ -559,9 +561,8 @@ bool QWindowsInputContext::handleIME_Request(WPARAM wParam, if (size < 0) return false; *result = size; - return true; } - break; + return true; case IMR_CONFIRMRECONVERTSTRING: return true; default: @@ -572,7 +573,7 @@ bool QWindowsInputContext::handleIME_Request(WPARAM wParam, void QWindowsInputContext::handleInputLanguageChanged(WPARAM wparam, LPARAM lparam) { - const LCID newLanguageId = languageIdFromLocaleId(lparam); + const LCID newLanguageId = languageIdFromLocaleId(WORD(lparam)); if (newLanguageId == m_languageId) return; const LCID oldLanguageId = m_languageId; @@ -606,13 +607,13 @@ int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv) if (!surroundingTextV.isValid()) return -1; const QString surroundingText = surroundingTextV.toString(); - const DWORD memSize = sizeof(RECONVERTSTRING) - + (surroundingText.length() + 1) * sizeof(ushort); + const int memSize = int(sizeof(RECONVERTSTRING)) + + (surroundingText.length() + 1) * int(sizeof(ushort)); qCDebug(lcQpaInputMethods) << __FUNCTION__ << " reconv=" << reconv << " surroundingText=" << surroundingText << " size=" << memSize; // If memory is not allocated, return the required size. if (!reconv) - return surroundingText.isEmpty() ? -1 : int(memSize); + return surroundingText.isEmpty() ? -1 : memSize; const QVariant posV = QInputMethod::queryFocusObject(Qt::ImCursorPosition, QVariant()); const int pos = posV.isValid() ? posV.toInt() : 0; @@ -631,13 +632,13 @@ int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv) QInputMethodEvent selectEvent(QString(), attributes); QCoreApplication::sendEvent(fo, &selectEvent); - reconv->dwSize = memSize; + reconv->dwSize = DWORD(memSize); reconv->dwVersion = 0; - reconv->dwStrLen = surroundingText.size(); + reconv->dwStrLen = DWORD(surroundingText.size()); reconv->dwStrOffset = sizeof(RECONVERTSTRING); - reconv->dwCompStrLen = endPos - startPos; // TCHAR count. - reconv->dwCompStrOffset = startPos * sizeof(ushort); // byte count. + reconv->dwCompStrLen = DWORD(endPos - startPos); // TCHAR count. + reconv->dwCompStrOffset = DWORD(startPos) * sizeof(ushort); // byte count. reconv->dwTargetStrLen = reconv->dwCompStrLen; reconv->dwTargetStrOffset = reconv->dwCompStrOffset; ushort *pastReconv = reinterpret_cast<ushort *>(reconv + 1); diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index bd2014b8f2..27ec258f37 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -514,8 +514,8 @@ QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) co case QPlatformIntegration::FontSmoothingGamma: return QVariant(QWindowsFontDatabase::fontSmoothingGamma()); case QPlatformIntegration::MouseDoubleClickInterval: - if (const int ms = GetDoubleClickTime()) - return QVariant(ms); + if (const UINT ms = GetDoubleClickTime()) + return QVariant(int(ms)); break; case QPlatformIntegration::UseRtlExtensions: return QVariant(d->m_context.useRTLExtensions()); diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index c5dff60114..403ac6ecfb 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -541,7 +541,7 @@ Q_STATIC_ASSERT((NumMods == KeyboardLayoutItem::NumQtKeys)); /** Remap return or action key to select key for windows mobile. */ -inline int winceKeyBend(int keyCode) +inline quint32 winceKeyBend(quint32 keyCode) { return KeyTbl[keyCode]; } @@ -575,10 +575,10 @@ QT_END_INCLUDE_NAMESPACE #endif // Q_OS_WINCE // Translate a VK into a Qt key code, or unicode character -static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer, bool *isDeadkey = 0) +static inline quint32 toKeyOrUnicode(quint32 vk, quint32 scancode, unsigned char *kbdBuffer, bool *isDeadkey = 0) { Q_ASSERT(vk > 0 && vk < 256); - int code = 0; + quint32 code = 0; QChar unicodeBuffer[5]; int res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0); // When Ctrl modifier is used ToUnicode does not return correct values. In order to assign the @@ -614,10 +614,6 @@ static inline int asciiToKeycode(char a, int state) return a & 0xff; } -static inline bool isModifierKey(int code) -{ - return (code >= Qt::Key_Shift) && (code <= Qt::Key_ScrollLock); -} // Key translation -----------------------------------------------------------------------[ end ]--- @@ -636,13 +632,13 @@ void QWindowsKeyMapper::changeKeyboard() /* MAKELCID()'s first argument is a WORD, and GetKeyboardLayout() * returns a DWORD. */ - LCID newLCID = MAKELCID((quintptr)GetKeyboardLayout(0), SORT_DEFAULT); + LCID newLCID = MAKELCID(quintptr(GetKeyboardLayout(0)), SORT_DEFAULT); // keyboardInputLocale = qt_localeFromLCID(newLCID); bool bidi = false; wchar_t LCIDFontSig[16]; if (GetLocaleInfo(newLCID, LOCALE_FONTSIGNATURE, LCIDFontSig, sizeof(LCIDFontSig) / sizeof(wchar_t)) - && (LCIDFontSig[7] & (wchar_t)0x0800)) + && (LCIDFontSig[7] & wchar_t(0x0800))) bidi = true; keyboardInputDirection = bidi ? Qt::RightToLeft : Qt::LeftToRight; @@ -666,7 +662,7 @@ void QWindowsKeyMapper::updateKeyMap(const MSG &msg) unsigned char kbdBuffer[256]; // Will hold the complete keyboard state GetKeyboardState(kbdBuffer); const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask; - updatePossibleKeyCodes(kbdBuffer, scancode, msg.wParam); + updatePossibleKeyCodes(kbdBuffer, scancode, quint32(msg.wParam)); } // Fills keyLayout for that vk_key. Values are all characters one can type using that key @@ -725,7 +721,7 @@ void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 keyLayout[vk_key].qtKey[7] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey); keyLayout[vk_key].deadkeys |= isDeadKey ? 0x80 : 0; // Add a fall back key for layouts which don't do composition and show non-latin1 characters - int fallbackKey = winceKeyBend(vk_key); + quint32 fallbackKey = winceKeyBend(vk_key); if (!fallbackKey || fallbackKey == Qt::Key_unknown) { fallbackKey = 0; if (vk_key != keyLayout[vk_key].qtKey[0] && vk_key < 0x5B && vk_key > 0x2F) @@ -766,7 +762,7 @@ void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 static inline QString messageKeyText(const MSG &msg) { - const QChar ch = QChar((ushort)msg.wParam); + const QChar ch = QChar(ushort(msg.wParam)); return ch.isNull() ? QString() : QString(ch); } @@ -811,7 +807,7 @@ static void showSystemMenu(QWindow* w) topLevelHwnd, 0); if (ret) - qWindowsWndProc(topLevelHwnd, WM_SYSCOMMAND, ret, 0); + qWindowsWndProc(topLevelHwnd, WM_SYSCOMMAND, WPARAM(ret), 0); } static inline void sendExtendedPressRelease(QWindow *w, int k, @@ -875,7 +871,7 @@ bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, con if (cmd < 0 || cmd > 52) return false; - const int qtKey = CmdTbl[cmd]; + const int qtKey = int(CmdTbl[cmd]); sendExtendedPressRelease(receiver, qtKey, Qt::KeyboardModifier(state), 0, 0, 0); // QTBUG-43343: Make sure to return false if Qt does not handle the key, otherwise, // the keys are not passed to the active media player. @@ -889,10 +885,10 @@ bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, con bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &msg, bool /* grab */) { - const int msgType = msg.message; + const UINT msgType = msg.message; const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask; - quint32 vk_key = msg.wParam; + quint32 vk_key = quint32(msg.wParam); quint32 nModifiers = 0; QWindow *receiver = m_keyGrabber ? m_keyGrabber : window; @@ -953,13 +949,13 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms if (dirStatus == VK_LSHIFT && ((msg.wParam == VK_SHIFT && GetKeyState(VK_LCONTROL)) || (msg.wParam == VK_CONTROL && GetKeyState(VK_LSHIFT)))) { - sendExtendedPressRelease(receiver, Qt::Key_Direction_L, 0, scancode, msg.wParam, nModifiers, QString(), false); + sendExtendedPressRelease(receiver, Qt::Key_Direction_L, 0, scancode, vk_key, nModifiers, QString(), false); result = true; dirStatus = 0; } else if (dirStatus == VK_RSHIFT && ( (msg.wParam == VK_SHIFT && GetKeyState(VK_RCONTROL)) || (msg.wParam == VK_CONTROL && GetKeyState(VK_RSHIFT)))) { - sendExtendedPressRelease(receiver, Qt::Key_Direction_R, 0, scancode, msg.wParam, nModifiers, QString(), false); + sendExtendedPressRelease(receiver, Qt::Key_Direction_R, 0, scancode, vk_key, nModifiers, QString(), false); result = true; dirStatus = 0; } else { @@ -1034,7 +1030,7 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms || (msg.wParam >= VK_OEM_PLUS && msg.wParam <= VK_OEM_3)) ? 0 : int(Qt::KeypadModifier); default: - if ((uint)msg.lParam == 0x004c0001 || (uint)msg.lParam == 0xc04c0001) + if (uint(msg.lParam) == 0x004c0001 || uint(msg.lParam) == 0xc04c0001) state |= Qt::KeypadModifier; break; } @@ -1046,6 +1042,7 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms case Qt::Key_Slash: case Qt::Key_NumLock: state |= Qt::KeypadModifier; + break; default: break; } @@ -1055,13 +1052,13 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms if (msgType == WM_KEYDOWN || msgType == WM_IME_KEYDOWN || msgType == WM_SYSKEYDOWN) { // Get the last record of this key press, so we can validate the current state // The record is not removed from the list - KeyRecord *rec = key_recorder.findKey(msg.wParam, false); + KeyRecord *rec = key_recorder.findKey(int(msg.wParam), false); // If rec's state doesn't match the current state, something has changed behind our back // (Consumed by modal widget is one possibility) So, remove the record from the list // This will stop the auto-repeat of the key, should a modifier change, for example if (rec && rec->state != state) { - key_recorder.findKey(msg.wParam, true); + key_recorder.findKey(int(msg.wParam), true); rec = 0; } @@ -1074,11 +1071,11 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms QChar uch; if (PeekMessage(&wm_char, 0, charType, charType, PM_REMOVE)) { // Found a ?_CHAR - uch = QChar((ushort)wm_char.wParam); + uch = QChar(ushort(wm_char.wParam)); if (msgType == WM_SYSKEYDOWN && uch.isLetter() && (msg.lParam & KF_ALTDOWN)) uch = uch.toLower(); // (See doc of WM_SYSCHAR) Alt-letter if (!code && !uch.row()) - code = asciiToKeycode(uch.cell(), state); + code = asciiToKeycode(char(uch.cell()), state); } // Special handling for the WM_IME_KEYDOWN message. Microsoft IME (Korean) will not @@ -1089,7 +1086,7 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms const QWindowsInputContext *windowsInputContext = qobject_cast<const QWindowsInputContext *>(QWindowsIntegration::instance()->inputContext()); if (!(windowsInputContext && windowsInputContext->isComposing())) - vk_key = ImmGetVirtualKey((HWND)window->winId()); + vk_key = ImmGetVirtualKey(reinterpret_cast<HWND>(window->winId())); BYTE keyState[256]; wchar_t newKey[3] = {0}; GetKeyboardState(keyState); @@ -1109,14 +1106,14 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms uch = QChar(QLatin1Char(0x7f)); // Windows doesn't know this one. } else { if (msgType != WM_SYSKEYDOWN || !code) { - UINT map = MapVirtualKey(msg.wParam, 2); + UINT map = MapVirtualKey(UINT(msg.wParam), 2); // If the high bit of the return value is set, it's a deadkey if (!(map & 0x80000000)) - uch = QChar((ushort)map); + uch = QChar(ushort(map)); } } if (!code && !uch.row()) - code = asciiToKeycode(uch.cell(), state); + code = asciiToKeycode(char(uch.cell()), state); } // Special handling of global Windows hotkeys @@ -1145,9 +1142,9 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms if (rec) { if (code < Qt::Key_Shift || code > Qt::Key_ScrollLock) { QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyRelease, code, - Qt::KeyboardModifier(state), scancode, msg.wParam, nModifiers, rec->text, true); + Qt::KeyboardModifier(state), scancode, quint32(msg.wParam), nModifiers, rec->text, true); QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyPress, code, - Qt::KeyboardModifier(state), scancode, msg.wParam, nModifiers, rec->text, true); + Qt::KeyboardModifier(state), scancode, quint32(msg.wParam), nModifiers, rec->text, true); result = true; } } @@ -1155,7 +1152,7 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms // and store the key data into our records. else { const QString text = uch.isNull() ? QString() : QString(uch); - const char a = uch.row() ? 0 : uch.cell(); + const char a = uch.row() ? char(0) : char(uch.cell()); const Qt::KeyboardModifiers modifiers(state); #ifndef QT_NO_SHORTCUT // Is Qt interested in the context menu key? @@ -1164,9 +1161,9 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms return false; } #endif // !QT_NO_SHORTCUT - key_recorder.storeKey(msg.wParam, a, state, text); + key_recorder.storeKey(int(msg.wParam), a, state, text); QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyPress, code, - modifiers, scancode, msg.wParam, nModifiers, text, false); + modifiers, scancode, quint32(msg.wParam), nModifiers, text, false); result =true; bool store = true; #ifndef Q_OS_WINCE @@ -1185,7 +1182,7 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms } #endif // !Q_OS_WINCE if (!store) - key_recorder.findKey(msg.wParam, true); + key_recorder.findKey(int(msg.wParam), true); } } @@ -1195,7 +1192,7 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms // The key may not be in our records if, for example, the down event was handled by // win32 natively, or our window gets focus while a key is already press, but now gets // the key release event. - KeyRecord* rec = key_recorder.findKey(msg.wParam, true); + const KeyRecord *rec = key_recorder.findKey(int(msg.wParam), true); if (!rec && !(code == Qt::Key_Shift || code == Qt::Key_Control || code == Qt::Key_Meta @@ -1203,13 +1200,14 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms // Someone ate the key down event } else { if (!code) - code = asciiToKeycode(rec->ascii ? rec->ascii : msg.wParam, state); + code = asciiToKeycode(rec->ascii ? char(rec->ascii) : char(msg.wParam), state); // Map SHIFT + Tab to SHIFT + BackTab, QShortcutMap knows about this translation if (code == Qt::Key_Tab && (state & Qt::ShiftModifier) == Qt::ShiftModifier) code = Qt::Key_Backtab; QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyRelease, code, - Qt::KeyboardModifier(state), scancode, msg.wParam, nModifiers, + Qt::KeyboardModifier(state), scancode, quint32(msg.wParam), + nModifiers, (rec ? rec->text : QString()), false); result = true; #ifndef Q_OS_WINCE @@ -1249,7 +1247,12 @@ QList<int> QWindowsKeyMapper::possibleKeys(const QKeyEvent *e) const { QList<int> result; - const KeyboardLayoutItem &kbItem = keyLayout[e->nativeVirtualKey()]; + + const quint32 nativeVirtualKey = e->nativeVirtualKey(); + if (nativeVirtualKey > 255) + return result; + + const KeyboardLayoutItem &kbItem = keyLayout[nativeVirtualKey]; if (!kbItem.exists) return result; diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp index eaaf2820ee..de18426484 100644 --- a/src/plugins/platforms/windows/qwindowsmime.cpp +++ b/src/plugins/platforms/windows/qwindowsmime.cpp @@ -150,7 +150,7 @@ static bool qt_write_dibv5(QDataStream &s, QImage image) bi.bV5Planes = 1; bi.bV5BitCount = 32; bi.bV5Compression = BI_BITFIELDS; - bi.bV5SizeImage = bpl_bmp*image.height(); + bi.bV5SizeImage = DWORD(bpl_bmp * image.height()); bi.bV5XPelsPerMeter = 0; bi.bV5YPelsPerMeter = 0; bi.bV5ClrUsed = 0; @@ -170,30 +170,29 @@ static bool qt_write_dibv5(QDataStream &s, QImage image) image = image.convertToFormat(QImage::Format_ARGB32); uchar *buf = new uchar[bpl_bmp]; - uchar *b; - memset(buf, 0, bpl_bmp); + memset(buf, 0, size_t(bpl_bmp)); for (int y=image.height()-1; y>=0; y--) { // write the image bits - QRgb *p = (QRgb *)image.scanLine(y); - QRgb *end = p + image.width(); - b = buf; + const QRgb *p = reinterpret_cast<const QRgb *>(image.constScanLine(y)); + const QRgb *end = p + image.width(); + uchar *b = buf; while (p < end) { int alpha = qAlpha(*p); if (alpha) { - *b++ = qBlue(*p); - *b++ = qGreen(*p); - *b++ = qRed(*p); + *b++ = uchar(qBlue(*p)); + *b++ = uchar(qGreen(*p)); + *b++ = uchar(qRed(*p)); } else { //white for fully transparent pixels. *b++ = 0xff; *b++ = 0xff; *b++ = 0xff; } - *b++ = alpha; + *b++ = uchar(alpha); p++; } - d->write((char*)buf, bpl_bmp); + d->write(reinterpret_cast<const char *>(buf), bpl_bmp); if (s.status() != QDataStream::Ok) { delete[] buf; return false; @@ -221,25 +220,22 @@ static bool qt_read_dibv5(QDataStream &s, QImage &image) if (d->atEnd()) return false; - d->read((char *)&bi, sizeof(bi)); // read BITMAPV5HEADER header + d->read(reinterpret_cast<char *>(&bi), sizeof(bi)); // read BITMAPV5HEADER header if (s.status() != QDataStream::Ok) return false; - int nbits = bi.bV5BitCount; - int comp = bi.bV5Compression; - if (nbits != 32 || bi.bV5Planes != 1 || comp != BMP_BITFIELDS) + const int nbits = bi.bV5BitCount; + if (nbits != 32 || bi.bV5Planes != 1 || bi.bV5Compression != BMP_BITFIELDS) return false; //Unsupported DIBV5 format - int w = bi.bV5Width, h = bi.bV5Height; - int red_mask = bi.bV5RedMask; - int green_mask = bi.bV5GreenMask; - int blue_mask = bi.bV5BlueMask; - int alpha_mask = bi.bV5AlphaMask; - int red_shift = 0; - int green_shift = 0; - int blue_shift = 0; - int alpha_shift = 0; - QImage::Format format = QImage::Format_ARGB32; + const int w = bi.bV5Width; + int h = bi.bV5Height; + const int red_mask = int(bi.bV5RedMask); + const int green_mask = int(bi.bV5GreenMask); + const int blue_mask = int(bi.bV5BlueMask); + const int alpha_mask = int(bi.bV5AlphaMask); + + const QImage::Format format = QImage::Format_ARGB32; if (bi.bV5Height < 0) h = -h; // support images with negative height @@ -251,30 +247,25 @@ static bool qt_read_dibv5(QDataStream &s, QImage &image) image.setDotsPerMeterX(bi.bV5XPelsPerMeter); image.setDotsPerMeterY(bi.bV5YPelsPerMeter); - red_shift = calc_shift(red_mask); - green_shift = calc_shift(green_mask); - blue_shift = calc_shift(blue_mask); - if (alpha_mask) { - alpha_shift = calc_shift(alpha_mask); - } + const int red_shift = calc_shift(red_mask); + const int green_shift = calc_shift(green_mask); + const int blue_shift = calc_shift(blue_mask); + const int alpha_shift = alpha_mask ? calc_shift(alpha_mask) : 0u; - int bpl = image.bytesPerLine(); + const int bpl = image.bytesPerLine(); uchar *data = image.bits(); - QRgb *p; - QRgb *end; + uchar *buf24 = new uchar[bpl]; - int bpl24 = ((w*nbits+31)/32)*4; - uchar *b; - unsigned int c; + const int bpl24 = ((w * nbits + 31) / 32) * 4; while (--h >= 0) { - p = (QRgb *)(data + h*bpl); - end = p + w; - if (d->read((char *)buf24,bpl24) != bpl24) + QRgb *p = reinterpret_cast<QRgb *>(data + h * bpl); + QRgb *end = p + w; + if (d->read(reinterpret_cast<char *>(buf24), bpl24) != bpl24) break; - b = buf24; + const uchar *b = buf24; while (p < end) { - c = *b | (*(b+1))<<8 | (*(b+2))<<16 | (*(b+3))<<24; + const int c = *b | (*(b + 1)) << 8 | (*(b + 2)) << 16 | (*(b + 3)) << 24; *p++ = qRgba(((c & red_mask) >> red_shift) , ((c & green_mask) >> green_shift), ((c & blue_mask) >> blue_shift), @@ -289,9 +280,9 @@ static bool qt_read_dibv5(QDataStream &s, QImage &image) uchar *buf = new uchar[bpl]; h = -bi.bV5Height; for (int y = 0; y < h/2; ++y) { - memcpy(buf, data + y*bpl, bpl); - memcpy(data + y*bpl, data + (h-y-1)*bpl, bpl); - memcpy(data + (h-y-1)*bpl, buf, bpl); + memcpy(buf, data + y * bpl, size_t(bpl)); + memcpy(data + y*bpl, data + (h - y -1) * bpl, size_t(bpl)); + memcpy(data + (h - y -1 ) * bpl, buf, size_t(bpl)); } delete [] buf; } @@ -309,7 +300,7 @@ static int getCf(const FORMATETC &formatetc) static FORMATETC setCf(int cf) { FORMATETC formatetc; - formatetc.cfFormat = cf; + formatetc.cfFormat = CLIPFORMAT(cf); formatetc.dwAspect = DVASPECT_CONTENT; formatetc.lindex = -1; formatetc.ptd = NULL; @@ -319,12 +310,12 @@ static FORMATETC setCf(int cf) static bool setData(const QByteArray &data, STGMEDIUM *pmedium) { - HGLOBAL hData = GlobalAlloc(0, data.size()); + HGLOBAL hData = GlobalAlloc(0, SIZE_T(data.size())); if (!hData) return false; void *out = GlobalLock(hData); - memcpy(out, data.data(), data.size()); + memcpy(out, data.data(), size_t(data.size())); GlobalUnlock(hData); pmedium->tymed = TYMED_HGLOBAL; pmedium->hGlobal = hData; @@ -339,8 +330,8 @@ static QByteArray getData(int cf, IDataObject *pDataObj, int lindex = -1) formatetc.lindex = lindex; STGMEDIUM s; if (pDataObj->GetData(&formatetc, &s) == S_OK) { - DWORD * val = (DWORD*)GlobalLock(s.hGlobal); - data = QByteArray::fromRawData((char*)val, GlobalSize(s.hGlobal)); + const void *val = GlobalLock(s.hGlobal); + data = QByteArray::fromRawData(reinterpret_cast<const char *>(val), int(GlobalSize(s.hGlobal))); data.detach(); GlobalUnlock(s.hGlobal); ReleaseStgMedium(&s); @@ -356,7 +347,7 @@ static QByteArray getData(int cf, IDataObject *pDataObj, int lindex = -1) while(SUCCEEDED(hr)){ hr = s.pstm->Read(szBuffer, sizeof(szBuffer), &actualRead); if (SUCCEEDED(hr) && actualRead > 0) { - data += QByteArray::fromRawData(szBuffer, actualRead); + data += QByteArray::fromRawData(szBuffer, int(actualRead)); } if (actualRead != sizeof(szBuffer)) break; @@ -508,11 +499,11 @@ QWindowsMime::~QWindowsMime() */ int QWindowsMime::registerMimeType(const QString &mime) { - int f = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (mime.utf16())); + const UINT f = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (mime.utf16())); if (!f) qErrnoWarning("QWindowsMime::registerMimeType: Failed to register clipboard format"); - return f; + return int(f); } /*! @@ -655,9 +646,9 @@ bool QWindowsMimeText::convertFromMime(const FORMATETC &formatetc, const QMimeDa ++u; } res.truncate(ri); - const int byteLength = res.length() * sizeof(ushort); + const int byteLength = res.length() * int(sizeof(ushort)); QByteArray r(byteLength + 2, '\0'); - memcpy(r.data(), res.unicode(), byteLength); + memcpy(r.data(), res.unicode(), size_t(byteLength)); r[byteLength] = 0; r[byteLength+1] = 0; return setData(r, pmedium); @@ -700,17 +691,17 @@ QVariant QWindowsMimeText::convertToMime(const QString &mime, LPDATAOBJECT pData QString str; QByteArray data = getData(CF_UNICODETEXT, pDataObj); if (!data.isEmpty()) { - str = QString::fromWCharArray((const wchar_t *)data.data()); + str = QString::fromWCharArray(reinterpret_cast<const wchar_t *>(data.constData())); str.replace(QStringLiteral("\r\n"), QStringLiteral("\n")); } else { data = getData(CF_TEXT, pDataObj); if (!data.isEmpty()) { const char* d = data.data(); - const int s = qstrlen(d); + const unsigned s = qstrlen(d); QByteArray r(data.size()+1, '\0'); char* o = r.data(); int j=0; - for (int i=0; i<s; i++) { + for (unsigned i = 0; i < s; ++i) { char c = d[i]; if (c!='\r') o[j++]=c; @@ -771,22 +762,22 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat for (int i=0; i<urls.size(); i++) { QString fn = QDir::toNativeSeparators(urls.at(i).toLocalFile()); if (!fn.isEmpty()) { - size += sizeof(ushort) * (fn.length() + 1); + size += sizeof(ushort) * size_t(fn.length() + 1); fileNames.append(fn); } } QByteArray result(size, '\0'); - DROPFILES* d = (DROPFILES*)result.data(); + DROPFILES* d = reinterpret_cast<DROPFILES *>(result.data()); d->pFiles = sizeof(DROPFILES); GetCursorPos(&d->pt); // try d->fNC = true; - char* files = ((char*)d) + d->pFiles; + char *files = (reinterpret_cast<char*>(d)) + d->pFiles; d->fWide = true; - wchar_t* f = (wchar_t*)files; + wchar_t *f = reinterpret_cast<wchar_t *>(files); for (int i=0; i<fileNames.size(); i++) { - int l = fileNames.at(i).length(); + const size_t l = size_t(fileNames.at(i).length()); memcpy(f, fileNames.at(i).utf16(), l * sizeof(ushort)); f += l; *f++ = 0; @@ -799,7 +790,8 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat QByteArray result; if (!urls.isEmpty()) { QString url = urls.at(0).toString(); - result = QByteArray((const char *)url.utf16(), url.length() * sizeof(ushort)); + result = QByteArray(reinterpret_cast<const char *>(url.utf16()), + url.length() * int(sizeof(ushort))); } result.append('\0'); result.append('\0'); @@ -854,9 +846,9 @@ QVariant QWindowsMimeURI::convertToMime(const QString &mimeType, LPDATAOBJECT pD if (data.isEmpty()) return QVariant(); - LPDROPFILES hdrop = (LPDROPFILES)data.data(); + const DROPFILES *hdrop = reinterpret_cast<const DROPFILES *>(data.constData()); if (hdrop->fWide) { - const wchar_t* filesw = (const wchar_t *)(data.data() + hdrop->pFiles); + const wchar_t *filesw = reinterpret_cast<const wchar_t *>(data.constData() + hdrop->pFiles); int i = 0; while (filesw[i]) { QString fileurl = QString::fromWCharArray(filesw + i); @@ -864,7 +856,7 @@ QVariant QWindowsMimeURI::convertToMime(const QString &mimeType, LPDATAOBJECT pD i += fileurl.length()+1; } } else { - const char* files = (const char *)data.data() + hdrop->pFiles; + const char* files = reinterpret_cast<const char *>(data.constData() + hdrop->pFiles); int i=0; while (files[i]) { urls += QUrl::fromLocalFile(QString::fromLocal8Bit(files+i)); @@ -880,7 +872,7 @@ QVariant QWindowsMimeURI::convertToMime(const QString &mimeType, LPDATAOBJECT pD QByteArray data = getData(CF_INETURL_W, pDataObj); if (data.isEmpty()) return QVariant(); - return QUrl(QString::fromWCharArray((const wchar_t *)data.constData())); + return QUrl(QString::fromWCharArray(reinterpret_cast<const wchar_t *>(data.constData()))); } else if (canGetData(CF_INETURL, pDataObj)) { QByteArray data = getData(CF_INETURL, pDataObj); if (data.isEmpty()) @@ -1008,14 +1000,14 @@ bool QWindowsMimeHtml::convertFromMime(const FORMATETC &formatetc, const QMimeDa result += "<!--EndFragment-->"; // set the correct number for EndHTML - QByteArray pos = QString::number(result.size()).toLatin1(); - memcpy((char *)(result.data() + 53 - pos.length()), pos.constData(), pos.length()); + QByteArray pos = QByteArray::number(result.size()); + memcpy(reinterpret_cast<char *>(result.data() + 53 - pos.length()), pos.constData(), size_t(pos.length())); // set correct numbers for StartFragment and EndFragment - pos = QString::number(result.indexOf("<!--StartFragment-->") + 20).toLatin1(); - memcpy((char *)(result.data() + 79 - pos.length()), pos.constData(), pos.length()); - pos = QString::number(result.indexOf("<!--EndFragment-->")).toLatin1(); - memcpy((char *)(result.data() + 103 - pos.length()), pos.constData(), pos.length()); + pos = QByteArray::number(result.indexOf("<!--StartFragment-->") + 20); + memcpy(reinterpret_cast<char *>(result.data() + 79 - pos.length()), pos.constData(), size_t(pos.length())); + pos = QByteArray::number(result.indexOf("<!--EndFragment-->")); + memcpy(reinterpret_cast<char *>(result.data() + 103 - pos.length()), pos.constData(), size_t(pos.length())); return setData(result, pmedium); } @@ -1243,9 +1235,9 @@ bool QBuiltInMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData ++u; } res.truncate(ri); - const int byteLength = res.length() * sizeof(ushort); + const int byteLength = res.length() * int(sizeof(ushort)); QByteArray r(byteLength + 2, '\0'); - memcpy(r.data(), res.unicode(), byteLength); + memcpy(r.data(), res.unicode(), size_t(byteLength)); r[byteLength] = 0; r[byteLength+1] = 0; data = r; @@ -1282,7 +1274,7 @@ QVariant QBuiltInMimes::convertToMime(const QString &mimeType, IDataObject *pDat qCDebug(lcQpaMime) << __FUNCTION__; if (mimeType == QLatin1String("text/html") && preferredType == QVariant::String) { // text/html is in wide chars on windows (compatible with Mozilla) - val = QString::fromWCharArray((const wchar_t *)data.data()); + val = QString::fromWCharArray(reinterpret_cast<const wchar_t *>(data.constData())); } else { val = data; // it should be enough to return the data and let QMimeData do the rest. } @@ -1422,8 +1414,8 @@ bool QLastResortMimes::canConvertToMime(const QString &mimeType, IDataObject *pD if (isCustomMimeType(mimeType)) { // MSDN documentation for QueryGetData says only -1 is supported, so ignore lindex here. QString clipFormat = customMimeType(mimeType); - int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16())); - return canGetData(cf, pDataObj); + const UINT cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16())); + return canGetData(int(cf), pDataObj); } else if (formats.keys(mimeType).isEmpty()) { // if it is not in there then register it and see if we can get it int cf = QWindowsMime::registerMimeType(mimeType); @@ -1443,8 +1435,8 @@ QVariant QLastResortMimes::convertToMime(const QString &mimeType, IDataObject *p if (isCustomMimeType(mimeType)) { int lindex; QString clipFormat = customMimeType(mimeType, &lindex); - int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16())); - data = getData(cf, pDataObj, lindex); + const UINT cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16())); + data = getData(int(cf), pDataObj, lindex); } else if (formats.keys(mimeType).isEmpty()) { int cf = QWindowsMime::registerMimeType(mimeType); data = getData(cf, pDataObj); @@ -1593,7 +1585,7 @@ void QWindowsMimeConverter::ensureInitialized() const QString QWindowsMimeConverter::clipboardFormatName(int cf) { wchar_t buf[256] = {0}; - return GetClipboardFormatName(cf, buf, 255) + return GetClipboardFormatName(UINT(cf), buf, 255) ? QString::fromWCharArray(buf) : QString(); } diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index e26010b5c4..4ed708540c 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -203,7 +203,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, // Check for events synthesized from touch. Lower 7 bits are touch/pen index, bit 8 indicates touch. // However, when tablet support is active, extraInfo is a packet serial number. This is not a problem // since we do not want to ignore mouse events coming from a tablet. - const quint64 extraInfo = GetMessageExtraInfo(); + const quint64 extraInfo = quint64(GetMessageExtraInfo()); if ((extraInfo & signatureMask) == miWpSignature) { if (extraInfo & 0x80) { // Bit 7 indicates touch event, else tablet pen. source = Qt::MouseEventSynthesizedBySystem; @@ -243,7 +243,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, } QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle()); - const Qt::MouseButtons buttons = keyStateToMouseButtons((int)msg.wParam); + const Qt::MouseButtons buttons = keyStateToMouseButtons(int(msg.wParam)); // If the window was recently resized via mouse doubleclick on the frame or title bar, // we don't get WM_LBUTTONDOWN or WM_LBUTTONDBLCLK for the second click, @@ -418,13 +418,13 @@ static void redirectWheelEvent(QWindow *window, const QPoint &globalPos, int del bool QWindowsMouseHandler::translateMouseWheelEvent(QWindow *window, HWND, MSG msg, LRESULT *) { - const Qt::KeyboardModifiers mods = keyStateToModifiers((int)msg.wParam); + const Qt::KeyboardModifiers mods = keyStateToModifiers(int(msg.wParam)); int delta; if (msg.message == WM_MOUSEWHEEL || msg.message == WM_MOUSEHWHEEL) - delta = (short) HIWORD (msg.wParam); + delta = GET_WHEEL_DELTA_WPARAM(msg.wParam); else - delta = (int) msg.wParam; + delta = int(msg.wParam); Qt::Orientation orientation = (msg.message == WM_MOUSEHWHEEL || (mods & Qt::AltModifier)) ? @@ -495,15 +495,17 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND, return true; const QRect screenGeometry = screen->geometry(); - const int winTouchPointCount = msg.wParam; + const int winTouchPointCount = int(msg.wParam); QScopedArrayPointer<TOUCHINPUT> winTouchInputs(new TOUCHINPUT[winTouchPointCount]); - memset(winTouchInputs.data(), 0, sizeof(TOUCHINPUT) * winTouchPointCount); + memset(winTouchInputs.data(), 0, sizeof(TOUCHINPUT) * size_t(winTouchPointCount)); QTouchPointList touchPoints; touchPoints.reserve(winTouchPointCount); Qt::TouchPointStates allStates = 0; - QWindowsContext::user32dll.getTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT)); + QWindowsContext::user32dll.getTouchInputInfo(reinterpret_cast<HANDLE>(msg.lParam), + UINT(msg.wParam), + winTouchInputs.data(), sizeof(TOUCHINPUT)); for (int i = 0; i < winTouchPointCount; ++i) { const TOUCHINPUT &winTouchInput = winTouchInputs[i]; int id = m_touchInputIDToTouchPointID.value(winTouchInput.dwID, -1); @@ -544,7 +546,7 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND, touchPoints.append(touchPoint); } - QWindowsContext::user32dll.closeTouchInputHandle((HANDLE) msg.lParam); + QWindowsContext::user32dll.closeTouchInputHandle(reinterpret_cast<HANDLE>(msg.lParam)); // all touch points released, forget the ids we've seen, they may not be reused if (allStates == Qt::TouchPointReleased) diff --git a/src/plugins/platforms/windows/qwindowsnativeimage.cpp b/src/plugins/platforms/windows/qwindowsnativeimage.cpp index 66e64e64b4..3cdfc9f56e 100644 --- a/src/plugins/platforms/windows/qwindowsnativeimage.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeimage.cpp @@ -93,13 +93,13 @@ static inline HBITMAP createDIB(HDC hdc, int width, int height, bmi.blueMask = 0; } - void *bits = 0; + uchar *bits = Q_NULLPTR; HBITMAP bitmap = CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO *>(&bmi), - DIB_RGB_COLORS, &bits, 0, 0); + DIB_RGB_COLORS, reinterpret_cast<void **>(&bits), 0, 0); if (!bitmap || !bits) qFatal("%s: CreateDIBSection failed.", __FUNCTION__); - *bitsIn = (uchar*)bits; + *bitsIn = bits; return bitmap; } @@ -112,7 +112,7 @@ QWindowsNativeImage::QWindowsNativeImage(int width, int height, if (width != 0 && height != 0) { uchar *bits; m_bitmap = createDIB(m_hdc, width, height, format, &bits); - m_null_bitmap = (HBITMAP)SelectObject(m_hdc, m_bitmap); + m_null_bitmap = static_cast<HBITMAP>(SelectObject(m_hdc, m_bitmap)); m_image = QImage(bits, width, height, format); Q_ASSERT(m_image.paintEngine()->type() == QPaintEngine::Raster); static_cast<QRasterPaintEngine *>(m_image.paintEngine())->setDC(m_hdc); diff --git a/src/plugins/platforms/windows/qwindowsole.cpp b/src/plugins/platforms/windows/qwindowsole.cpp index e480c1ebcf..4521f66edd 100644 --- a/src/plugins/platforms/windows/qwindowsole.cpp +++ b/src/plugins/platforms/windows/qwindowsole.cpp @@ -215,7 +215,7 @@ QWindowsOleDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppe fmtetcs = mc.allFormatsForMime(data); } else { FORMATETC formatetc; - formatetc.cfFormat = CF_PERFORMEDDROPEFFECT; + formatetc.cfFormat = CLIPFORMAT(CF_PERFORMEDDROPEFFECT); formatetc.dwAspect = DVASPECT_CONTENT; formatetc.lindex = -1; formatetc.ptd = NULL; @@ -269,7 +269,7 @@ QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs) m_lpfmtetcs.reserve(fmtetcs.count()); for (int idx = 0; idx < fmtetcs.count(); ++idx) { LPFORMATETC destetc = new FORMATETC(); - if (copyFormatEtc(destetc, (LPFORMATETC)&(fmtetcs.at(idx)))) { + if (copyFormatEtc(destetc, &(fmtetcs.at(idx)))) { m_lpfmtetcs.append(destetc); } else { m_isNull = true; @@ -363,14 +363,14 @@ QWindowsOleEnumFmtEtc::Next(ULONG celt, LPFORMATETC rgelt, ULONG FAR* pceltFetch nOffset = m_nIndex + i; if (nOffset < ULONG(m_lpfmtetcs.count())) { - copyFormatEtc((LPFORMATETC)&(rgelt[i]), m_lpfmtetcs.at(nOffset)); + copyFormatEtc(rgelt + i, m_lpfmtetcs.at(int(nOffset))); i++; } else { break; } } - m_nIndex += (WORD)i; + m_nIndex += i; if (pceltFetched != NULL) *pceltFetched = i; @@ -397,7 +397,7 @@ QWindowsOleEnumFmtEtc::Skip(ULONG celt) } } - m_nIndex += (WORD)i; + m_nIndex += i; if (i != celt) return ResultFromScode(S_FALSE); @@ -431,7 +431,7 @@ QWindowsOleEnumFmtEtc::Clone(LPENUMFORMATETC FAR* newEnum) return NOERROR; } -bool QWindowsOleEnumFmtEtc::copyFormatEtc(LPFORMATETC dest, LPFORMATETC src) const +bool QWindowsOleEnumFmtEtc::copyFormatEtc(LPFORMATETC dest, const FORMATETC *src) const { if (dest == NULL || src == NULL) return false; diff --git a/src/plugins/platforms/windows/qwindowsole.h b/src/plugins/platforms/windows/qwindowsole.h index 09f6114e2d..bbafa98a0b 100644 --- a/src/plugins/platforms/windows/qwindowsole.h +++ b/src/plugins/platforms/windows/qwindowsole.h @@ -103,7 +103,7 @@ public: STDMETHOD(Clone)(LPENUMFORMATETC FAR* newEnum); private: - bool copyFormatEtc(LPFORMATETC dest, LPFORMATETC src) const; + bool copyFormatEtc(LPFORMATETC dest, const FORMATETC *src) const; ULONG m_dwRefs; ULONG m_nIndex; diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index fcbe488f93..438aa8752a 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -75,10 +75,10 @@ GpuDescription GpuDescription::detect() const HRESULT hr = direct3D9->GetAdapterIdentifier(0, 0, &adapterIdentifier); direct3D9->Release(); if (SUCCEEDED(hr)) { - result.vendorId = int(adapterIdentifier.VendorId); - result.deviceId = int(adapterIdentifier.DeviceId); - result.revision = int(adapterIdentifier.Revision); - result.subSysId = int(adapterIdentifier.SubSysId); + result.vendorId = adapterIdentifier.VendorId; + result.deviceId = adapterIdentifier.DeviceId; + result.revision = adapterIdentifier.Revision; + result.subSysId = adapterIdentifier.SubSysId; QVector<int> version(4, 0); version[0] = HIWORD(adapterIdentifier.DriverVersion.HighPart); // Product version[1] = LOWORD(adapterIdentifier.DriverVersion.HighPart); // Version @@ -329,10 +329,10 @@ bool QWindowsOpenGLTester::testDesktopGL() WNDCLASS wclass; wclass.cbClsExtra = 0; wclass.cbWndExtra = 0; - wclass.hInstance = (HINSTANCE) GetModuleHandle(0); + wclass.hInstance = static_cast<HINSTANCE>(GetModuleHandle(0)); wclass.hIcon = 0; wclass.hCursor = 0; - wclass.hbrBackground = (HBRUSH) (COLOR_BACKGROUND); + wclass.hbrBackground = HBRUSH(COLOR_BACKGROUND); wclass.lpszMenuName = 0; wclass.lpfnWndProc = DefWindowProc; wclass.lpszClassName = className; @@ -371,8 +371,7 @@ bool QWindowsOpenGLTester::testDesktopGL() typedef const GLubyte * (APIENTRY * GetString_t)(GLenum name); GetString_t GetString = reinterpret_cast<GetString_t>(::GetProcAddress(lib, "glGetString")); if (GetString) { - const char *versionStr = (const char *) GetString(GL_VERSION); - if (versionStr) { + if (const char *versionStr = reinterpret_cast<const char *>(GetString(GL_VERSION))) { const QByteArray version(versionStr); const int majorDot = version.indexOf('.'); if (majorDot != -1) { diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h index 0fad3d960e..0f1a78daaa 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.h +++ b/src/plugins/platforms/windows/qwindowsopengltester.h @@ -51,10 +51,10 @@ struct GpuDescription QString toString() const; QVariant toVariant() const; - int vendorId; - int deviceId; - int revision; - int subSysId; + uint vendorId; + uint deviceId; + uint revision; + uint subSysId; QVersionNumber driverVersion; QByteArray driverName; QByteArray description; diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index 02696c87cd..5accbe87e1 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -77,22 +77,6 @@ static inline QDpi monitorDPI(HMONITOR hMonitor) #endif // !Q_OS_WINCE -static inline QSizeF deviceSizeMM(const QSize &pixels, const QDpi &dpi) -{ - const qreal inchToMM = 25.4; - const qreal h = qreal(pixels.width()) / qreal(dpi.first) * inchToMM; - const qreal v = qreal(pixels.height()) / qreal(dpi.second) * inchToMM; - return QSizeF(h, v); -} - -static inline QDpi deviceDPI(const QSize &pixels, const QSizeF &physicalSizeMM) -{ - const qreal inchToMM = 25.4; - const qreal h = qreal(pixels.width()) / (qreal(physicalSizeMM.width()) / inchToMM); - const qreal v = qreal(pixels.height()) / (qreal(physicalSizeMM.height()) / inchToMM); - return QDpi(h, v); -} - typedef QList<QWindowsScreenData> WindowsScreenDataList; static bool monitorData(HMONITOR hMonitor, QWindowsScreenData *data) @@ -168,7 +152,7 @@ BOOL QT_WIN_CALLBACK monitorEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM static inline WindowsScreenDataList monitorData() { WindowsScreenDataList result; - EnumDisplayMonitors(0, 0, monitorEnumCallback, (LPARAM)&result); + EnumDisplayMonitors(0, 0, monitorEnumCallback, reinterpret_cast<LPARAM>(&result)); return result; } @@ -216,7 +200,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = QPixmap QWindowsScreen::grabWindow(WId window, int x, int y, int width, int height) const { RECT r; - HWND hwnd = window ? (HWND)window : GetDesktopWindow(); + HWND hwnd = window ? reinterpret_cast<HWND>(window) : GetDesktopWindow(); GetClientRect(hwnd, &r); if (width < 0) width = r.right - r.left; @@ -450,7 +434,7 @@ QWindowsScreenManager::QWindowsScreenManager() : bool QWindowsScreenManager::handleDisplayChange(WPARAM wParam, LPARAM lParam) { - const int newDepth = (int)wParam; + const int newDepth = int(wParam); const WORD newHorizontalResolution = LOWORD(lParam); const WORD newVerticalResolution = HIWORD(lParam); if (newDepth != m_lastDepth || newHorizontalResolution != m_lastHorizontalResolution diff --git a/src/plugins/platforms/windows/qwindowsservices.cpp b/src/plugins/platforms/windows/qwindowsservices.cpp index cc697ba7e4..ae63ac46ae 100644 --- a/src/plugins/platforms/windows/qwindowsservices.cpp +++ b/src/plugins/platforms/windows/qwindowsservices.cpp @@ -53,7 +53,10 @@ static inline bool shellExecute(const QUrl &url) #ifndef Q_OS_WINCE const QString nativeFilePath = url.isLocalFile() ? QDir::toNativeSeparators(url.toLocalFile()) : url.toString(QUrl::FullyEncoded); - const quintptr result = (quintptr)ShellExecute(0, 0, (wchar_t*)nativeFilePath.utf16(), 0, 0, SW_SHOWNORMAL); + const quintptr result = + reinterpret_cast<quintptr>(ShellExecute(0, 0, + reinterpret_cast<const wchar_t *>(nativeFilePath.utf16()), + 0, 0, SW_SHOWNORMAL)); // ShellExecute returns a value greater than 32 if successful if (result <= 32) { qWarning("ShellExecute '%s' failed (error %s).", qPrintable(url.toString()), qPrintable(QString::number(result))); @@ -91,7 +94,7 @@ static inline QString mailCommand() if (debug) qDebug() << __FUNCTION__ << "keyName=" << keyName; command[0] = 0; - if (!RegOpenKeyExW(HKEY_CLASSES_ROOT, (const wchar_t*)keyName.utf16(), 0, KEY_READ, &handle)) { + if (!RegOpenKeyExW(HKEY_CLASSES_ROOT, reinterpret_cast<const wchar_t*>(keyName.utf16()), 0, KEY_READ, &handle)) { DWORD bufferSize = BufferSize; RegQueryValueEx(handle, L"", 0, 0, reinterpret_cast<unsigned char*>(command), &bufferSize); RegCloseKey(handle); @@ -134,7 +137,8 @@ static inline bool launchMail(const QUrl &url) STARTUPINFO si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); - if (!CreateProcess(NULL, (wchar_t*)command.utf16(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { + if (!CreateProcess(NULL, reinterpret_cast<wchar_t *>(const_cast<ushort *>(command.utf16())), + NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { qErrnoWarning("Unable to launch '%s'", qPrintable(command)); return false; } diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp index b27811df9e..222551a86f 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp @@ -316,7 +316,7 @@ QDebug operator<<(QDebug d, const QWindowsTabletDeviceData &t) } #endif // !QT_NO_DEBUG_STREAM -QWindowsTabletDeviceData QWindowsTabletSupport::tabletInit(const quint64 uniqueId, const UINT cursorType) const +QWindowsTabletDeviceData QWindowsTabletSupport::tabletInit(qint64 uniqueId, UINT cursorType) const { QWindowsTabletDeviceData result; result.uniqueId = uniqueId; diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h index a6d2771206..6e0d92df53 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.h +++ b/src/plugins/platforms/windows/qwindowstabletsupport.h @@ -123,7 +123,7 @@ public: private: unsigned options() const; - QWindowsTabletDeviceData tabletInit(const quint64 uniqueId, const UINT cursorType) const; + QWindowsTabletDeviceData tabletInit(qint64 uniqueId, UINT cursorType) const; static QWindowsWinTab32DLL m_winTab32DLL; const HWND m_window; diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index cc367ff801..ef652e6f98 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -78,11 +78,6 @@ QT_BEGIN_NAMESPACE -static inline COLORREF qColorToCOLORREF(const QColor &color) -{ - return RGB(color.red(), color.green(), color.blue()); -} - static inline QColor COLORREFToQColor(COLORREF cr) { return QColor(GetRValue(cr), GetGValue(cr), GetBValue(cr)); @@ -99,30 +94,6 @@ static inline QTextStream& operator<<(QTextStream &str, const QColor &c) return str; } -static inline void paletteRoleToString(const QPalette &palette, - const QPalette::ColorRole role, - QTextStream &str) -{ - str << "Role: "; - str.setFieldWidth(2); - str.setPadChar(QLatin1Char('0')); - str << role; - str.setFieldWidth(0); - str << " Active: " << palette.color(QPalette::Active, role) - << " Disabled: " << palette.color(QPalette::Disabled, role) - << " Inactive: " << palette.color(QPalette::Inactive, role) - << '\n'; -} - -static inline QString paletteToString(const QPalette &palette) -{ - QString result; - QTextStream str(&result); - for (int r = 0; r < QPalette::NColorRoles; ++r) - paletteRoleToString(palette, static_cast<QPalette::ColorRole>(r), str); - return result; -} - static inline bool booleanSystemParametersInfo(UINT what, bool defaultValue) { BOOL result; @@ -151,6 +122,41 @@ static inline QColor getSysColor(int index) return COLORREFToQColor(GetSysColor(index)); } +#ifndef QT_NO_WINCE_SHELLSDK +// QTBUG-48823/Windows 10: SHGetFileInfo() (as called by item views on file system +// models has been observed to trigger a WM_PAINT on the mainwindow. Suppress the +// behavior by running it in a thread. +class ShGetFileInfoFunction +{ +public: + explicit ShGetFileInfoFunction(const wchar_t *fn, DWORD a, SHFILEINFO *i, UINT f, bool *r) : + m_fileName(fn), m_attributes(a), m_flags(f), m_info(i), m_result(r) {} + + void operator()() const { *m_result = SHGetFileInfo(m_fileName, m_attributes, m_info, sizeof(SHFILEINFO), m_flags); } + +private: + const wchar_t *m_fileName; + const DWORD m_attributes; + const UINT m_flags; + SHFILEINFO *const m_info; + bool *m_result; +}; + +static bool shGetFileInfoBackground(QWindowsThreadPoolRunner &r, + const wchar_t *fileName, DWORD attributes, + SHFILEINFO *info, UINT flags, + unsigned long timeOutMSecs = 5000) +{ + bool result = false; + if (!r.run(ShGetFileInfoFunction(fileName, attributes, info, flags, &result), timeOutMSecs)) { + qWarning().noquote() << "ShGetFileInfoBackground() timed out for " + << QString::fromWCharArray(fileName); + return false; + } + return result; +} +#endif // !QT_NO_WINCE_SHELLSDK + // from QStyle::standardPalette static inline QPalette standardPalette() { @@ -485,7 +491,9 @@ static QPixmap loadIconFromShell32(int resourceId, QSizeF size) HMODULE hmod = QSystemLibrary::load(L"shell32"); #endif if (hmod) { - HICON iconHandle = (HICON)LoadImage(hmod, MAKEINTRESOURCE(resourceId), IMAGE_ICON, size.width(), size.height(), 0); + HICON iconHandle = + static_cast<HICON>(LoadImage(hmod, MAKEINTRESOURCE(resourceId), + IMAGE_ICON, int(size.width()), int(size.height()), 0)); if (iconHandle) { QPixmap iconpixmap = qt_pixmapFromWinHICON(iconHandle); DestroyIcon(iconHandle); @@ -586,7 +594,7 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) con if (sp == FileLinkIcon || sp == DirLinkIcon || sp == DirLinkOpenIcon) { QPainter painter(&pixmap); QPixmap link = loadIconFromShell32(30, pixmapSize); - painter.drawPixmap(0, 0, pixmapSize.width(), pixmapSize.height(), link); + painter.drawPixmap(0, 0, int(pixmapSize.width()), int(pixmapSize.height()), link); } pixmap.setDevicePixelRatio(scaleFactor); return pixmap; @@ -661,7 +669,8 @@ static QPixmap pixmapFromShellImageList(int iImageList, const SHFILEINFO &info) return result; IImageList *imageList = 0; - HRESULT hr = QWindowsContext::shell32dll.sHGetImageList(iImageList, iID_IImageList, (void **)&imageList); + HRESULT hr = QWindowsContext::shell32dll.sHGetImageList(iImageList, iID_IImageList, + reinterpret_cast<void **>(&imageList)); if (hr != S_OK) return result; HICON hIcon; @@ -693,7 +702,7 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s QPixmap pixmap; const QString filePath = QDir::toNativeSeparators(fileInfo.filePath()); - const int width = size.width(); + const int width = int(size.width()); const int iconSize = width > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON; const int requestedImageListSize = #ifdef USE_IIMAGELIST @@ -716,23 +725,22 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s } SHFILEINFO info; - unsigned int flags = + const unsigned int flags = #ifndef Q_OS_WINCE SHGFI_ICON|iconSize|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX; #else iconSize|SHGFI_SYSICONINDEX; #endif // Q_OS_WINCE - unsigned long val = 0; + + #if !defined(QT_NO_WINCE_SHELLSDK) - if (cacheableDirIcon && useDefaultFolderIcon) { - flags |= SHGFI_USEFILEATTRIBUTES; - val = SHGetFileInfo(L"dummy", - FILE_ATTRIBUTE_DIRECTORY, - &info, sizeof(SHFILEINFO), flags); - } else { - val = SHGetFileInfo(reinterpret_cast<const wchar_t *>(filePath.utf16()), 0, - &info, sizeof(SHFILEINFO), flags); - } + const bool val = cacheableDirIcon && useDefaultFolderIcon + ? shGetFileInfoBackground(m_threadPoolRunner, L"dummy", FILE_ATTRIBUTE_DIRECTORY, + &info, flags | SHGFI_USEFILEATTRIBUTES) + : shGetFileInfoBackground(m_threadPoolRunner, reinterpret_cast<const wchar_t *>(filePath.utf16()), 0, + &info, flags); +#else + const bool val = false; #endif // !QT_NO_WINCE_SHELLSDK // Even if GetFileInfo returns a valid result, hIcon can be empty in some cases diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h index fc004b68c8..cacde98601 100644 --- a/src/plugins/platforms/windows/qwindowstheme.h +++ b/src/plugins/platforms/windows/qwindowstheme.h @@ -34,6 +34,7 @@ #ifndef QWINDOWSTHEME_H #define QWINDOWSTHEME_H +#include "qwindowsthreadpoolrunner.h" #include <qpa/qplatformtheme.h> QT_BEGIN_NAMESPACE @@ -74,6 +75,7 @@ private: static QWindowsTheme *m_instance; QPalette *m_palettes[NPalettes]; QFont *m_fonts[NFonts]; + mutable QWindowsThreadPoolRunner m_threadPoolRunner; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h b/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h new file mode 100644 index 0000000000..0361aa90f5 --- /dev/null +++ b/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSTHREADPOOLRUNNER_H +#define QWINDOWSTHREADPOOLRUNNER_H + +#include <QtCore/QMutex> +#include <QtCore/QRunnable> +#include <QtCore/QThreadPool> +#include <QtCore/QWaitCondition> + +QT_BEGIN_NAMESPACE + +/*! + \class QWindowsThreadPoolRunner + \brief Runs a task in the global instance of QThreadPool + + QThreadPool does not provide a method to wait on a single task, so this needs + to be done by using QWaitCondition/QMutex. + + \internal + \ingroup qt-lighthouse-win +*/ +class QWindowsThreadPoolRunner +{ + Q_DISABLE_COPY(QWindowsThreadPoolRunner) + +#ifndef QT_NO_THREAD + template <class RunnableFunction> // nested class implementing QRunnable to execute a function. + class Runnable : public QRunnable + { + public: + explicit Runnable(QMutex *m, QWaitCondition *c, RunnableFunction f) + : m_mutex(m), m_condition(c), m_function(f) {} + + void run() Q_DECL_OVERRIDE + { + m_function(); + m_mutex->lock(); + m_condition->wakeAll(); + m_mutex->unlock(); + } + + private: + QMutex *m_mutex; + QWaitCondition *m_condition; + RunnableFunction m_function; + }; // class Runnable + +public: + QWindowsThreadPoolRunner() {} + + template <class Function> + bool run(Function f, unsigned long timeOutMSecs = 5000) + { + QThreadPool *pool = QThreadPool::globalInstance(); + Q_ASSERT(pool); + Runnable<Function> *runnable = new Runnable<Function>(&m_mutex, &m_condition, f); + m_mutex.lock(); + pool->start(runnable); + const bool ok = m_condition.wait(&m_mutex, timeOutMSecs); + m_mutex.unlock(); + if (!ok) + pool->cancel(runnable); + return ok; + } + +private: + QMutex m_mutex; + QWaitCondition m_condition; +#else // !QT_NO_THREAD +public: + QWindowsThreadPoolRunner() {} + + template <class Function> + bool run(Function f, unsigned long /* timeOutMSecs */ = 5000) + { + f(); + return true; + } +#endif // QT_NO_THREAD +}; + +QT_END_NAMESPACE + +#endif // QWINDOWSTHREADPOOLRUNNER_H diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 7f45b4817a..e640d38241 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -183,7 +183,7 @@ static QPoint windowPlacementOffset(HWND hwnd, const QPoint &point) return QPoint(0, 0); const QWindowsScreenManager &screenManager = QWindowsContext::instance()->screenManager(); const QWindowsScreen *screen = screenManager.screens().size() == 1 - ? screenManager.screens().first() : screenManager.screenAtDp(point); + ? screenManager.screens().constFirst() : screenManager.screenAtDp(point); if (screen) return screen->availableGeometry().topLeft() - screen->geometry().topLeft(); #else @@ -248,13 +248,6 @@ static QWindow::Visibility windowVisibility_sys(HWND hwnd) return QWindow::Windowed; } -static inline QSize clientSize(HWND hwnd) -{ - RECT rect = { 0, 0, 0, 0 }; - GetClientRect(hwnd, &rect); // Always returns point 0,0, thus unusable for geometry. - return qSizeOfRect(rect); -} - static inline bool windowIsOpenGL(const QWindow *w) { switch (w->surfaceType()) { @@ -1474,7 +1467,9 @@ void QWindowsWindow::handleGeometryChange() // QTBUG-32121: OpenGL/normal windows (with exception of ANGLE) do not receive // expose events when shrinking, synthesize. if (!testFlag(OpenGL_ES2) && isExposed() - && !(m_data.geometry.width() >= previousGeometry.width() || m_data.geometry.height() >= previousGeometry.height())) { + && m_data.geometry.size() != previousGeometry.size() // Exclude plain move + // One dimension grew -> Windows will send expose, no need to synthesize. + && !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) { fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true); } if (previousGeometry.topLeft() != m_data.geometry.topLeft()) { @@ -1564,11 +1559,11 @@ void QWindowsWindow::releaseDC() bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message, WPARAM, LPARAM) { + if (message == WM_ERASEBKGND) // Backing store - ignored. + return true; // Ignore invalid update bounding rectangles if (!GetUpdateRect(m_data.hwnd, 0, FALSE)) return false; - if (message == WM_ERASEBKGND) // Backing store - ignored. - return true; PAINTSTRUCT ps; // Observed painting problems with Aero style disabled (QTBUG-7865). @@ -1921,7 +1916,7 @@ QMargins QWindowsWindow::frameMargins() const // Always skip calculating style-dependent margins for windows claimed to be frameless. // This allows users to remove the margins by handling WM_NCCALCSIZE with WS_THICKFRAME set // to ensure Areo snap still works (QTBUG-40578). - m_data.frame = window()->flags() & Qt::FramelessWindowHint + m_data.frame = m_data.flags & Qt::FramelessWindowHint ? QMargins(0, 0, 0, 0) : QWindowsGeometryHint::frame(style(), exStyle()); clearFlag(FrameDirty); @@ -2094,14 +2089,15 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const // Documentation of MINMAXINFO states that it will only work for the primary screen if (screen && screen == QGuiApplication::primaryScreen()) { - mmi->ptMaxSize.y = screen->availableGeometry().height(); + const QRect availableGeometry = QHighDpi::toNativePixels(screen->availableGeometry(), screen); + mmi->ptMaxSize.y = availableGeometry.height(); // Width, because you can have the taskbar on the sides too. - mmi->ptMaxSize.x = screen->availableGeometry().width(); + mmi->ptMaxSize.x = availableGeometry.width(); // If you have the taskbar on top, or on the left you don't want it at (0,0): - mmi->ptMaxPosition.x = screen->availableGeometry().x(); - mmi->ptMaxPosition.y = screen->availableGeometry().y(); + mmi->ptMaxPosition.x = availableGeometry.x(); + mmi->ptMaxPosition.y = availableGeometry.y(); } else if (!screen){ qWarning() << "window()->screen() returned a null screen"; } diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index 67af5c03ef..eba0593d75 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -63,7 +63,8 @@ HEADERS += \ $$PWD/qplatformfunctions_wince.h \ $$PWD/qwindowsnativeimage.h \ $$PWD/qwindowsnativeinterface.h \ - $$PWD/qwindowsopengltester.h + $$PWD/qwindowsopengltester.h \ + $$PWD/qwindowsthreadpoolrunner.h INCLUDEPATH += $$PWD diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro index cc0373c077..2e0f723693 100644 --- a/src/plugins/platforms/windows/windows.pro +++ b/src/plugins/platforms/windows/windows.pro @@ -1,10 +1,5 @@ TARGET = qwindows -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = QWindowsIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) - QT *= core-private QT *= gui-private QT *= platformsupport-private @@ -25,3 +20,8 @@ HEADERS += \ qwindowsgdinativeinterface.h OTHER_FILES += windows.json + +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QWindowsIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp index 4517200a2d..fc7ab15f73 100644 --- a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp +++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp @@ -47,6 +47,9 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpaBackingStore, "qt.qpa.backingstore") +Q_LOGGING_CATEGORY(lcQpaBackingStoreVerbose, "qt.qpa.backingstore.verbose") + class QWinRTBackingStorePrivate { public: @@ -62,6 +65,7 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window) : QPlatformBackingStore(window), d_ptr(new QWinRTBackingStorePrivate) { Q_D(QWinRTBackingStore); + qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window; d->initialized = false; d->screen = static_cast<QWinRTScreen*>(window->screen()->handle()); @@ -73,6 +77,7 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window) bool QWinRTBackingStore::initialize() { Q_D(QWinRTBackingStore); + qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << d->initialized; if (d->initialized) return true; @@ -94,6 +99,7 @@ bool QWinRTBackingStore::initialize() QWinRTBackingStore::~QWinRTBackingStore() { + qCDebug(lcQpaBackingStore) << __FUNCTION__ << this; } QPaintDevice *QWinRTBackingStore::paintDevice() @@ -107,6 +113,8 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo Q_D(QWinRTBackingStore); Q_UNUSED(offset) + qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << this << window << region; + if (d->size.isEmpty()) return; @@ -140,6 +148,8 @@ void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents Q_D(QWinRTBackingStore); Q_UNUSED(staticContents) + qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << this << size; + if (!initialize()) return; @@ -169,11 +179,14 @@ QImage QWinRTBackingStore::toImage() const void QWinRTBackingStore::beginPaint(const QRegion ®ion) { + qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << this << region; + resize(window()->size(), region); } void QWinRTBackingStore::endPaint() { + qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << this; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.h b/src/plugins/platforms/winrt/qwinrtbackingstore.h index 20b27a3865..b5d9dfed4f 100644 --- a/src/plugins/platforms/winrt/qwinrtbackingstore.h +++ b/src/plugins/platforms/winrt/qwinrtbackingstore.h @@ -39,9 +39,13 @@ #include <qpa/qplatformbackingstore.h> #include <QtCore/QScopedPointer> +#include <QtCore/QLoggingCategory> QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcQpaBackingStore) +Q_DECLARE_LOGGING_CATEGORY(lcQpaBackingStoreVerbose) + class QWinRTScreen; class QWinRTBackingStorePrivate; diff --git a/src/plugins/platforms/winrt/qwinrtclipboard.cpp b/src/plugins/platforms/winrt/qwinrtclipboard.cpp new file mode 100644 index 0000000000..4e71490902 --- /dev/null +++ b/src/plugins/platforms/winrt/qwinrtclipboard.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwinrtclipboard.h" + +#include <QtCore/QCoreApplication> +#include <QtCore/qfunctions_winrt.h> +#include <QtCore/private/qeventdispatcher_winrt_p.h> + +#include <Windows.ApplicationModel.datatransfer.h> + +#include <functional> + +using namespace ABI::Windows::ApplicationModel::DataTransfer; +using namespace ABI::Windows::Foundation; +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; + +typedef IEventHandler<IInspectable *> ContentChangedHandler; + +#define RETURN_NULLPTR_IF_FAILED(msg) RETURN_IF_FAILED(msg, return nullptr) + +QT_BEGIN_NAMESPACE + +QWinRTClipboard::QWinRTClipboard() +{ +#ifndef Q_OS_WINPHONE + QEventDispatcherWinRT::runOnXamlThread([this]() { + HRESULT hr; + hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_Clipboard).Get(), + &m_nativeClipBoard); + Q_ASSERT_SUCCEEDED(hr); + + EventRegistrationToken tok; + hr = m_nativeClipBoard->add_ContentChanged(Callback<ContentChangedHandler>(this, &QWinRTClipboard::onContentChanged).Get(), &tok); + Q_ASSERT_SUCCEEDED(hr); + + return hr; + }); +#endif // !Q_OS_WINPHONE +} + +QMimeData *QWinRTClipboard::mimeData(QClipboard::Mode mode) +{ + if (!supportsMode(mode)) + return nullptr; + +#ifndef Q_OS_WINPHONE + ComPtr<IDataPackageView> view; + HRESULT hr; + hr = m_nativeClipBoard->GetContent(&view); + RETURN_NULLPTR_IF_FAILED("Could not get clipboard content."); + + ComPtr<IAsyncOperation<HSTRING>> op; + HString result; + // This throws a security exception (WinRT originate error / 0x40080201. + // Unfortunately there seems to be no way to avoid this, neither + // running on the XAML thread, nor some other way. Stack Overflow + // confirms this problem since Windows (Phone) 8.0. + hr = view->GetTextAsync(&op); + RETURN_NULLPTR_IF_FAILED("Could not get clipboard text."); + + hr = QWinRTFunctions::await(op, result.GetAddressOf()); + RETURN_NULLPTR_IF_FAILED("Could not get clipboard text content"); + + quint32 size; + const wchar_t *textStr = result.GetRawBuffer(&size); + QString text = QString::fromWCharArray(textStr, size); + text.replace(QStringLiteral("\r\n"), QStringLiteral("\n")); + m_mimeData.setText(text); + + return &m_mimeData; +#else // Q_OS_WINPHONE + return QPlatformClipboard::mimeData(mode); +#endif // Q_OS_WINPHONE +} + +// Inspired by QWindowsMimeText::convertFromMime +inline QString convertToWindowsLineEnding(const QString &text) +{ + const QChar *u = text.unicode(); + QString res; + const int s = text.length(); + int maxsize = s + s / 40 + 3; + res.resize(maxsize); + int ri = 0; + bool cr = false; + for (int i = 0; i < s; ++i) { + if (*u == QLatin1Char('\r')) + cr = true; + else { + if (*u == QLatin1Char('\n') && !cr) + res[ri++] = QLatin1Char('\r'); + cr = false; + } + res[ri++] = *u; + if (ri+3 >= maxsize) { + maxsize += maxsize / 4; + res.resize(maxsize); + } + ++u; + } + res.truncate(ri); + return res; +} + +void QWinRTClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) +{ + if (!supportsMode(mode)) + return; + +#ifndef Q_OS_WINPHONE + const QString text = data->text(); + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, text]() { + HRESULT hr; + ComPtr<IDataPackage> package; + hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_DataPackage).Get(), + &package); + + const QString nativeString = convertToWindowsLineEnding(text); + HStringReference textRef(reinterpret_cast<LPCWSTR>(nativeString.utf16()), nativeString.length()); + + hr = package->SetText(textRef.Get()); + RETURN_HR_IF_FAILED("Could not set text to clipboard data package."); + + hr = m_nativeClipBoard->SetContent(package.Get()); + RETURN_HR_IF_FAILED("Could not set clipboard content."); + return S_OK; + }); + RETURN_VOID_IF_FAILED("Could not set clipboard text."); + emitChanged(mode); +#else // Q_OS_WINPHONE + QPlatformClipboard::setMimeData(data, mode); +#endif // Q_OS_WINPHONE +} + +bool QWinRTClipboard::supportsMode(QClipboard::Mode mode) const +{ +#ifndef Q_OS_WINPHONE + return mode == QClipboard::Clipboard; +#else + return QPlatformClipboard::supportsMode(mode); +#endif +} + +HRESULT QWinRTClipboard::onContentChanged(IInspectable *, IInspectable *) +{ + emitChanged(QClipboard::Clipboard); + return S_OK; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtclipboard.h b/src/plugins/platforms/winrt/qwinrtclipboard.h new file mode 100644 index 0000000000..1fb10bdfc0 --- /dev/null +++ b/src/plugins/platforms/winrt/qwinrtclipboard.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINRTPLATFORMCLIPBOARD_H +#define QWINRTPLATFORMCLIPBOARD_H + +#include <qpa/qplatformclipboard.h> +#include <QMimeData> + +#include <wrl.h> + +#ifndef Q_OS_WINPHONE +namespace ABI { + namespace Windows { + namespace ApplicationModel { + namespace DataTransfer { + struct IClipboardStatics; + } + } + } +} +#endif // !Q_OS_WINPHONE + +QT_BEGIN_NAMESPACE + +class QWinRTClipboard: public QPlatformClipboard +{ +public: + QWinRTClipboard(); + + QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; + void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; + bool supportsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; + + HRESULT onContentChanged(IInspectable *, IInspectable *); +private: +#ifndef Q_OS_WINPHONE + Microsoft::WRL::ComPtr<ABI::Windows::ApplicationModel::DataTransfer::IClipboardStatics> m_nativeClipBoard; +#endif + QMimeData m_mimeData; +}; + +QT_END_NAMESPACE + +#endif // QWINRTPLATFORMCLIPBOARD_H diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp index 793256a83f..22fb8cb63e 100644 --- a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp +++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp @@ -47,6 +47,20 @@ using namespace Microsoft::WRL; QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts") + +QDebug operator<<(QDebug d, const QFontDef &def) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "Family=" << def.family << " Stylename=" << def.styleName + << " pointsize=" << def.pointSize << " pixelsize=" << def.pixelSize + << " styleHint=" << def.styleHint << " weight=" << def.weight + << " stretch=" << def.stretch << " hintingPreference=" + << def.hintingPreference; + return d; +} + // Based on unicode range tables at http://www.microsoft.com/typography/otspec/os2.htm#ur static QFontDatabase::WritingSystem writingSystemFromUnicodeRange(const DWRITE_UNICODE_RANGE &range) { @@ -114,6 +128,7 @@ static QFontDatabase::WritingSystem writingSystemFromUnicodeRange(const DWRITE_U QString QWinRTFontDatabase::fontDir() const { + qCDebug(lcQpaFonts) << __FUNCTION__; QString fontDirectory = QBasicFontDatabase::fontDir(); if (!QFile::exists(fontDirectory)) { // Fall back to app directory + fonts, and just app directory after that @@ -130,6 +145,8 @@ QString QWinRTFontDatabase::fontDir() const QWinRTFontDatabase::~QWinRTFontDatabase() { + qCDebug(lcQpaFonts) << __FUNCTION__; + foreach (IDWriteFontFile *fontFile, m_fonts.keys()) fontFile->Release(); @@ -149,6 +166,8 @@ bool QWinRTFontDatabase::fontsAlwaysScalable() const void QWinRTFontDatabase::populateFontDatabase() { + qCDebug(lcQpaFonts) << __FUNCTION__; + ComPtr<IDWriteFactory1> factory; HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, __uuidof(IDWriteFactory1), &factory); if (FAILED(hr)) { @@ -204,6 +223,8 @@ void QWinRTFontDatabase::populateFontDatabase() void QWinRTFontDatabase::populateFamily(const QString &familyName) { + qCDebug(lcQpaFonts) << __FUNCTION__ << familyName; + IDWriteFontFamily *fontFamily = m_fontFamilies.value(familyName); if (!fontFamily) { qWarning("The font family %s was not found.", qPrintable(familyName)); @@ -367,6 +388,8 @@ void QWinRTFontDatabase::populateFamily(const QString &familyName) QFontEngine *QWinRTFontDatabase::fontEngine(const QFontDef &fontDef, void *handle) { + qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef << handle; + if (!handle) // Happens if a font family population failed return 0; @@ -436,6 +459,8 @@ QStringList QWinRTFontDatabase::fallbacksForFamily(const QString &family, QFont: Q_UNUSED(styleHint) Q_UNUSED(script) + qCDebug(lcQpaFonts) << __FUNCTION__ << family; + QStringList result; if (family == QLatin1String("Helvetica")) result.append(QStringLiteral("Arial")); @@ -445,6 +470,8 @@ QStringList QWinRTFontDatabase::fallbacksForFamily(const QString &family, QFont: void QWinRTFontDatabase::releaseHandle(void *handle) { + qCDebug(lcQpaFonts) << __FUNCTION__ << handle; + if (!handle) return; diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.h b/src/plugins/platforms/winrt/qwinrtfontdatabase.h index 41619f5bd8..e8495e202f 100644 --- a/src/plugins/platforms/winrt/qwinrtfontdatabase.h +++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.h @@ -38,12 +38,15 @@ #define QWINRTFONTDATABASE_H #include <QtPlatformSupport/private/qbasicfontdatabase_p.h> +#include <QtCore/QLoggingCategory> struct IDWriteFontFile; struct IDWriteFontFamily; QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts) + struct FontDescription { quint32 index; diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp index a0474b6710..72fc378760 100644 --- a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp @@ -54,6 +54,8 @@ typedef ITypedEventHandler<InputPane*, InputPaneVisibilityEventArgs*> InputPaneV QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.input.methods") + inline QRectF getInputPaneRect(IInputPane *pane, qreal scaleFactor) { Rect rect; @@ -78,6 +80,8 @@ inline QRectF getInputPaneRect(IInputPane *pane, qreal scaleFactor) QWinRTInputContext::QWinRTInputContext(QWinRTScreen *screen) : m_screen(screen) { + qCDebug(lcQpaInputMethods) << __FUNCTION__ << screen; + IInputPaneStatics *statics; if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(), &statics))) { @@ -114,6 +118,7 @@ bool QWinRTInputContext::isInputPanelVisible() const HRESULT QWinRTInputContext::onShowing(IInputPane *pane, IInputPaneVisibilityEventArgs *) { + qCDebug(lcQpaInputMethods) << __FUNCTION__ << pane; m_isInputPanelVisible = true; emitInputPanelVisibleChanged(); return handleVisibilityChange(pane); @@ -121,6 +126,7 @@ HRESULT QWinRTInputContext::onShowing(IInputPane *pane, IInputPaneVisibilityEven HRESULT QWinRTInputContext::onHiding(IInputPane *pane, IInputPaneVisibilityEventArgs *) { + qCDebug(lcQpaInputMethods) << __FUNCTION__ << pane; m_isInputPanelVisible = false; emitInputPanelVisibleChanged(); return handleVisibilityChange(pane); @@ -128,6 +134,7 @@ HRESULT QWinRTInputContext::onHiding(IInputPane *pane, IInputPaneVisibilityEvent HRESULT QWinRTInputContext::handleVisibilityChange(IInputPane *pane) { + qCDebug(lcQpaInputMethods) << __FUNCTION__ << pane; const QRectF keyboardRect = getInputPaneRect(pane, m_screen->scaleFactor()); if (m_keyboardRect != keyboardRect) { m_keyboardRect = keyboardRect; @@ -165,31 +172,35 @@ static HRESULT getInputPane(ComPtr<IInputPane2> *inputPane2) void QWinRTInputContext::showInputPanel() { + qCDebug(lcQpaInputMethods) << __FUNCTION__; + QEventDispatcherWinRT::runOnXamlThread([&]() { ComPtr<IInputPane2> inputPane; HRESULT hr = getInputPane(&inputPane); if (FAILED(hr)) - return hr; + return S_OK; boolean success; hr = inputPane->TryShow(&success); if (FAILED(hr) || !success) qErrnoWarning(hr, "Failed to show input panel."); - return hr; + return S_OK; }); } void QWinRTInputContext::hideInputPanel() { + qCDebug(lcQpaInputMethods) << __FUNCTION__; + QEventDispatcherWinRT::runOnXamlThread([&]() { ComPtr<IInputPane2> inputPane; HRESULT hr = getInputPane(&inputPane); if (FAILED(hr)) - return hr; + return S_OK; boolean success; hr = inputPane->TryHide(&success); if (FAILED(hr) || !success) qErrnoWarning(hr, "Failed to hide input panel."); - return hr; + return S_OK; }); } diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.h b/src/plugins/platforms/winrt/qwinrtinputcontext.h index 6f88ff46e6..d5a1a40efc 100644 --- a/src/plugins/platforms/winrt/qwinrtinputcontext.h +++ b/src/plugins/platforms/winrt/qwinrtinputcontext.h @@ -39,6 +39,7 @@ #include <qpa/qplatforminputcontext.h> #include <QtCore/QRectF> +#include <QtCore/QLoggingCategory> #include <wrl.h> @@ -58,6 +59,8 @@ namespace ABI { QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcQpaInputMethods) + class QWinRTScreen; class QWinRTInputContext : public QPlatformInputContext { diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index 9dac667ce5..30c0e81e21 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -44,6 +44,7 @@ #include "qwinrteglcontext.h" #include "qwinrtfontdatabase.h" #include "qwinrttheme.h" +#include "qwinrtclipboard.h" #include <QtGui/QOffscreenSurface> #include <QtGui/QOpenGLContext> @@ -111,6 +112,7 @@ class QWinRTIntegrationPrivate public: QPlatformFontDatabase *fontDatabase; QPlatformServices *platformServices; + QPlatformClipboard *clipboard; QWinRTScreen *mainScreen; QScopedPointer<QWinRTInputContext> inputContext; @@ -195,6 +197,7 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate) screenAdded(d->mainScreen); d->platformServices = new QWinRTServices; + d->clipboard = new QWinRTClipboard; } QWinRTIntegration::~QWinRTIntegration() @@ -300,6 +303,12 @@ QPlatformServices *QWinRTIntegration::services() const return d->platformServices; } +QPlatformClipboard *QWinRTIntegration::clipboard() const +{ + Q_D(const QWinRTIntegration); + return d->clipboard; +} + Qt::KeyboardModifiers QWinRTIntegration::queryKeyboardModifiers() const { Q_D(const QWinRTIntegration); diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h index 9bf5d27973..1ed286ab2e 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.h +++ b/src/plugins/platforms/winrt/qwinrtintegration.h @@ -93,6 +93,7 @@ public: QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE; QPlatformServices *services() const Q_DECL_OVERRIDE; + QPlatformClipboard *clipboard() const Q_DECL_OVERRIDE; Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE; QStringList themeNames() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 4c4d553b2d..47e68ae0af 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -39,8 +39,10 @@ #include "qwinrtbackingstore.h" #include "qwinrtinputcontext.h" #include "qwinrtcursor.h" +#include "qwinrtwindow.h" #include <private/qeventdispatcher_winrt_p.h> +#include <QtCore/QLoggingCategory> #include <QtGui/QSurfaceFormat> #include <QtGui/QGuiApplication> #include <qpa/qwindowsysteminterface.h> @@ -469,6 +471,7 @@ QWinRTScreen::QWinRTScreen() : d_ptr(new QWinRTScreenPrivate) { Q_D(QWinRTScreen); + qCDebug(lcQpaWindows) << __FUNCTION__; d->orientation = Qt::PrimaryOrientation; d->touchDevice = Q_NULLPTR; @@ -553,6 +556,7 @@ QWinRTScreen::QWinRTScreen() QWinRTScreen::~QWinRTScreen() { Q_D(QWinRTScreen); + qCDebug(lcQpaWindows) << __FUNCTION__ << this; // Unregister callbacks HRESULT hr; @@ -631,6 +635,12 @@ QDpi QWinRTScreen::logicalDpi() const return QDpi(d->logicalDpi, d->logicalDpi); } +qreal QWinRTScreen::pixelDensity() const +{ + Q_D(const QWinRTScreen); + return qRound(d->logicalDpi / 96); +} + qreal QWinRTScreen::scaleFactor() const { Q_D(const QWinRTScreen); @@ -697,6 +707,8 @@ Xaml::IDependencyObject *QWinRTScreen::canvas() const void QWinRTScreen::setStatusBarVisibility(bool visible, QWindow *window) { Q_D(QWinRTScreen); + qCDebug(lcQpaWindows) << __FUNCTION__ << window << visible; + const Qt::WindowFlags windowType = window->flags() & Qt::WindowType_Mask; if (!window || (windowType != Qt::Window && windowType != Qt::Dialog)) return; @@ -768,6 +780,7 @@ QWindow *QWinRTScreen::topWindow() const void QWinRTScreen::addWindow(QWindow *window) { Q_D(QWinRTScreen); + qCDebug(lcQpaWindows) << __FUNCTION__ << window; if (window == topWindow()) return; @@ -785,6 +798,7 @@ void QWinRTScreen::addWindow(QWindow *window) void QWinRTScreen::removeWindow(QWindow *window) { Q_D(QWinRTScreen); + qCDebug(lcQpaWindows) << __FUNCTION__ << window; #ifdef Q_OS_WINPHONE if (window->visibility() == QWindow::Minimized) @@ -1131,6 +1145,7 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs * hr = d->coreWindow->get_Bounds(&size); RETURN_OK_IF_FAILED("Failed to get window bounds"); d->logicalSize = QSizeF(size.Width, size.Height); + qCDebug(lcQpaWindows) << __FUNCTION__ << d->logicalSize; QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry()); QPlatformScreen::resizeMaximizedWindows(); handleExpose(); @@ -1140,6 +1155,7 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs * HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args) { Q_D(QWinRTScreen); + qCDebug(lcQpaWindows) << __FUNCTION__; CoreWindowActivationState activationState; args->get_WindowActivationState(&activationState); @@ -1159,6 +1175,8 @@ HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args HRESULT QWinRTScreen::onClosed(ICoreWindow *, ICoreWindowEventArgs *) { + qCDebug(lcQpaWindows) << __FUNCTION__; + foreach (QWindow *w, QGuiApplication::topLevelWindows()) QWindowSystemInterface::handleCloseEvent(w); return S_OK; @@ -1170,6 +1188,7 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEvent boolean visible; HRESULT hr = args ? args->get_Visible(&visible) : d->coreWindow->get_Visible(&visible); RETURN_OK_IF_FAILED("Failed to get visibility."); + qCDebug(lcQpaWindows) << __FUNCTION__ << visible; QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden); if (visible) handleExpose(); @@ -1179,7 +1198,7 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEvent HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *) { Q_D(QWinRTScreen); - + qCDebug(lcQpaWindows) << __FUNCTION__; DisplayOrientations displayOrientation; HRESULT hr = d->displayInformation->get_CurrentOrientation(&displayOrientation); RETURN_OK_IF_FAILED("Failed to get current orientations."); @@ -1187,7 +1206,8 @@ HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable * Qt::ScreenOrientation newOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation))); if (d->orientation != newOrientation) { d->orientation = newOrientation; -#ifdef Q_OS_WINPHONE + qCDebug(lcQpaWindows) << " New orientation:" << newOrientation; +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) onSizeChanged(nullptr, nullptr); #endif QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation); @@ -1211,6 +1231,8 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *) hr = d->displayInformation->get_ResolutionScale(&resolutionScale); d->scaleFactor = qreal(resolutionScale) / 100; #endif + qCDebug(lcQpaWindows) << __FUNCTION__ << "Scale Factor:" << d->scaleFactor; + RETURN_OK_IF_FAILED("Failed to get scale factor"); FLOAT dpi; @@ -1225,6 +1247,8 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *) hr = d->displayInformation->get_RawDpiY(&dpi); RETURN_OK_IF_FAILED("Failed to get y raw DPI."); d->physicalDpi.second = dpi ? dpi : 96.0; + qCDebug(lcQpaWindows) << __FUNCTION__ << "Logical DPI:" << d->logicalDpi + << "Physical DPI:" << d->physicalDpi; return S_OK; } @@ -1232,12 +1256,14 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *) #ifdef Q_OS_WINPHONE HRESULT QWinRTScreen::onStatusBarShowing(IStatusBar *, IInspectable *) { + qCDebug(lcQpaWindows) << __FUNCTION__; onSizeChanged(nullptr, nullptr); return S_OK; } HRESULT QWinRTScreen::onStatusBarHiding(IStatusBar *, IInspectable *) { + qCDebug(lcQpaWindows) << __FUNCTION__; onSizeChanged(nullptr, nullptr); return S_OK; } diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index 0043b2cfa3..ac9db9bfef 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -93,6 +93,7 @@ public: QImage::Format format() const Q_DECL_OVERRIDE; QSizeF physicalSize() const Q_DECL_OVERRIDE; QDpi logicalDpi() const Q_DECL_OVERRIDE; + qreal pixelDensity() const Q_DECL_OVERRIDE; qreal scaleFactor() const; QPlatformCursor *cursor() const Q_DECL_OVERRIDE; Qt::KeyboardModifiers keyboardModifiers() const; diff --git a/src/plugins/platforms/winrt/qwinrttheme.cpp b/src/plugins/platforms/winrt/qwinrttheme.cpp index 7d09551f5b..7ef13fd0aa 100644 --- a/src/plugins/platforms/winrt/qwinrttheme.cpp +++ b/src/plugins/platforms/winrt/qwinrttheme.cpp @@ -56,6 +56,8 @@ using namespace ABI::Windows::UI::ViewManagement; QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpaTheme, "qt.qpa.theme") + static IUISettings *uiSettings() { static ComPtr<IUISettings> settings; @@ -285,12 +287,14 @@ QWinRTTheme::QWinRTTheme() : d_ptr(new QWinRTThemePrivate) { Q_D(QWinRTTheme); + qCDebug(lcQpaTheme) << __FUNCTION__; nativeColorSettings(d->palette); } bool QWinRTTheme::usePlatformNativeDialog(DialogType type) const { + qCDebug(lcQpaTheme) << __FUNCTION__ << type; static bool useNativeDialogs = qEnvironmentVariableIsSet("QT_USE_WINRT_NATIVE_DIALOGS") ? qEnvironmentVariableIntValue("QT_USE_WINRT_NATIVE_DIALOGS") : true; @@ -301,6 +305,7 @@ bool QWinRTTheme::usePlatformNativeDialog(DialogType type) const QPlatformDialogHelper *QWinRTTheme::createPlatformDialogHelper(DialogType type) const { + qCDebug(lcQpaTheme) << __FUNCTION__ << type; switch (type) { case FileDialog: return new QWinRTFileDialogHelper; @@ -314,6 +319,7 @@ QPlatformDialogHelper *QWinRTTheme::createPlatformDialogHelper(DialogType type) QVariant QWinRTTheme::styleHint(QPlatformIntegration::StyleHint hint) { + qCDebug(lcQpaTheme) << __FUNCTION__ << hint; HRESULT hr; switch (hint) { case QPlatformIntegration::CursorFlashTime: { @@ -363,6 +369,7 @@ QVariant QWinRTTheme::styleHint(QPlatformIntegration::StyleHint hint) const QPalette *QWinRTTheme::palette(Palette type) const { Q_D(const QWinRTTheme); + qCDebug(lcQpaTheme) << __FUNCTION__ << type; if (type == SystemPalette) return &d->palette; return QPlatformTheme::palette(type); diff --git a/src/plugins/platforms/winrt/qwinrttheme.h b/src/plugins/platforms/winrt/qwinrttheme.h index 2e159cbd55..e1a0e14964 100644 --- a/src/plugins/platforms/winrt/qwinrttheme.h +++ b/src/plugins/platforms/winrt/qwinrttheme.h @@ -39,9 +39,12 @@ #include <qpa/qplatformtheme.h> #include <qpa/qplatformintegration.h> +#include <QtCore/QLoggingCategory> QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcQpaTheme) + class QWinRTThemePrivate; class QWinRTTheme : public QPlatformTheme { diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index 034879c478..07904ffbf7 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -69,6 +69,8 @@ using namespace ABI::Windows::UI::Xaml::Controls; QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpaWindows, "qt.qpa.windows"); + static void setUIElementVisibility(IUIElement *uiElement, bool visibility) { Q_ASSERT(uiElement); @@ -101,6 +103,7 @@ QWinRTWindow::QWinRTWindow(QWindow *window) , d_ptr(new QWinRTWindowPrivate) { Q_D(QWinRTWindow); + qCDebug(lcQpaWindows) << __FUNCTION__ << this; d->surface = EGL_NO_SURFACE; d->display = EGL_NO_DISPLAY; @@ -161,6 +164,7 @@ QWinRTWindow::QWinRTWindow(QWindow *window) QWinRTWindow::~QWinRTWindow() { Q_D(QWinRTWindow); + qCDebug(lcQpaWindows) << __FUNCTION__ << this; HRESULT hr; hr = QEventDispatcherWinRT::runOnXamlThread([d]() { @@ -187,6 +191,8 @@ QWinRTWindow::~QWinRTWindow() if (!d->surface) return; + qCDebug(lcQpaWindows) << __FUNCTION__ << ": Destroying surface"; + EGLBoolean value = eglDestroySurface(d->display, d->surface); d->surface = EGL_NO_SURFACE; if (value == EGL_FALSE) @@ -214,12 +220,15 @@ bool QWinRTWindow::isExposed() const void QWinRTWindow::setGeometry(const QRect &rect) { Q_D(QWinRTWindow); + qCDebug(lcQpaWindows) << __FUNCTION__ << this << rect; const Qt::WindowFlags windowFlags = window()->flags(); const Qt::WindowFlags windowType = windowFlags & Qt::WindowType_Mask; if (window()->isTopLevel() && (windowType == Qt::Window || windowType == Qt::Dialog)) { - QPlatformWindow::setGeometry(windowFlags & Qt::MaximizeUsingFullscreenGeometryHint - ? d->screen->geometry() : d->screen->availableGeometry()); + const QRect screenRect = windowFlags & Qt::MaximizeUsingFullscreenGeometryHint + ? d->screen->geometry() : d->screen->availableGeometry(); + qCDebug(lcQpaWindows) << __FUNCTION__ << "top-level, overwrite" << screenRect; + QPlatformWindow::setGeometry(screenRect); QWindowSystemInterface::handleGeometryChange(window(), geometry()); } else { QPlatformWindow::setGeometry(rect); @@ -243,6 +252,8 @@ void QWinRTWindow::setGeometry(const QRect &rect) Q_ASSERT_SUCCEEDED(hr); hr = frameworkElement->put_Height(size.height()); Q_ASSERT_SUCCEEDED(hr); + qCDebug(lcQpaWindows) << __FUNCTION__ << "(setGeometry Xaml)" << this + << topLeft << size; return S_OK; }); Q_ASSERT_SUCCEEDED(hr); @@ -251,6 +262,8 @@ void QWinRTWindow::setGeometry(const QRect &rect) void QWinRTWindow::setVisible(bool visible) { Q_D(QWinRTWindow); + qCDebug(lcQpaWindows) << __FUNCTION__ << this << visible; + if (!window()->isTopLevel()) return; if (visible) { @@ -272,6 +285,7 @@ void QWinRTWindow::setWindowTitle(const QString &title) void QWinRTWindow::raise() { Q_D(QWinRTWindow); + qCDebug(lcQpaWindows) << __FUNCTION__ << this; if (!window()->isTopLevel()) return; d->screen->raise(window()); @@ -280,6 +294,7 @@ void QWinRTWindow::raise() void QWinRTWindow::lower() { Q_D(QWinRTWindow); + qCDebug(lcQpaWindows) << __FUNCTION__ << this; if (!window()->isTopLevel()) return; d->screen->lower(window()); @@ -299,6 +314,8 @@ qreal QWinRTWindow::devicePixelRatio() const void QWinRTWindow::setWindowState(Qt::WindowState state) { Q_D(QWinRTWindow); + qCDebug(lcQpaWindows) << __FUNCTION__ << this << state; + if (d->state == state) return; diff --git a/src/plugins/platforms/winrt/qwinrtwindow.h b/src/plugins/platforms/winrt/qwinrtwindow.h index 9ac7adbf4d..36f5b9de84 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.h +++ b/src/plugins/platforms/winrt/qwinrtwindow.h @@ -37,12 +37,15 @@ #ifndef QWINRTWINDOW_H #define QWINRTWINDOW_H +#include <QtCore/QLoggingCategory> #include <qpa/qplatformwindow.h> #include <qpa/qwindowsysteminterface.h> #include <EGL/egl.h> QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcQpaWindows) + class QWinRTWindowPrivate; class QWinRTWindow : public QPlatformWindow { diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro index be6aad02d1..261295ef0b 100644 --- a/src/plugins/platforms/winrt/winrt.pro +++ b/src/plugins/platforms/winrt/winrt.pro @@ -1,10 +1,6 @@ TARGET = qwinrt -CONFIG -= precompile_header -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = QWinRTIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) +CONFIG -= precompile_header QT += core-private gui-private platformsupport-private @@ -16,6 +12,7 @@ INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/freetype/include SOURCES = \ main.cpp \ qwinrtbackingstore.cpp \ + qwinrtclipboard.cpp \ qwinrtcursor.cpp \ qwinrteglcontext.cpp \ qwinrteventdispatcher.cpp \ @@ -33,6 +30,7 @@ SOURCES = \ HEADERS = \ qwinrtbackingstore.h \ + qwinrtclipboard.h \ qwinrtcursor.h \ qwinrteglcontext.h \ qwinrteventdispatcher.h \ @@ -48,3 +46,8 @@ HEADERS = \ qwinrtwindow.h OTHER_FILES += winrt.json + +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QWinRTIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/xcb_egl.pro b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/xcb_egl.pro index 28a572a2c9..6d52332bad 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/xcb_egl.pro +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/xcb_egl.pro @@ -1,10 +1,5 @@ TARGET = qxcb-egl-integration -PLUGIN_CLASS_NAME = QXcbEglIntegrationPlugin -PLUGIN_TYPE = xcbglintegrations - -load(qt_plugin) - include(../gl_integrations_plugin_base.pri) CONFIG += egl @@ -22,3 +17,7 @@ SOURCES += \ qxcbeglwindow.cpp \ qxcbeglmain.cpp \ qxcbeglnativeinterfacehandler.cpp + +PLUGIN_CLASS_NAME = QXcbEglIntegrationPlugin +PLUGIN_TYPE = xcbglintegrations +load(qt_plugin) diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro index 1c577e5dc9..67fd68765a 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro @@ -1,10 +1,5 @@ TARGET = qxcb-glx-integration -PLUGIN_CLASS_NAME = QXcbGlxIntegrationPlugin -PLUGIN_TYPE = xcbglintegrations - -load(qt_plugin) - include(../gl_integrations_plugin_base.pri) #should be removed from the sources @@ -31,3 +26,7 @@ SOURCES += \ qxcbglxwindow.cpp \ qglxintegration.cpp \ qxcbglxnativeinterfacehandler.cpp + +PLUGIN_CLASS_NAME = QXcbGlxIntegrationPlugin +PLUGIN_TYPE = xcbglintegrations +load(qt_plugin) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 9cedd296e1..05c02249cc 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -613,8 +613,8 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra initializeScreens(); initializeXRender(); - m_xi2Enabled = false; #if defined(XCB_USE_XINPUT2) + m_xi2Enabled = false; initializeXInput2(); #endif initializeXShape(); @@ -1133,8 +1133,16 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) handleClientMessageEvent((xcb_client_message_event_t *)event); break; case XCB_ENTER_NOTIFY: +#ifdef XCB_USE_XINPUT22 + if (isAtLeastXI22() && xi2MouseEvents()) + break; +#endif HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent); case XCB_LEAVE_NOTIFY: +#ifdef XCB_USE_XINPUT22 + if (isAtLeastXI22() && xi2MouseEvents()) + break; +#endif m_keyboard->updateXKBStateFromCore(((xcb_leave_notify_event_t *)event)->state); HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent); case XCB_FOCUS_IN: @@ -1922,6 +1930,7 @@ static const char * xcb_atomnames = { "Abs MT Position Y\0" "Abs MT Touch Major\0" "Abs MT Touch Minor\0" + "Abs MT Orientation\0" "Abs MT Pressure\0" "Abs MT Tracking ID\0" "Max Contacts\0" @@ -1945,7 +1954,9 @@ static const char * xcb_atomnames = { "_COMPIZ_DECOR_PENDING\0" "_COMPIZ_DECOR_REQUEST\0" "_COMPIZ_DECOR_DELETE_PIXMAP\0" - "_COMPIZ_TOOLKIT_ACTION\0" // \0\0 terminates loop. + "_COMPIZ_TOOLKIT_ACTION\0" + "_GTK_LOAD_ICONTHEMES\0" + // \0\0 terminates loop. }; QXcbAtom::Atom QXcbConnection::qatom(xcb_atom_t xatom) const @@ -2216,13 +2227,15 @@ void QXcbConnection::initializeXKB() #endif } +#if defined(XCB_USE_XINPUT22) bool QXcbConnection::xi2MouseEvents() const { static bool mouseViaXI2 = !qEnvironmentVariableIsSet("QT_XCB_NO_XI2_MOUSE"); - // Don't use XInput2 when Xinerama extension is enabled, - // because it causes problems with multi-monitor setup. + // FIXME: Don't use XInput2 mouse events when Xinerama extension + // is enabled, because it causes problems with multi-monitor setup. return mouseViaXI2 && !has_xinerama_extension; } +#endif #if defined(XCB_USE_XINPUT2) static int xi2ValuatorOffset(unsigned char *maskPtr, int maskLen, int number) diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index a6a7b9e7ca..86af5dc9c5 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -261,6 +261,7 @@ namespace QXcbAtom { AbsMTPositionY, AbsMTTouchMajor, AbsMTTouchMinor, + AbsMTOrientation, AbsMTPressure, AbsMTTrackingID, MaxContacts, @@ -287,6 +288,7 @@ namespace QXcbAtom { _COMPIZ_DECOR_REQUEST, _COMPIZ_DECOR_DELETE_PIXMAP, _COMPIZ_TOOLKIT_ACTION, + _GTK_LOAD_ICONTHEMES, NPredefinedAtoms, @@ -347,8 +349,10 @@ public: virtual void handleFocusInEvent(const xcb_focus_in_event_t *) {} virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {} virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {} - virtual void handleXIMouseEvent(xcb_ge_event_t *) {} - +#ifdef XCB_USE_XINPUT22 + virtual void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource = Qt::MouseEventNotSynthesized) {} + virtual void handleXIEnterLeave(xcb_ge_event_t *) {} +#endif virtual QXcbWindow *toWindow() { return 0; } }; @@ -485,8 +489,8 @@ public: static bool xEmbedSystemTrayAvailable(); static bool xEmbedSystemTrayVisualHasAlphaChannel(); -#ifdef XCB_USE_XINPUT2 - void handleEnterEvent(const xcb_enter_notify_event_t *); +#ifdef XCB_USE_XINPUT21 + void handleEnterEvent(); #endif #ifdef XCB_USE_XINPUT22 @@ -500,7 +504,9 @@ public: QXcbGlIntegration *glIntegration() const { return m_glIntegration; } +#ifdef XCB_USE_XINPUT22 bool xi2MouseEvents() const; +#endif protected: bool event(QEvent *e) Q_DECL_OVERRIDE; @@ -534,9 +540,9 @@ private: void initializeScreens(); bool compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const; +#ifdef XCB_USE_XINPUT2 bool m_xi2Enabled; int m_xi2Minor; -#ifdef XCB_USE_XINPUT2 void initializeXInput2(); void finalizeXInput2(); void xi2SetupDevices(); diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index e055ad1424..9911afb11e 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -38,6 +38,7 @@ #include "qtouchdevice.h" #include <qpa/qwindowsysteminterface.h> #include <QDebug> +#include <cmath> #ifdef XCB_USE_XINPUT2 @@ -48,6 +49,7 @@ struct XInput2TouchDeviceData { XInput2TouchDeviceData() : xiDeviceInfo(0) , qtTouchDevice(0) + , providesTouchOrientation(false) { } XIDeviceInfo *xiDeviceInfo; @@ -59,6 +61,7 @@ struct XInput2TouchDeviceData { QPointF firstPressedPosition; // in screen coordinates where the first point was pressed QPointF firstPressedNormalPosition; // device coordinates (0 to 1, 0 to 1) where the first point was pressed QSizeF size; // device size in mm + bool providesTouchOrientation; }; void QXcbConnection::initializeXInput2() @@ -293,6 +296,11 @@ void QXcbConnection::xi2Select(xcb_window_t window) bitMask |= XI_ButtonPressMask; bitMask |= XI_ButtonReleaseMask; bitMask |= XI_MotionMask; + + // There is a check for enter/leave events in plain xcb enter/leave event handler + bitMask |= XI_EnterMask; + bitMask |= XI_LeaveMask; + qCDebug(lcQpaXInput, "XInput 2.2: Selecting press/release/motion events in addition to touch"); } XIEventMask mask; @@ -307,9 +315,12 @@ void QXcbConnection::xi2Select(xcb_window_t window) if (result != Success) qCDebug(lcQpaXInput, "XInput 2.2: failed to select pointer/touch events, window %x, result %d", window, result); } -#endif // XCB_USE_XINPUT22 const bool pointerSelected = isAtLeastXI22() && xi2MouseEvents(); +#else + const bool pointerSelected = false; +#endif // XCB_USE_XINPUT22 + QSet<int> tabletDevices; #ifndef QT_NO_TABLETEVENT if (!m_tabletData.isEmpty()) { @@ -413,6 +424,8 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id) caps |= QTouchDevice::Position | QTouchDevice::NormalizedPosition; else if (vci->label == atom(QXcbAtom::AbsMTTouchMajor)) caps |= QTouchDevice::Area; + else if (vci->label == atom(QXcbAtom::AbsMTOrientation)) + dev->providesTouchOrientation = true; else if (vci->label == atom(QXcbAtom::AbsMTPressure) || vci->label == atom(QXcbAtom::AbsPressure)) caps |= QTouchDevice::Pressure; else if (vci->label == atom(QXcbAtom::RelX)) { @@ -474,6 +487,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event); int sourceDeviceId = xiEvent->deviceid; // may be the master id xXIDeviceEvent *xiDeviceEvent = 0; + xXIEnterEvent *xiEnterEvent = 0; QXcbWindowEventListener *eventListener = 0; switch (xiEvent->evtype) { @@ -488,14 +502,16 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) { xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event); eventListener = windowEventListenerFromId(xiDeviceEvent->event); - if (eventListener) { - long result = 0; - if (eventListener->handleGenericEvent(reinterpret_cast<xcb_generic_event_t *>(event), &result)) - return; - } sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master break; } + case XI_Enter: + case XI_Leave: { + xiEnterEvent = reinterpret_cast<xXIEnterEvent *>(event); + eventListener = windowEventListenerFromId(xiEnterEvent->event); + sourceDeviceId = xiEnterEvent->sourceid; // use the actual device id instead of the master + break; + } case XI_HierarchyChanged: xi2HandleHierachyEvent(xiEvent); return; @@ -506,11 +522,19 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) break; } + if (eventListener) { + long result = 0; + if (eventListener->handleGenericEvent(reinterpret_cast<xcb_generic_event_t *>(event), &result)) + return; + } + #ifndef QT_NO_TABLETEVENT - for (int i = 0; i < m_tabletData.count(); ++i) { - if (m_tabletData.at(i).deviceId == sourceDeviceId) { - if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener)) - return; + if (!xiEnterEvent) { + for (int i = 0; i < m_tabletData.count(); ++i) { + if (m_tabletData.at(i).deviceId == sourceDeviceId) { + if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener)) + return; + } } } #endif // QT_NO_TABLETEVENT @@ -543,6 +567,13 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) xi2ProcessTouch(xiDeviceEvent, platformWindow); break; } + } else if (xiEnterEvent && xi2MouseEvents() && eventListener) { + switch (xiEnterEvent->evtype) { + case XI_Enter: + case XI_Leave: + eventListener->handleXIEnterLeave(event); + break; + } } #endif // XCB_USE_XINPUT22 } @@ -574,7 +605,9 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo QXcbScreen* screen = platformWindow->xcbScreen(); qreal x = fixed1616ToReal(xiDeviceEvent->root_x); qreal y = fixed1616ToReal(xiDeviceEvent->root_y); - qreal nx = -1.0, ny = -1.0, d = 0.0; + qreal nx = -1.0, ny = -1.0; + qreal w = 0.0, h = 0.0; + bool majorAxisIsY = touchPoint.area.height() > touchPoint.area.width(); for (int i = 0; i < dev->xiDeviceInfo->num_classes; ++i) { XIAnyClassInfo *classinfo = dev->xiDeviceInfo->classes[i]; if (classinfo->type == XIValuatorClass) { @@ -599,7 +632,24 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo } else if (vci->label == atom(QXcbAtom::AbsMTPositionY)) { ny = valuatorNormalized(value, vci); } else if (vci->label == atom(QXcbAtom::AbsMTTouchMajor)) { - d = valuatorNormalized(value, vci) * screen->geometry().width(); + const qreal sw = screen->geometry().width(); + const qreal sh = screen->geometry().height(); + w = valuatorNormalized(value, vci) * std::sqrt(sw * sw + sh * sh); + } else if (vci->label == atom(QXcbAtom::AbsMTTouchMinor)) { + const qreal sw = screen->geometry().width(); + const qreal sh = screen->geometry().height(); + h = valuatorNormalized(value, vci) * std::sqrt(sw * sw + sh * sh); + } else if (vci->label == atom(QXcbAtom::AbsMTOrientation)) { + // Find the closest axis. + // 0 corresponds to the Y axis, vci->max to the X axis. + // Flipping over the Y axis and rotating by 180 degrees + // don't change the result, so normalize value to range + // [0, vci->max] first. + value = qAbs(value); + while (value > vci->max) + value -= 2 * vci->max; + value = qAbs(value); + majorAxisIsY = value < vci->max - value; } else if (vci->label == atom(QXcbAtom::AbsMTPressure) || vci->label == atom(QXcbAtom::AbsPressure)) { touchPoint.pressure = valuatorNormalized(value, vci); @@ -616,8 +666,18 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo ny = y / screen->geometry().height(); } if (xiDeviceEvent->evtype != XI_TouchEnd) { - if (d == 0.0) - d = touchPoint.area.width(); + if (!dev->providesTouchOrientation) { + if (w == 0.0) + w = touchPoint.area.width(); + h = w; + } else { + if (w == 0.0) + w = qMax(touchPoint.area.width(), touchPoint.area.height()); + if (h == 0.0) + h = qMin(touchPoint.area.width(), touchPoint.area.height()); + if (majorAxisIsY) + qSwap(w, h); + } } switch (xiDeviceEvent->evtype) { @@ -681,7 +741,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo } dev->pointPressedPosition.remove(touchPoint.id); } - touchPoint.area = QRectF(x - d/2, y - d/2, d, d); + touchPoint.area = QRectF(x - w/2, y - h/2, w, h); touchPoint.normalPosition = QPointF(nx, ny); if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) @@ -718,6 +778,8 @@ bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab) XISetMask(mask, XI_ButtonPress); XISetMask(mask, XI_ButtonRelease); XISetMask(mask, XI_Motion); + XISetMask(mask, XI_Enter); + XISetMask(mask, XI_Leave); XISetMask(mask, XI_TouchBegin); XISetMask(mask, XI_TouchUpdate); XISetMask(mask, XI_TouchEnd); @@ -827,9 +889,9 @@ void QXcbConnection::updateScrollingDevice(ScrollingDevice &scrollingDevice, int #endif } -void QXcbConnection::handleEnterEvent(const xcb_enter_notify_event_t *) -{ #ifdef XCB_USE_XINPUT21 +void QXcbConnection::handleEnterEvent() +{ QHash<int, ScrollingDevice>::iterator it = m_scrollingDevices.begin(); const QHash<int, ScrollingDevice>::iterator end = m_scrollingDevices.end(); while (it != end) { @@ -845,8 +907,8 @@ void QXcbConnection::handleEnterEvent(const xcb_enter_notify_event_t *) XIFreeDeviceInfo(xiDeviceInfo); ++it; } -#endif } +#endif void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice) { @@ -1068,7 +1130,7 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, Q // Synthesize mouse events since otherwise there are no mouse events from // the pen on the XI 2.2+ path. if (xi2MouseEvents() && eventListener) - eventListener->handleXIMouseEvent(reinterpret_cast<xcb_ge_event_t *>(event)); + eventListener->handleXIMouseEvent(reinterpret_cast<xcb_ge_event_t *>(event), Qt::MouseEventSynthesizedByQt); #else Q_UNUSED(eventListener); #endif diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 9296a6d141..f5cc87394b 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -193,6 +193,7 @@ void QXcbDrag::startDrag() XCB_ATOM_ATOM, 32, drag_types.size(), (const void *)drag_types.constData()); setUseCompositing(current_virtual_desktop->compositingActive()); + setScreen(current_virtual_desktop->screens().constFirst()->screen()); QBasicDrag::startDrag(); if (connection()->mouseGrabber() == Q_NULLPTR) shapedPixmapWindow()->setMouseGrabEnabled(true); @@ -322,6 +323,9 @@ void QXcbDrag::move(const QPoint &globalPos) if (virtualDesktop != current_virtual_desktop) { setUseCompositing(virtualDesktop->compositingActive()); recreateShapedPixmapWindow(static_cast<QPlatformScreen*>(screen)->screen(), deviceIndependentPos); + if (connection()->mouseGrabber() == Q_NULLPTR) + shapedPixmapWindow()->setMouseGrabEnabled(true); + current_virtual_desktop = virtualDesktop; } else { QBasicDrag::moveShapedPixmapWindow(deviceIndependentPos); @@ -419,6 +423,7 @@ void QXcbDrag::move(const QPoint &globalPos) xcb_client_message_event_t enter; enter.response_type = XCB_CLIENT_MESSAGE; + enter.sequence = 0; enter.window = target; enter.format = 32; enter.type = atom(QXcbAtom::XdndEnter); @@ -447,6 +452,7 @@ void QXcbDrag::move(const QPoint &globalPos) xcb_client_message_event_t move; move.response_type = XCB_CLIENT_MESSAGE; + move.sequence = 0; move.window = target; move.format = 32; move.type = atom(QXcbAtom::XdndPosition); @@ -475,6 +481,7 @@ void QXcbDrag::drop(const QPoint &globalPos) xcb_client_message_event_t drop; drop.response_type = XCB_CLIENT_MESSAGE; + drop.sequence = 0; drop.window = current_target; drop.format = 32; drop.type = atom(QXcbAtom::XdndDrop); @@ -736,6 +743,7 @@ void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message xcb_client_message_event_t response; response.response_type = XCB_CLIENT_MESSAGE; + response.sequence = 0; response.window = xdnd_dragsource; response.format = 32; response.type = atom(QXcbAtom::XdndStatus); @@ -882,6 +890,7 @@ void QXcbDrag::send_leave() xcb_client_message_event_t leave; leave.response_type = XCB_CLIENT_MESSAGE; + leave.sequence = 0; leave.window = current_target; leave.format = 32; leave.type = atom(QXcbAtom::XdndLeave); @@ -952,6 +961,7 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e xcb_client_message_event_t finished; finished.response_type = XCB_CLIENT_MESSAGE; + finished.sequence = 0; finished.window = xdnd_dragsource; finished.format = 32; finished.type = atom(QXcbAtom::XdndFinished); diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 19e8b1de7d..94e17a2983 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -174,9 +174,11 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char if (canNotGrabEnv) m_canGrab = false; + const int numParameters = parameters.size(); + m_connections.reserve(1 + numParameters / 2); m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName); - for (int i = 0; i < parameters.size() - 1; i += 2) { + for (int i = 0; i < numParameters - 1; i += 2) { qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1); QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1); m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData()); diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 2e088d3ca5..631dd17908 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -797,9 +797,9 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state) } } +#ifdef XCB_USE_XINPUT22 void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo) { -#ifdef XCB_USE_XINPUT22 if (m_config && !connection()->hasXKB()) { xXIModifierInfo *mods = static_cast<xXIModifierInfo *>(modInfo); xXIGroupInfo *group = static_cast<xXIGroupInfo *>(groupInfo); @@ -815,12 +815,8 @@ void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo) //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); } } -#else - Q_UNUSED(modInfo); - Q_UNUSED(groupInfo); - Q_ASSERT(false); // this can't be -#endif } +#endif quint32 QXcbKeyboard::xkbModMask(quint16 state) { diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index d2e37d624c..457a27affb 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -68,7 +68,9 @@ public: void updateXKBMods(); quint32 xkbModMask(quint16 state); void updateXKBStateFromCore(quint16 state); +#ifdef XCB_USE_XINPUT22 void updateXKBStateFromXI(void *modInfo, void *groupInfo); +#endif #ifndef QT_NO_XKB // when XKEYBOARD is present on the X server int coreDeviceId() const { return core_device_id; } diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index dfb0a125e2..96239a0f20 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -48,6 +48,7 @@ #include <QtPlatformHeaders/qxcbwindowfunctions.h> #include <QtPlatformHeaders/qxcbintegrationfunctions.h> +#include <QtPlatformHeaders/qxcbscreenfunctions.h> #ifndef QT_NO_DBUS #include "QtPlatformSupport/private/qdbusmenuconnection_p.h" @@ -76,7 +77,7 @@ static int resourceType(const QByteArray &key) QByteArrayLiteral("startupid"), QByteArrayLiteral("traywindow"), QByteArrayLiteral("gettimestamp"), QByteArrayLiteral("x11screen"), QByteArrayLiteral("rootwindow"), - QByteArrayLiteral("subpixeltype"), QByteArrayLiteral("antialiasingEnabled"), + QByteArrayLiteral("subpixeltype"), QByteArrayLiteral("antialiasingenabled"), QByteArrayLiteral("nofonthinting"), QByteArrayLiteral("atspibus") }; @@ -367,6 +368,10 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio if (function == QXcbWindowFunctions::visualIdIdentifier()) { return QFunctionPointer(QXcbWindowFunctions::VisualId(QXcbWindow::visualIdStatic)); } + + if (function == QXcbScreenFunctions::virtualDesktopNumberIdentifier()) + return QFunctionPointer(QXcbScreenFunctions::VirtualDesktopNumber(QXcbScreen::virtualDesktopNumberStatic)); + return Q_NULLPTR; } diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index f3d381b99e..f74244e13c 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -208,7 +208,10 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe m_geometry = QRect(QPoint(), m_virtualSize); if (m_availableGeometry.isEmpty()) - m_availableGeometry = m_geometry; + m_availableGeometry = m_geometry & m_virtualDesktop->workArea(); + + if (m_sizeMillimeters.isEmpty()) + m_sizeMillimeters = m_virtualSizeMillimeters; readXResources(); @@ -358,6 +361,7 @@ void QXcbScreen::sendStartupMessage(const QByteArray &message) const ev.response_type = XCB_CLIENT_MESSAGE; ev.format = 8; ev.type = connection()->atom(QXcbAtom::_NET_STARTUP_INFO_BEGIN); + ev.sequence = 0; ev.window = rootWindow; int sent = 0; int length = message.length() + 1; // include NUL byte @@ -435,6 +439,14 @@ void QXcbScreen::setOutput(xcb_randr_output_t outputId, // TODO: Send an event to the QScreen instance that the screen changed its name } +int QXcbScreen::virtualDesktopNumberStatic(const QScreen *screen) +{ + if (screen && screen->handle()) + return static_cast<const QXcbScreen *>(screen->handle())->screenNumber(); + + return 0; +} + /*! \brief handle the XCB screen change event and update properties diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index f4de2b9dfd..7376ddf35c 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -133,6 +133,7 @@ public: bool isPrimary() const { return m_primary; } int screenNumber() const { return m_virtualDesktop->number(); } + static int virtualDesktopNumberStatic(const QScreen *screen); xcb_screen_t *screen() const { return m_virtualDesktop->screen(); } xcb_window_t root() const { return screen()->root; } diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp index 1f217e8de7..49c0440a3c 100644 --- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp +++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp @@ -94,9 +94,9 @@ xcb_window_t QXcbSystemTrayTracker::locateTrayWindow(const QXcbConnection *conne void QXcbSystemTrayTracker::requestSystemTrayWindowDock(xcb_window_t window) const { xcb_client_message_event_t trayRequest; - memset(&trayRequest, 0, sizeof(trayRequest)); trayRequest.response_type = XCB_CLIENT_MESSAGE; trayRequest.format = 32; + trayRequest.sequence = 0; trayRequest.window = m_trayWindow; trayRequest.type = m_trayAtom; trayRequest.data.data32[0] = XCB_CURRENT_TIME; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index f97f570831..a0b1ddb434 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -34,6 +34,7 @@ #include "qxcbwindow.h" #include <QtDebug> +#include <QMetaEnum> #include <QScreen> #include <QtGui/QIcon> #include <QtGui/QRegion> @@ -50,6 +51,7 @@ #include "qxcbsystemtraytracker.h" #include <qpa/qplatformintegration.h> +#include <qpa/qplatformcursor.h> #include <algorithm> @@ -261,6 +263,26 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s) } #endif // XCB_USE_XLIB +// TODO move this into a utility function in QWindow or QGuiApplication +static QWindow *childWindowAt(QWindow *win, const QPoint &p) +{ + foreach (QObject *obj, win->children()) { + if (obj->isWindowType()) { + QWindow *childWin = static_cast<QWindow *>(obj); + if (childWin->isVisible()) { + if (QWindow *recurse = childWindowAt(childWin, p)) + return recurse; + } + } + } + if (!win->isTopLevel() + && !(win->flags() & Qt::WindowTransparentForInput) + && win->geometry().contains(win->parent()->mapFromGlobal(p))) { + return win; + } + return Q_NULLPTR; +} + static const char *wm_window_type_property_id = "_q_xcb_wm_window_type"; QXcbWindow::QXcbWindow(QWindow *window) @@ -855,6 +877,33 @@ void QXcbWindow::hide() connection()->setMouseGrabber(Q_NULLPTR); m_mapped = false; + + // Hiding a modal window doesn't send an enter event to its transient parent when the + // mouse is already over the parent window, so the enter event must be emulated. + if (window()->isModal()) { + // Get the cursor position at modal window screen + const QPoint nativePos = xcbScreen()->cursor()->pos(); + const QPoint cursorPos = QHighDpi::fromNativePixels(nativePos, xcbScreen()->screenForPosition(nativePos)->screen()); + + // Find the top level window at cursor position. + // Don't use QGuiApplication::topLevelAt(): search only the virtual siblings of this window's screen + QWindow *enterWindow = Q_NULLPTR; + foreach (QPlatformScreen *screen, xcbScreen()->virtualSiblings()) { + if (screen->geometry().contains(cursorPos)) { + const QPoint devicePosition = QHighDpi::toNativePixels(cursorPos, screen->screen()); + enterWindow = screen->topLevelAt(devicePosition); + break; + } + } + + if (enterWindow && enterWindow != window()) { + // Find the child window at cursor position, otherwise use the top level window + if (QWindow *childWindow = childWindowAt(enterWindow, cursorPos)) + enterWindow = childWindow; + const QPoint localPos = enterWindow->mapFromGlobal(cursorPos); + QWindowSystemInterface::handleEnterEvent(enterWindow, localPos, cursorPos); + } + } } static QWindow *tlWindow(QWindow *window) @@ -894,8 +943,13 @@ static bool focusInPeeker(QXcbConnection *connection, xcb_generic_event_t *event return true; } uint response_type = event->response_type & ~0x80; - if (response_type == XCB_FOCUS_IN) - return true; + if (response_type == XCB_FOCUS_IN) { + // Ignore focus events that are being sent only because the pointer is over + // our window, even if the input focus is in a different window. + xcb_focus_in_event_t *e = (xcb_focus_in_event_t *) event; + if (e->detail != XCB_NOTIFY_DETAIL_POINTER) + return true; + } /* We are also interested in XEMBED_FOCUS_IN events */ if (response_type == XCB_CLIENT_MESSAGE) { @@ -1170,6 +1224,7 @@ void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two) event.response_type = XCB_CLIENT_MESSAGE; event.format = 32; + event.sequence = 0; event.window = m_window; event.type = atom(QXcbAtom::_NET_WM_STATE); event.data.data32[0] = set ? 1 : 0; @@ -1211,6 +1266,7 @@ void QXcbWindow::setWindowState(Qt::WindowState state) event.response_type = XCB_CLIENT_MESSAGE; event.format = 32; + event.sequence = 0; event.window = m_window; event.type = atom(QXcbAtom::WM_CHANGE_STATE); event.data.data32[0] = XCB_WM_STATE_ICONIC; @@ -1606,6 +1662,7 @@ void QXcbWindow::requestActivateWindow() event.response_type = XCB_CLIENT_MESSAGE; event.format = 32; + event.sequence = 0; event.window = m_window; event.type = atom(QXcbAtom::_NET_ACTIVE_WINDOW); event.data.data32[0] = 1; @@ -1980,8 +2037,9 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even } else if (event->type == atom(QXcbAtom::_COMPIZ_DECOR_PENDING) || event->type == atom(QXcbAtom::_COMPIZ_DECOR_REQUEST) || event->type == atom(QXcbAtom::_COMPIZ_DECOR_DELETE_PIXMAP) - || event->type == atom(QXcbAtom::_COMPIZ_TOOLKIT_ACTION)) { - //silence the _COMPIZ messages for now + || event->type == atom(QXcbAtom::_COMPIZ_TOOLKIT_ACTION) + || event->type == atom(QXcbAtom::_GTK_LOAD_ICONTHEMES)) { + //silence the _COMPIZ and _GTK messages for now } else { qWarning() << "QXcbWindow: Unhandled client message:" << connection()->atomName(event->type); } @@ -2104,7 +2162,7 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event) } void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y, - int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source) { const bool isWheel = detail >= 4 && detail <= 7; if (!isWheel && window() != QGuiApplication::focusWindow()) { @@ -2140,11 +2198,11 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in return; } - handleMouseEvent(timestamp, local, global, modifiers); + handleMouseEvent(timestamp, local, global, modifiers, source); } void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y, - int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source) { QPoint local(event_x, event_y); QPoint global(root_x, root_y); @@ -2154,15 +2212,94 @@ void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, return; } - handleMouseEvent(timestamp, local, global, modifiers); + handleMouseEvent(timestamp, local, global, modifiers, source); +} + +static bool ignoreLeaveEvent(quint8 mode, quint8 detail) +{ + return (mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) // Check for AwesomeWM + || detail == XCB_NOTIFY_DETAIL_VIRTUAL + || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL; +} + +static bool ignoreEnterEvent(quint8 mode, quint8 detail) +{ + return ((mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) // Check for AwesomeWM + || (mode != XCB_NOTIFY_MODE_NORMAL && mode != XCB_NOTIFY_MODE_UNGRAB) + || detail == XCB_NOTIFY_DETAIL_VIRTUAL + || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL); +} + +class EnterEventChecker +{ +public: + bool checkEvent(xcb_generic_event_t *event) + { + if (!event) + return false; + if ((event->response_type & ~0x80) != XCB_ENTER_NOTIFY) + return false; + + xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)event; + if (ignoreEnterEvent(enter->mode, enter->detail)) + return false; + + return true; + } +}; + +void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, int root_y, + quint8 mode, quint8 detail, xcb_timestamp_t timestamp) +{ + connection()->setTime(timestamp); +#ifdef XCB_USE_XINPUT21 + connection()->handleEnterEvent(); +#endif + + const QPoint global = QPoint(root_x, root_y); + + if (ignoreEnterEvent(mode, detail) + || (connection()->buttons() != Qt::NoButton + && QGuiApplicationPrivate::lastCursorPosition != global)) + return; + + const QPoint local(event_x, event_y); + QWindowSystemInterface::handleEnterEvent(window(), local, global); +} + +void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y, + quint8 mode, quint8 detail, xcb_timestamp_t timestamp) +{ + connection()->setTime(timestamp); + + const QPoint global(root_x, root_y); + + if (ignoreLeaveEvent(mode, detail) + || (connection()->buttons() != Qt::NoButton + && QGuiApplicationPrivate::lastCursorPosition != global)) + return; + + EnterEventChecker checker; + xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)connection()->checkEvent(checker); + QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : 0; + + if (enterWindow) { + QPoint local(enter->event_x, enter->event_y); + QPoint global = QPoint(root_x, root_y); + QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global); + } else { + QWindowSystemInterface::handleLeaveEvent(window()); + } + + free(enter); } void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, - Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) + Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source) { QPoint local(event_x, event_y); QPoint global(root_x, root_y); - handleMouseEvent(timestamp, local, global, modifiers); + handleMouseEvent(timestamp, local, global, modifiers, source); } // Handlers for plain xcb events. Used only when XI 2.2 or newer is not available. @@ -2191,12 +2328,10 @@ static inline int fixed1616ToInt(FP1616 val) { return int((qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF); } -#endif // With XI 2.2+ press/release/motion comes here instead of the above handlers. -void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event) +void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource source) { -#ifdef XCB_USE_XINPUT22 QXcbConnection *conn = connection(); xXIDeviceEvent *ev = reinterpret_cast<xXIDeviceEvent *>(event); const Qt::KeyboardModifiers modifiers = conn->keyboard()->translateModifiers(ev->mods.effective_mods); @@ -2215,107 +2350,84 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event) conn->setButton(conn->translateMouseButton(i), XIMaskIsSet(buttonMask, i)); } + const char *sourceName = nullptr; + if (lcQpaXInput().isDebugEnabled()) { + const QMetaObject *metaObject = qt_getEnumMetaObject(source); + const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(source))); + sourceName = me.valueToKey(source); + } + switch (ev->evtype) { case XI_ButtonPress: - qCDebug(lcQpaXInput, "XI2 mouse press, button %d, time %d", button, ev->time); + qCDebug(lcQpaXInput, "XI2 mouse press, button %d, time %d, source %s", button, ev->time, sourceName); conn->setButton(button, true); - handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time); + handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source); break; case XI_ButtonRelease: - qCDebug(lcQpaXInput, "XI2 mouse release, button %d, time %d", button, ev->time); + qCDebug(lcQpaXInput, "XI2 mouse release, button %d, time %d, source %s", button, ev->time, sourceName); conn->setButton(button, false); - handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time); + handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source); break; case XI_Motion: - qCDebug(lcQpaXInput, "XI2 mouse motion %d,%d, time %d", event_x, event_y, ev->time); - handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time); + qCDebug(lcQpaXInput, "XI2 mouse motion %d,%d, time %d, source %s", event_x, event_y, ev->time, sourceName); + handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time, source); break; default: qWarning() << "Unrecognized XI2 mouse event" << ev->evtype; break; } -#else - Q_UNUSED(event); - Q_ASSERT(false); // this can't be -#endif } -QXcbWindow *QXcbWindow::toWindow() { return this; } - -void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers) +// With XI 2.2+ enter/leave comes here and are blocked in plain xcb events +void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event) { - connection()->setTime(time); - QWindowSystemInterface::handleMouseEvent(window(), time, local, global, connection()->buttons(), modifiers); -} + xXIEnterEvent *ev = reinterpret_cast<xXIEnterEvent *>(event); -static bool ignoreLeaveEvent(const xcb_leave_notify_event_t *event) -{ - return event->detail == XCB_NOTIFY_DETAIL_VIRTUAL - || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL - || event->mode == XCB_NOTIFY_MODE_GRAB; -} + // Compare the window with current mouse grabber to prevent deliver events to any other windows. + // If leave event occurs and the window is under mouse - allow to deliver the leave event. + QXcbWindow *mouseGrabber = connection()->mouseGrabber(); + if (mouseGrabber && mouseGrabber != this + && (ev->evtype != XI_Leave || QGuiApplicationPrivate::currentMouseWindow != window())) { + return; + } -static bool ignoreEnterEvent(const xcb_enter_notify_event_t *event) -{ - return (event->mode != XCB_NOTIFY_MODE_NORMAL - || event->detail == XCB_NOTIFY_DETAIL_VIRTUAL - || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL); -} + const int root_x = fixed1616ToInt(ev->root_x); + const int root_y = fixed1616ToInt(ev->root_y); -class EnterEventChecker -{ -public: - bool checkEvent(xcb_generic_event_t *event) - { - if (!event) - return false; - if ((event->response_type & ~0x80) != XCB_ENTER_NOTIFY) - return false; + switch (ev->evtype) { + case XI_Enter: { + const int event_x = fixed1616ToInt(ev->event_x); + const int event_y = fixed1616ToInt(ev->event_y); + qCDebug(lcQpaXInput, "XI2 mouse enter %d,%d, mode %d, detail %d, time %d", event_x, event_y, ev->mode, ev->detail, ev->time); + handleEnterNotifyEvent(event_x, event_y, root_x, root_y, ev->mode, ev->detail, ev->time); + break; + } + case XI_Leave: + qCDebug(lcQpaXInput, "XI2 mouse leave, mode %d, detail %d, time %d", ev->mode, ev->detail, ev->time); + connection()->keyboard()->updateXKBStateFromXI(&ev->mods, &ev->group); + handleLeaveNotifyEvent(root_x, root_y, ev->mode, ev->detail, ev->time); + break; + } +} +#endif - xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)event; - if (ignoreEnterEvent(enter)) - return false; +QXcbWindow *QXcbWindow::toWindow() { return this; } - return true; - } -}; +void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, + Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source) +{ + connection()->setTime(time); + QWindowSystemInterface::handleMouseEvent(window(), time, local, global, connection()->buttons(), modifiers, source); +} void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event) { - connection()->setTime(event->time); -#ifdef XCB_USE_XINPUT2 - connection()->handleEnterEvent(event); -#endif - - if (ignoreEnterEvent(event)) - return; - - const QPoint local(event->event_x, event->event_y); - QPoint global = QPoint(event->root_x, event->root_y); - QWindowSystemInterface::handleEnterEvent(window(), local, global); + handleEnterNotifyEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->mode, event->detail, event->time); } void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event) { - connection()->setTime(event->time); - - if (ignoreLeaveEvent(event)) - return; - - EnterEventChecker checker; - xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)connection()->checkEvent(checker); - QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : 0; - - if (enterWindow) { - QPoint local(enter->event_x, enter->event_y); - QPoint global = QPoint(event->root_x, event->root_y); - - QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global); - } else { - QWindowSystemInterface::handleLeaveEvent(window()); - } - - free(enter); + handleLeaveNotifyEvent(event->root_x, event->root_y, event->mode, event->detail, event->time); } void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) @@ -2369,14 +2481,22 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev } } -void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *) +void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *event) { + // Ignore focus events that are being sent only because the pointer is over + // our window, even if the input focus is in a different window. + if (event->detail == XCB_NOTIFY_DETAIL_POINTER) + return; doFocusIn(); } -void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *) +void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *event) { + // Ignore focus events that are being sent only because the pointer is over + // our window, even if the input focus is in a different window. + if (event->detail == XCB_NOTIFY_DETAIL_POINTER) + return; doFocusOut(); } @@ -2419,7 +2539,7 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab) if (!grab && connection()->mouseGrabber() == this) connection()->setMouseGrabber(Q_NULLPTR); #ifdef XCB_USE_XINPUT22 - if (connection()->xi2MouseEvents()) { + if (connection()->isAtLeastXI22() && connection()->xi2MouseEvents()) { bool result = connection()->xi2SetMouseGrabEnabled(m_window, grab); if (grab && result) connection()->setMouseGrabber(this); @@ -2491,6 +2611,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) xcb_client_message_event_t xev; xev.response_type = XCB_CLIENT_MESSAGE; xev.type = moveResize; + xev.sequence = 0; xev.window = xcb_window(); xev.format = 32; const QPoint globalPos = window()->mapToGlobal(pos); @@ -2519,6 +2640,7 @@ void QXcbWindow::sendXEmbedMessage(xcb_window_t window, quint32 message, event.response_type = XCB_CLIENT_MESSAGE; event.format = 32; + event.sequence = 0; event.window = window; event.type = atom(QXcbAtom::_XEMBED); event.data.data32[0] = connection()->time(); diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index d2c02fe3df..4673f3dd33 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -132,11 +132,15 @@ public: void handleFocusInEvent(const xcb_focus_in_event_t *event) Q_DECL_OVERRIDE; void handleFocusOutEvent(const xcb_focus_out_event_t *event) Q_DECL_OVERRIDE; void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) Q_DECL_OVERRIDE; - void handleXIMouseEvent(xcb_ge_event_t *) Q_DECL_OVERRIDE; +#ifdef XCB_USE_XINPUT22 + void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized) Q_DECL_OVERRIDE; + void handleXIEnterLeave(xcb_ge_event_t *) Q_DECL_OVERRIDE; +#endif QXcbWindow *toWindow() Q_DECL_OVERRIDE; - void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers); + void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, + Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source); void updateNetWmUserTime(xcb_timestamp_t timestamp); @@ -204,13 +208,19 @@ protected: bool compressExposeEvent(QRegion &exposeRegion); void handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y, - int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); void handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y, - int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); void handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, - Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); + Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); + + void handleEnterNotifyEvent(int event_x, int event_y, int root_x, int root_y, + quint8 mode, quint8 detail, xcb_timestamp_t timestamp); + + void handleLeaveNotifyEvent(int root_x, int root_y, + quint8 mode, quint8 detail, xcb_timestamp_t timestamp); xcb_window_t m_window; diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro index 09ab1ad77a..75684a769b 100644 --- a/src/plugins/platforms/xcb/xcb-plugin.pro +++ b/src/plugins/platforms/xcb/xcb-plugin.pro @@ -1,13 +1,12 @@ TARGET = qxcb -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = QXcbIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) - QT += core-private gui-private platformsupport-private xcb_qpa_lib-private SOURCES = \ qxcbmain.cpp OTHER_FILES += xcb.json README +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QXcbIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index 302d87e007..f4a4e5a78a 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -1,8 +1,6 @@ TARGET = QtXcbQpa CONFIG += no_module_headers internal_module -load(qt_module) - QT += core-private gui-private platformsupport-private SOURCES = \ @@ -105,3 +103,4 @@ contains(QT_CONFIG, xkbcommon-qt) { QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XKBCOMMON } +load(qt_module) diff --git a/src/plugins/platformthemes/gtk2/gtk2.pro b/src/plugins/platformthemes/gtk2/gtk2.pro index 73c156f82b..1c434e1d4d 100644 --- a/src/plugins/platformthemes/gtk2/gtk2.pro +++ b/src/plugins/platformthemes/gtk2/gtk2.pro @@ -1,10 +1,5 @@ TARGET = qgtk2 -PLUGIN_TYPE = platformthemes -PLUGIN_EXTENDS = - -PLUGIN_CLASS_NAME = QGtk2ThemePlugin -load(qt_plugin) - QT += core-private gui-private platformsupport-private CONFIG += X11 @@ -19,3 +14,8 @@ SOURCES += \ main.cpp \ qgtk2dialoghelpers.cpp \ qgtk2theme.cpp \ + +PLUGIN_TYPE = platformthemes +PLUGIN_EXTENDS = - +PLUGIN_CLASS_NAME = QGtk2ThemePlugin +load(qt_plugin) diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp index 857f373759..f0a54ec92f 100644 --- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp +++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp @@ -517,8 +517,8 @@ void QGtk2FontDialogHelper::hide() static QString qt_fontToString(const QFont &font) { PangoFontDescription *desc = pango_font_description_new(); - pango_font_description_set_size(desc, font.pointSizeF() * PANGO_SCALE); - pango_font_description_set_family(desc, font.family().toUtf8()); + pango_font_description_set_size(desc, (font.pointSizeF() > 0.0 ? font.pointSizeF() : QFontInfo(font).pointSizeF()) * PANGO_SCALE); + pango_font_description_set_family(desc, QFontInfo(font).family().toUtf8()); int weight = font.weight(); if (weight >= QFont::Black) diff --git a/src/plugins/printsupport/cocoa/cocoa.pro b/src/plugins/printsupport/cocoa/cocoa.pro index a3b9e2dfcf..feed33a231 100644 --- a/src/plugins/printsupport/cocoa/cocoa.pro +++ b/src/plugins/printsupport/cocoa/cocoa.pro @@ -1,8 +1,5 @@ TARGET = cocoaprintersupport MODULE = cocoaprintersupport -PLUGIN_TYPE = printsupport -PLUGIN_CLASS_NAME = QCocoaPrinterSupportPlugin -load(qt_plugin) QT += gui-private printsupport-private LIBS += -framework Cocoa @@ -10,3 +7,7 @@ LIBS += -framework Cocoa SOURCES += main.cpp OTHER_FILES += cocoa.json + +PLUGIN_TYPE = printsupport +PLUGIN_CLASS_NAME = QCocoaPrinterSupportPlugin +load(qt_plugin) diff --git a/src/plugins/printsupport/cups/cups.pro b/src/plugins/printsupport/cups/cups.pro index cdbb08b10a..757408e7f7 100644 --- a/src/plugins/printsupport/cups/cups.pro +++ b/src/plugins/printsupport/cups/cups.pro @@ -1,8 +1,5 @@ TARGET = cupsprintersupport MODULE = cupsprintersupport -PLUGIN_TYPE = printsupport -PLUGIN_CLASS_NAME = QCupsPrinterSupportPlugin -load(qt_plugin) QT += core-private gui-private printsupport printsupport-private @@ -20,3 +17,7 @@ HEADERS += qcupsprintersupport_p.h \ qcupsprintengine_p.h OTHER_FILES += cups.json + +PLUGIN_TYPE = printsupport +PLUGIN_CLASS_NAME = QCupsPrinterSupportPlugin +load(qt_plugin) diff --git a/src/plugins/printsupport/windows/windows.pro b/src/plugins/printsupport/windows/windows.pro index 3366262ef0..06694fb7fe 100644 --- a/src/plugins/printsupport/windows/windows.pro +++ b/src/plugins/printsupport/windows/windows.pro @@ -1,8 +1,5 @@ TARGET = windowsprintersupport MODULE = windowsprintersupport -PLUGIN_TYPE = printsupport -PLUGIN_CLASS_NAME = QWindowsPrinterSupportPlugin -load(qt_plugin) QT *= core-private QT *= gui-private @@ -22,3 +19,7 @@ HEADERS += \ OTHER_FILES += windows.json LIBS += -lwinspool -lcomdlg32 -lgdi32 -luser32 + +PLUGIN_TYPE = printsupport +PLUGIN_CLASS_NAME = QWindowsPrinterSupportPlugin +load(qt_plugin) diff --git a/src/plugins/styles/bb10style/bb10style.pro b/src/plugins/styles/bb10style/bb10style.pro index ad35df6de7..543f67f169 100644 --- a/src/plugins/styles/bb10style/bb10style.pro +++ b/src/plugins/styles/bb10style/bb10style.pro @@ -1,9 +1,5 @@ TARGET = bb10styleplugin -PLUGIN_TYPE = styles -PLUGIN_CLASS_NAME = BlackBerry10StylePlugin -load(qt_plugin) - INCLUDEPATH += $$PWD QT += widgets @@ -26,3 +22,6 @@ RESOURCES += \ OTHER_FILES += qbb10styleplugin.json +PLUGIN_TYPE = styles +PLUGIN_CLASS_NAME = BlackBerry10StylePlugin +load(qt_plugin) diff --git a/src/printsupport/kernel/qplatformprintdevice.cpp b/src/printsupport/kernel/qplatformprintdevice.cpp index 6385f58aa1..802a12603a 100644 --- a/src/printsupport/kernel/qplatformprintdevice.cpp +++ b/src/printsupport/kernel/qplatformprintdevice.cpp @@ -53,6 +53,9 @@ QPlatformPrintDevice::QPlatformPrintDevice() m_haveOutputBins(false), m_haveDuplexModes(false), m_haveColorModes(false) +#ifndef QT_NO_MIMETYPES + , m_haveMimeTypes(false) +#endif { } @@ -68,6 +71,9 @@ QPlatformPrintDevice::QPlatformPrintDevice(const QString &id) m_haveOutputBins(false), m_haveDuplexModes(false), m_haveColorModes(false) +#ifndef QT_NO_MIMETYPES + , m_haveMimeTypes(false) +#endif { } diff --git a/src/printsupport/printsupport.pro b/src/printsupport/printsupport.pro index 6dd3eaab3c..52eab672d3 100644 --- a/src/printsupport/printsupport.pro +++ b/src/printsupport/printsupport.pro @@ -3,15 +3,14 @@ QT = core-private gui-private widgets-private DEFINES += QT_NO_USING_NAMESPACE -MODULE_PLUGIN_TYPES = \ - printsupport - QMAKE_DOCS = $$PWD/doc/qtprintsupport.qdocconf -load(qt_module) - QMAKE_LIBS += $$QMAKE_LIBS_PRINTSUPPORT include(kernel/kernel.pri) include(widgets/widgets.pri) include(dialogs/dialogs.pri) + +MODULE_PLUGIN_TYPES = \ + printsupport +load(qt_module) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index 8db06e6831..8a3919267f 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -1879,11 +1879,14 @@ bool QODBCDriver::open(const QString & db, if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) { qSqlWarning(QLatin1String("QODBCDriver::open: Unable to allocate connection"), d); setOpenError(true); + cleanup(); return false; } - if (!d->setConnectionOptions(connOpts)) + if (!d->setConnectionOptions(connOpts)) { + cleanup(); return false; + } // Create the connection string QString connQStr; @@ -1916,6 +1919,7 @@ bool QODBCDriver::open(const QString & db, if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) { setLastError(qMakeError(tr("Unable to connect"), QSqlError::ConnectionError, d)); setOpenError(true); + cleanup(); return false; } @@ -1923,6 +1927,7 @@ bool QODBCDriver::open(const QString & db, setLastError(qMakeError(tr("Unable to connect - Driver doesn't support all " "functionality required"), QSqlError::ConnectionError, d)); setOpenError(true); + cleanup(); return false; } diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index de1f1638fd..4f36e0b513 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -1390,8 +1390,10 @@ bool QPSQLDriver::subscribeToNotification(const QString &name) PGresult *result = d->exec(query); if (PQresultStatus(result) != PGRES_COMMAND_OK) { setLastError(qMakeError(tr("Unable to subscribe"), QSqlError::StatementError, d, result)); + PQclear(result); return false; } + PQclear(result); if (!d->sn) { d->sn = new QSocketNotifier(socket, QSocketNotifier::Read); @@ -1423,8 +1425,10 @@ bool QPSQLDriver::unsubscribeFromNotification(const QString &name) PGresult *result = d->exec(query); if (PQresultStatus(result) != PGRES_COMMAND_OK) { setLastError(qMakeError(tr("Unable to unsubscribe"), QSqlError::StatementError, d, result)); + PQclear(result); return false; } + PQclear(result); d->seid.removeAll(name); diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp index 3b540fd193..3b00e6f848 100644 --- a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp +++ b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp @@ -139,8 +139,6 @@ public: QVector<QVariant> firstRow; }; -static const uint initial_cache_size = 128; - QSQLite2ResultPrivate::QSQLite2ResultPrivate(QSQLite2Result* res) : q(res), access(0), currentTail(0), currentMachine(0), skippedStatus(false), skipRow(false), utf8(false) { diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp index ccfc6e04f0..adaeb8c846 100644 --- a/src/sql/kernel/qsqldriver.cpp +++ b/src/sql/kernel/qsqldriver.cpp @@ -457,6 +457,17 @@ QString QSqlDriver::stripDelimiters(const QString &identifier, IdentifierType ty This method can be used to manipulate tables without having to worry about database-dependent SQL dialects. For non-prepared statements, the values will be properly escaped. + + In the WHERE statement, each non-null field of \a rec specifies a + filter condition of equality to the field value, or if prepared, a + placeholder. However, prepared or not, a null field specifies the + condition IS NULL and never introduces a placeholder. The + application must not attempt to bind data for the null field during + execution. The field must be set to some non-null value if a + placeholder is desired. Furthermore, since non-null fields specify + equality conditions and SQL NULL is not equal to anything, even + itself, it is generally not useful to bind a null to a placeholder. + */ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName, const QSqlRecord &rec, bool preparedStatement) const @@ -476,31 +487,23 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName, s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(tableName); break; case WhereStatement: - if (preparedStatement) { - for (int i = 0; i < rec.count(); ++i) { - s.append(prepareIdentifier(rec.fieldName(i), FieldName,this)); - if (rec.isNull(i)) - s.append(QLatin1String(" IS NULL")); - else - s.append(QLatin1String(" = ?")); - s.append(QLatin1String(" AND ")); - } - } else { - for (i = 0; i < rec.count(); ++i) { - s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)); - QString val = formatValue(rec.field(i)); - if (val == QLatin1String("NULL")) - s.append(QLatin1String(" IS NULL")); - else - s.append(QLatin1String(" = ")).append(val); - s.append(QLatin1String(" AND ")); - } - } - if (!s.isEmpty()) { - s.prepend(QLatin1String("WHERE ")); - s.chop(5); // remove tailing AND + { + const QString tableNamePrefix = tableName.isEmpty() + ? QString() + : prepareIdentifier(tableName, QSqlDriver::TableName, this) + QLatin1Char('.'); + for (int i = 0; i < rec.count(); ++i) { + s.append(QLatin1String(i? " AND " : "WHERE ")); + s.append(tableNamePrefix); + s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)); + if (rec.isNull(i)) + s.append(QLatin1String(" IS NULL")); + else if (preparedStatement) + s.append(QLatin1String(" = ?")); + else + s.append(QLatin1String(" = ")).append(formatValue(rec.field(i))); } break; + } case UpdateStatement: s.append(QLatin1String("UPDATE ")).append(tableName).append( QLatin1String(" SET ")); diff --git a/src/sql/kernel/qsqlresult.h b/src/sql/kernel/qsqlresult.h index c86a8f858f..eeef68d2b8 100644 --- a/src/sql/kernel/qsqlresult.h +++ b/src/sql/kernel/qsqlresult.h @@ -38,6 +38,9 @@ #include <QtCore/qvector.h> #include <QtSql/qsql.h> +// for testing: +class tst_QSqlQuery; + QT_BEGIN_NAMESPACE @@ -54,6 +57,8 @@ class Q_SQL_EXPORT QSqlResult Q_DECLARE_PRIVATE(QSqlResult) friend class QSqlQuery; friend class QSqlTableModelPrivate; + // for testing: + friend class ::tst_QSqlQuery; public: virtual ~QSqlResult(); diff --git a/src/sql/sql.pro b/src/sql/sql.pro index 10004cb445..218671d7e7 100644 --- a/src/sql/sql.pro +++ b/src/sql/sql.pro @@ -4,13 +4,8 @@ QT = core-private DEFINES += QT_NO_USING_NAMESPACE win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x62000000 -MODULE_PLUGIN_TYPES = \ - sqldrivers - QMAKE_DOCS = $$PWD/doc/qtsql.qdocconf -load(qt_module) - DEFINES += QT_NO_CAST_FROM_ASCII PRECOMPILED_HEADER = ../corelib/global/qt_pch.h SQL_P = sql @@ -18,3 +13,7 @@ SQL_P = sql include(kernel/kernel.pri) include(drivers/drivers.pri) include(models/models.pri) + +MODULE_PLUGIN_TYPES = \ + sqldrivers +load(qt_module) diff --git a/src/testlib/qtestblacklist.cpp b/src/testlib/qtestblacklist.cpp index c2643a2304..04c6aa2717 100644 --- a/src/testlib/qtestblacklist.cpp +++ b/src/testlib/qtestblacklist.cpp @@ -34,7 +34,6 @@ #include "qtestresult_p.h" #include <QtTest/qtestcase.h> -#include <QtTest/qtest.h> #include <QtCore/qbytearray.h> #include <QtCore/qfile.h> #include <QtCore/qset.h> diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 36eff6ac98..339db2246e 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1563,7 +1563,9 @@ static void qPrintDataTags(FILE *stream) member.resize(qstrlen(slot) + qstrlen("_data()") + 1); qsnprintf(member.data(), member.size(), "%s_data()", slot); invokeMethod(QTest::currentTestObject, member.constData()); - for (int j = 0; j < table.dataCount(); ++j) + const int dataCount = table.dataCount(); + localTags.reserve(dataCount); + for (int j = 0; j < dataCount; ++j) localTags << QLatin1String(table.testData(j)->dataTag()); // Print all tag combinations: diff --git a/src/testlib/qtestspontaneevent.h b/src/testlib/qtestspontaneevent.h index 18c4221f72..bc775aa803 100644 --- a/src/testlib/qtestspontaneevent.h +++ b/src/testlib/qtestspontaneevent.h @@ -76,17 +76,10 @@ public: } #endif + // ### Qt 6: remove everything except this function: static inline void setSpontaneous(QEvent *ev) { - // use a union instead of a reinterpret_cast to prevent alignment warnings - union - { - QSpontaneKeyEvent *skePtr; - QEvent *evPtr; - } helper; - - helper.evPtr = ev; - helper.skePtr->setSpontaneous(); + ev->setSpontaneous(); } protected: diff --git a/src/tools/bootstrap-dbus/bootstrap-dbus.pro b/src/tools/bootstrap-dbus/bootstrap-dbus.pro index 4c466ba0e9..3b28c23311 100644 --- a/src/tools/bootstrap-dbus/bootstrap-dbus.pro +++ b/src/tools/bootstrap-dbus/bootstrap-dbus.pro @@ -9,8 +9,6 @@ DEFINES += \ MODULE_INCNAME = QtDBus -load(qt_module) - QMAKE_CXXFLAGS += $$QT_HOST_CFLAGS_DBUS SOURCES = \ @@ -25,5 +23,7 @@ SOURCES = \ ../../dbus/qdbus_symbols.cpp \ ../../dbus/qdbusunixfiledescriptor.cpp +load(qt_module) + lib.CONFIG = dummy_install INSTALLS = lib diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 4f2456cf79..b3df192110 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -27,11 +27,6 @@ DEFINES += \ DEFINES -= QT_EVAL -load(qt_module) - -# otherwise mingw headers do not declare common functions like putenv -mingw: CONFIG -= strict_c++ - SOURCES += \ ../../corelib/codecs/qlatincodec.cpp \ ../../corelib/codecs/qtextcodec.cpp \ @@ -142,5 +137,10 @@ else:include(../../3rdparty/zlib_dependency.pri) win32:LIBS += -luser32 -lole32 -ladvapi32 -lshell32 +load(qt_module) + +# otherwise mingw headers do not declare common functions like putenv +mingw: CONFIG -= strict_c++ + lib.CONFIG = dummy_install INSTALLS += lib diff --git a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp index 51e6b4af4d..10cc6b9929 100644 --- a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp +++ b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp @@ -396,6 +396,7 @@ static void parseCmdLine(QStringList &arguments) int main(int argc, char **argv) { QStringList args; + args.reserve(argc - 1); for (int n = 1; n < argc; ++n) args.append(QString::fromLocal8Bit(argv[n])); parseCmdLine(args); diff --git a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp index 84d82db9a7..7361fa2230 100644 --- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp +++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp @@ -389,7 +389,10 @@ static QStringList makeArgNames(const QDBusIntrospection::Arguments &inputArgs, QDBusIntrospection::Arguments()) { QStringList retval; - for (int i = 0; i < inputArgs.count(); ++i) { + const int numInputArgs = inputArgs.count(); + const int numOutputArgs = outputArgs.count(); + retval.reserve(numInputArgs + numOutputArgs); + for (int i = 0; i < numInputArgs; ++i) { const QDBusIntrospection::Argument &arg = inputArgs.at(i); QString name = arg.name; if (name.isEmpty()) @@ -400,7 +403,7 @@ static QStringList makeArgNames(const QDBusIntrospection::Arguments &inputArgs, name += QLatin1String("_"); retval << name; } - for (int i = 0; i < outputArgs.count(); ++i) { + for (int i = 0; i < numOutputArgs; ++i) { const QDBusIntrospection::Argument &arg = outputArgs.at(i); QString name = arg.name; if (name.isEmpty()) @@ -1145,7 +1148,7 @@ static void writeAdaptor(const QString &filename, const QDBusIntrospection::Inte int main(int argc, char **argv) { QStringList arguments; - + arguments.reserve(argc); for (int i = 0; i < argc; ++i) { arguments.append(QString::fromLocal8Bit(argv[i])); } diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index b02e2dc0ed..e0d4bea5b9 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -1267,7 +1267,10 @@ void WriteInitialization::writeProperties(const QString &varName, } else { setFunction = QLatin1String("->setProperty(\""); setFunction += propertyName; - setFunction += QLatin1String("\", QVariant("); + setFunction += QLatin1String("\", QVariant"); + if (p->kind() == DomProperty::Enum) + setFunction += QLatin1String("::fromValue"); + setFunction += QLatin1Char('('); } QString varNewName = varName; @@ -2200,8 +2203,10 @@ QList<WriteInitialization::Item *> WriteInitialization::initializeTreeWidgetItem { // items QList<Item *> items; + const int numDomItems = domItems.size(); + items.reserve(numDomItems); - for (int i = 0; i < domItems.size(); ++i) { + for (int i = 0; i < numDomItems; ++i) { const DomItem *domItem = domItems.at(i); Item *item = new Item(QLatin1String("QTreeWidgetItem"), m_indent, m_output, m_refreshOut, m_driver); diff --git a/src/widgets/accessible/qaccessiblewidgetfactory.cpp b/src/widgets/accessible/qaccessiblewidgetfactory.cpp index 4fa7c89482..261bc69000 100644 --- a/src/widgets/accessible/qaccessiblewidgetfactory.cpp +++ b/src/widgets/accessible/qaccessiblewidgetfactory.cpp @@ -33,6 +33,7 @@ #include "qaccessiblewidgets_p.h" #include "qaccessiblemenu_p.h" +#include "private/qwidget_p.h" #include "simplewidgets_p.h" #include "rangecontrols_p.h" #include "complexwidgets_p.h" @@ -53,7 +54,15 @@ QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *obje QAccessibleInterface *iface = 0; if (!object || !object->isWidgetType()) return iface; + QWidget *widget = static_cast<QWidget*>(object); + // QWidget emits destroyed() from its destructor instead of letting the QObject + // destructor do it, which means the QWidget is unregistered from the accessibillity + // cache. But QWidget destruction also emits enter and leave events, which may end + // up here, so we have to ensure that we don't fill the cache with an entry of + // a widget that is going away. + if (QWidgetPrivate::get(widget)->data.in_destructor) + return iface; if (false) { #ifndef QT_NO_LINEEDIT diff --git a/src/widgets/accessible/widgets.pro b/src/widgets/accessible/widgets.pro index c6af6d3f71..da8607c637 100644 --- a/src/widgets/accessible/widgets.pro +++ b/src/widgets/accessible/widgets.pro @@ -1,10 +1,5 @@ TARGET = qtaccessiblewidgets -PLUGIN_TYPE = accessible -PLUGIN_EXTENDS = widgets -PLUGIN_CLASS_NAME = AccessibleFactory -load(qt_plugin) - QT += core-private gui-private widgets-private QTDIR_build:REQUIRES += "contains(QT_CONFIG, accessibility)" @@ -24,4 +19,7 @@ HEADERS += qaccessiblewidgets.h \ qaccessiblemenu.h \ itemviews.h - +PLUGIN_TYPE = accessible +PLUGIN_EXTENDS = widgets +PLUGIN_CLASS_NAME = AccessibleFactory +load(qt_plugin) diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 468bffe49e..9a8bfc552d 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -190,7 +190,6 @@ public: QSize sizeHint() const Q_DECL_OVERRIDE; virtual void setCellBrush(int row, int col, const QBrush &); - QBrush cellBrush(int row, int col); inline int cellWidth() const { return cellw; } @@ -459,20 +458,6 @@ void QWellArray::setCellBrush(int row, int col, const QBrush &b) d->brush[row*numCols()+col] = b; } -/* - Returns the brush set for the cell at \a row, \a column. If no brush is - set, Qt::NoBrush is returned. -*/ - -QBrush QWellArray::cellBrush(int row, int col) -{ - if (d && row >= 0 && row < numRows() && col >= 0 && col < numCols()) - return d->brush[row*numCols()+col]; - return Qt::NoBrush; -} - - - /*!\reimp */ diff --git a/src/widgets/dialogs/qsidebar.cpp b/src/widgets/dialogs/qsidebar.cpp index f883705cc3..645f418c4e 100644 --- a/src/widgets/dialogs/qsidebar.cpp +++ b/src/widgets/dialogs/qsidebar.cpp @@ -460,6 +460,7 @@ void QSidebar::removeEntry() QList<QModelIndex> idxs = selectionModel()->selectedIndexes(); QList<QPersistentModelIndex> indexes; const int numIndexes = idxs.count(); + indexes.reserve(numIndexes); for (int i = 0; i < numIndexes; i++) indexes.append(idxs.at(i)); diff --git a/src/widgets/dialogs/qwizard.h b/src/widgets/dialogs/qwizard.h index 9193f0b659..e0bb1459d5 100644 --- a/src/widgets/dialogs/qwizard.h +++ b/src/widgets/dialogs/qwizard.h @@ -182,7 +182,7 @@ protected: void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; #ifdef Q_OS_WIN - bool nativeEvent(const QByteArray &eventType, void * message, long * result); + bool nativeEvent(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE; #endif void done(int result) Q_DECL_OVERRIDE; virtual void initializePage(int id); diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp index a4b37f360b..b210cb904d 100644 --- a/src/widgets/dialogs/qwizard_win.cpp +++ b/src/widgets/dialogs/qwizard_win.cpp @@ -47,18 +47,6 @@ #include <QtGui/QWindow> #include <QtWidgets/QDesktopWidget> -// Note, these tests are duplicates in qwindowsxpstyle_p.h. -#ifdef Q_CC_GNU -# include <w32api.h> -# if (__W32API_MAJOR_VERSION >= 3 || (__W32API_MAJOR_VERSION == 2 && __W32API_MINOR_VERSION >= 5)) -# ifdef _WIN32_WINNT -# undef _WIN32_WINNT -# endif -# define _WIN32_WINNT 0x0501 -# include <commctrl.h> -# endif -#endif - #include <uxtheme.h> Q_DECLARE_METATYPE(QMargins) diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp index 8ffb60411c..cd651e2897 100644 --- a/src/widgets/graphicsview/qgraphicswidget.cpp +++ b/src/widgets/graphicsview/qgraphicswidget.cpp @@ -306,6 +306,7 @@ void QGraphicsWidget::resize(const QSizeF &size) \fn void QGraphicsWidget::resize(qreal w, qreal h) \overload + Constructs a resize with the given \c width (\a w) and \c height (\a h). This convenience function is equivalent to calling resize(QSizeF(w, h)). \sa setGeometry(), setTransform() diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index ad7be840d0..a126fef65e 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -4353,7 +4353,20 @@ QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QItemViewPaintPairs paintPairs = draggablePaintPairs(indexes, r); if (paintPairs.isEmpty()) return QPixmap(); - QPixmap pixmap(r->size()); + + qreal scale = 1.0f; + + Q_Q(const QAbstractItemView); + QWidget *window = q->window(); + if (window) { + QWindow *windowHandle = window->windowHandle(); + if (windowHandle) + scale = windowHandle->devicePixelRatio(); + } + + QPixmap pixmap(r->size() * scale); + pixmap.setDevicePixelRatio(scale); + pixmap.fill(Qt::transparent); QPainter painter(&pixmap); QStyleOptionViewItem option = viewOptionsV1(); diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 9c79509874..18ea19c8b9 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -1437,7 +1437,7 @@ QModelIndexList QListView::selectedIndexes() const return QModelIndexList(); QModelIndexList viewSelected = d->selectionModel->selectedIndexes(); - for (int i = 0; i < viewSelected.count(); ++i) { + for (int i = 0; i < viewSelected.count();) { const QModelIndex &index = viewSelected.at(i); if (!isIndexHidden(index) && index.parent() == d->root && index.column() == d->column) ++i; @@ -1978,6 +1978,11 @@ int QCommonListViewBase::horizontalScrollToValue(const int /*index*/, QListView: /* * ListMode ListView Implementation */ +QListModeViewBase::QListModeViewBase(QListView *q, QListViewPrivate *d) + : QCommonListViewBase(q, d) +{ + dd->defaultDropAction = Qt::CopyAction; +} #ifndef QT_NO_DRAGANDDROP QAbstractItemView::DropIndicatorPosition QListModeViewBase::position(const QPoint &pos, const QRect &rect, const QModelIndex &index) const @@ -2744,7 +2749,7 @@ bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions) drag->setMimeData(dd->model->mimeData(indexes)); drag->setPixmap(pixmap); drag->setHotSpot(dd->pressedPosition - rect.topLeft()); - Qt::DropAction action = drag->exec(supportedActions, Qt::CopyAction); + Qt::DropAction action = drag->exec(supportedActions, dd->defaultDropAction); draggedItems.clear(); if (action == Qt::MoveAction) dd->clearOrRemove(); diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h index 62fa45e640..d1ea6fe328 100644 --- a/src/widgets/itemviews/qlistview_p.h +++ b/src/widgets/itemviews/qlistview_p.h @@ -193,7 +193,7 @@ public: class QListModeViewBase : public QCommonListViewBase { public: - QListModeViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d) {} + QListModeViewBase(QListView *q, QListViewPrivate *d); QVector<int> flowPositions; QVector<int> segmentPositions; diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 91302d9e62..b34380dbc3 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -417,6 +417,7 @@ QWidget *QApplicationPrivate::hidden_focus_widget = 0; // will get keyboard inpu QWidget *QApplicationPrivate::active_window = 0; // toplevel with keyboard focus #ifndef QT_NO_WHEELEVENT int QApplicationPrivate::wheel_scroll_lines; // number of lines to scroll +QPointer<QWidget> QApplicationPrivate::wheel_widget; #endif bool qt_in_tab_key_event = false; int qt_antialiasing_threshold = -1; @@ -561,13 +562,18 @@ QApplication::QApplication(int &argc, char **argv) QApplication::QApplication(int &argc, char **argv, int _internal) #endif : QGuiApplication(*new QApplicationPrivate(argc, argv, _internal)) -{ Q_D(QApplication); d->construct(); } +{ + Q_D(QApplication); + d->init(); +} /*! \internal */ -void QApplicationPrivate::construct() +void QApplicationPrivate::init() { + QGuiApplicationPrivate::init(); + initResources(); qt_is_gui_used = (application_type != QApplicationPrivate::Tty); @@ -3161,9 +3167,8 @@ bool QApplication::notify(QObject *receiver, QEvent *e) case QEvent::KeyRelease: { bool isWidget = receiver->isWidgetType(); - bool isGraphicsWidget = false; #ifndef QT_NO_GRAPHICSVIEW - isGraphicsWidget = !isWidget && qobject_cast<QGraphicsWidget *>(receiver); + const bool isGraphicsWidget = !isWidget && qobject_cast<QGraphicsWidget *>(receiver); #endif QKeyEvent* key = static_cast<QKeyEvent*>(e); bool def = key->isAccepted(); @@ -3310,7 +3315,6 @@ bool QApplication::notify(QObject *receiver, QEvent *e) case QEvent::Wheel: { QWidget* w = static_cast<QWidget *>(receiver); - QWheelEvent* wheel = static_cast<QWheelEvent*>(e); // QTBUG-40656, QTBUG-42731: ignore wheel events when a popup (QComboBox) is open. if (const QWidget *popup = QApplication::activePopupWidget()) { @@ -3318,27 +3322,89 @@ bool QApplication::notify(QObject *receiver, QEvent *e) return true; } - QPoint relpos = wheel->pos(); - bool eventAccepted = wheel->isAccepted(); + QWheelEvent* wheel = static_cast<QWheelEvent*>(e); + const bool spontaneous = wheel->spontaneous(); + const Qt::ScrollPhase phase = wheel->phase(); + + // Ideally, we should lock on a widget when it starts receiving wheel + // events. This avoids other widgets to start receiving those events + // as the mouse cursor hovers them. However, given the way common + // wheeled mice work, there's no certain way of connecting different + // wheel events as a stream. This results in the NoScrollPhase case, + // where we just send the event from the original receiver and up its + // hierarchy until the event gets accepted. + // + // In the case of more evolved input devices, like Apple's trackpad or + // Magic Mouse, we receive the scroll phase information. This helps us + // connect wheel events as a stream and therefore makes it easier to + // lock on the widget onto which the scrolling was initiated. + // + // We assume that, when supported, the phase cycle follows the pattern: + // + // ScrollBegin (ScrollUpdate* ScrollEnd)+ + // + // This means that we can have scrolling sequences (starting with ScrollBegin) + // or partial sequences (after a ScrollEnd and starting with ScrollUpdate). + // If wheel_widget is null because it was deleted, we also take the same + // code path as an initial sequence. + if (phase == Qt::NoScrollPhase || phase == Qt::ScrollBegin || !QApplicationPrivate::wheel_widget) { + + // A system-generated ScrollBegin event starts a new user scrolling + // sequence, so we reset wheel_widget in case no one accepts the event + // or if we didn't get (or missed) a ScrollEnd previously. + if (spontaneous && phase == Qt::ScrollBegin) + QApplicationPrivate::wheel_widget = Q_NULLPTR; + + const QPoint &relpos = wheel->pos(); + + if (spontaneous && (phase == Qt::NoScrollPhase || phase == Qt::ScrollUpdate)) + QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, e, relpos); - if (e->spontaneous() && wheel->phase() == Qt::ScrollUpdate) - QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, e, relpos); + QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(), + wheel->modifiers(), phase, wheel->source()); + bool eventAccepted; + while (w) { + we.spont = spontaneous && w == receiver; + we.ignore(); + res = d->notify_helper(w, &we); + eventAccepted = we.isAccepted(); + if (res && eventAccepted) { + // A new scrolling sequence or partial sequence starts and w has accepted + // the event. Therefore, we can set wheel_widget, but only if it's not + // the end of a sequence. + if (spontaneous && (phase == Qt::ScrollBegin || phase == Qt::ScrollUpdate) && QGuiApplicationPrivate::scrollNoPhaseAllowed) + QApplicationPrivate::wheel_widget = w; + break; + } + if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation)) + break; - while (w) { + we.p += w->pos(); + w = w->parentWidget(); + } + wheel->setAccepted(eventAccepted); + } else if (!spontaneous) { + // wheel_widget may forward the wheel event to a delegate widget, + // either directly or indirectly (e.g. QAbstractScrollArea will + // forward to its QScrollBars through viewportEvent()). In that + // case, the event will not be spontaneous but synthesized, so + // we can send it straight to the receiver. + d->notify_helper(w, wheel); + } else { + // The phase is either ScrollUpdate or ScrollEnd, and wheel_widget + // is set. Since it accepted the wheel event previously, we continue + // sending those events until we get a ScrollEnd, which signifies + // the end of the natural scrolling sequence. + const QPoint &relpos = QApplicationPrivate::wheel_widget->mapFromGlobal(wheel->globalPos()); QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(), wheel->modifiers(), wheel->phase(), wheel->source()); - we.spont = wheel->spontaneous(); - res = d->notify_helper(w, w == receiver ? wheel : &we); - eventAccepted = ((w == receiver) ? wheel : &we)->isAccepted(); - e->spont = false; - if ((res && eventAccepted) - || w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation)) - break; - - relpos += w->pos(); - w = w->parentWidget(); + we.spont = true; + we.ignore(); + d->notify_helper(QApplicationPrivate::wheel_widget, &we); + wheel->setAccepted(we.isAccepted()); + if (phase == Qt::ScrollEnd) + QApplicationPrivate::wheel_widget = Q_NULLPTR; } - wheel->setAccepted(eventAccepted); } break; #endif @@ -3515,6 +3581,10 @@ bool QApplication::notify(QObject *receiver, QEvent *e) QApplicationPrivate::giveFocusAccordingToFocusPolicy(widget, e, localPos); } +#ifndef QT_NO_GESTURES + QPointer<QWidget> gesturePendingWidget; +#endif + while (widget) { // first, try to deliver the touch event acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents); @@ -3532,14 +3602,16 @@ bool QApplication::notify(QObject *receiver, QEvent *e) touchEvent->spont = false; if (res && eventAccepted) { // the first widget to accept the TouchBegin gets an implicit grab. - for (int i = 0; i < touchEvent->touchPoints().count(); ++i) { - const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i); - d->activeTouchPoints[QGuiApplicationPrivate::ActiveTouchPointsKey(touchEvent->device(), touchPoint.id())].target = widget; - } - break; - } else if (p.isNull() || widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) { + d->activateImplicitTouchGrab(widget, touchEvent); break; } +#ifndef QT_NO_GESTURES + if (gesturePendingWidget.isNull() && widget && QGestureManager::gesturePending(widget)) + gesturePendingWidget = widget; +#endif + if (p.isNull() || widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) + break; + QPoint offset = widget->pos(); widget = widget->parentWidget(); touchEvent->setTarget(widget); @@ -3553,9 +3625,27 @@ bool QApplication::notify(QObject *receiver, QEvent *e) } } +#ifndef QT_NO_GESTURES + if (!eventAccepted && !gesturePendingWidget.isNull()) { + // the first widget subscribed to a gesture gets an implicit grab + d->activateImplicitTouchGrab(gesturePendingWidget, touchEvent); + } +#endif + touchEvent->setAccepted(eventAccepted); break; } + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + { + QWidget *widget = static_cast<QWidget *>(receiver); + // We may get here if the widget is subscribed to a gesture, + // but has not accepted TouchBegin. Propagate touch events + // only if TouchBegin has been accepted. + if (widget && widget->testAttribute(Qt::WA_WState_AcceptedTouchBeginEvent)) + res = d->notify_helper(widget, e); + break; + } case QEvent::RequestSoftwareInputPanel: inputMethod()->show(); break; @@ -4295,6 +4385,17 @@ QWidget *QApplicationPrivate::findClosestTouchPointTarget(QTouchDevice *device, return static_cast<QWidget *>(closestTarget); } +void QApplicationPrivate::activateImplicitTouchGrab(QWidget *widget, QTouchEvent *touchEvent) +{ + if (touchEvent->type() != QEvent::TouchBegin) + return; + + for (int i = 0, tc = touchEvent->touchPoints().count(); i < tc; ++i) { + const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i); + activeTouchPoints[QGuiApplicationPrivate::ActiveTouchPointsKey(touchEvent->device(), touchPoint.id())].target = widget; + } +} + bool QApplicationPrivate::translateRawTouchEvent(QWidget *window, QTouchDevice *device, const QList<QTouchEvent::TouchPoint> &touchPoints, @@ -4425,10 +4526,11 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window, || QGestureManager::gesturePending(widget) #endif ) { - if (touchEvent.type() == QEvent::TouchEnd) - widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, false); if (QApplication::sendSpontaneousEvent(widget, &touchEvent) && touchEvent.isAccepted()) accepted = true; + // widget can be deleted on TouchEnd + if (touchEvent.type() == QEvent::TouchEnd && !widget.isNull()) + widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, false); } break; } diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index 75d86a5eba..4b3cf773dc 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -150,7 +150,7 @@ public: bool notify_helper(QObject *receiver, QEvent * e); - void construct( + void init( #ifdef Q_DEAD_CODE_FROM_QT4_X11 Display *dpy = 0, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0 #endif @@ -202,6 +202,7 @@ public: static QWidget *active_window; #ifndef QT_NO_WHEELEVENT static int wheel_scroll_lines; + static QPointer<QWidget> wheel_widget; #endif static int enabledAnimations; // Combination of QPlatformTheme::UiEffect @@ -281,6 +282,7 @@ public: QWidget *findClosestTouchPointTarget(QTouchDevice *device, const QTouchEvent::TouchPoint &touchPoint); void appendTouchPoint(const QTouchEvent::TouchPoint &touchPoint); void removeTouchPoint(int touchPointId); + void activateImplicitTouchGrab(QWidget *widget, QTouchEvent *touchBeginEvent); static bool translateRawTouchEvent(QWidget *widget, QTouchDevice *device, const QList<QTouchEvent::TouchPoint> &touchPoints, diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp index fb2914d53a..967ef6b40c 100644 --- a/src/widgets/kernel/qgesturemanager.cpp +++ b/src/widgets/kernel/qgesturemanager.cpp @@ -548,9 +548,9 @@ bool QGestureManager::filterEvent(QObject *receiver, QEvent *event) if (widgetWindow) return filterEvent(widgetWindow->widget(), event); - if (!m_gestureToRecognizer.contains(static_cast<QGesture *>(receiver))) + QGesture *state = qobject_cast<QGesture *>(receiver); + if (!state || !m_gestureToRecognizer.contains(state)) return false; - QGesture *state = static_cast<QGesture *>(receiver); QMultiMap<QObject *, Qt::GestureType> contexts; contexts.insert(state, state->gestureType()); return filterEventThroughContexts(contexts, event); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 5bff30524a..6fdd5d3d0e 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1880,7 +1880,6 @@ void QWidgetPrivate::deleteTLSysExtra() if (extra->topextra->window) { extra->topextra->window->destroy(); } - setWinId(0); delete extra->topextra->window; extra->topextra->window = 0; @@ -6415,13 +6414,13 @@ bool QWidget::hasFocus() const const QWidget* w = this; while (w->d_func()->extra && w->d_func()->extra->focus_proxy) w = w->d_func()->extra->focus_proxy; - if (QWidget *window = w->window()) { #ifndef QT_NO_GRAPHICSVIEW + if (QWidget *window = w->window()) { QWExtra *e = window->d_func()->extra; if (e && e->proxyWidget && e->proxyWidget->hasFocus() && window->focusWidget() == w) return true; -#endif } +#endif // !QT_NO_GRAPHICSVIEW return (QApplication::focusWidget() == w); } @@ -7216,7 +7215,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) if (q->isVisible()) hide_sys(); data.crect = QRect(x, y, w, h); - } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) { + } else if (q->testAttribute(Qt::WA_OutsideWSRange)) { q->setAttribute(Qt::WA_OutsideWSRange, false); needsShow = true; } @@ -7918,8 +7917,11 @@ void QWidgetPrivate::show_sys() invalidateBuffer(q->rect()); q->setAttribute(Qt::WA_Mapped); // add our window the modal window list (native dialogs) - if ((q->isWindow() && (!extra || !extra->proxyWidget)) - && q->windowModality() != Qt::NonModal && window) { + if (window && q->isWindow() +#ifndef QT_NO_GRAPHICSVIEW + && (!extra || !extra->proxyWidget) +#endif + && q->windowModality() != Qt::NonModal) { QGuiApplicationPrivate::showModalWindow(window); } return; @@ -8053,8 +8055,11 @@ void QWidgetPrivate::hide_sys() if (q->testAttribute(Qt::WA_DontShowOnScreen)) { q->setAttribute(Qt::WA_Mapped, false); // remove our window from the modal window list (native dialogs) - if ((q->isWindow() && (!extra || !extra->proxyWidget)) - && q->windowModality() != Qt::NonModal && window) { + if (window && q->isWindow() +#ifndef QT_NO_GRAPHICSVIEW + && (!extra || !extra->proxyWidget) +#endif + && q->windowModality() != Qt::NonModal) { QGuiApplicationPrivate::hideModalWindow(window); } // do not return here, if window non-zero, we must hide it @@ -12842,9 +12847,8 @@ void QWidget::setMask(const QRegion &newMask) void QWidgetPrivate::setMask_sys(const QRegion ®ion) { Q_Q(QWidget); - if (const QWindow *window = q->windowHandle()) - if (QPlatformWindow *platformWindow = window->handle()) - platformWindow->setMask(QHighDpi::toNativeLocalRegion(region, window)); + if (QWindow *window = q->windowHandle()) + window->setMask(region); } /*! diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index a56f6e1133..2af1550ad1 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -605,43 +605,43 @@ Q_SIGNALS: protected: // Event handlers - bool event(QEvent *) Q_DECL_OVERRIDE; - virtual void mousePressEvent(QMouseEvent *); - virtual void mouseReleaseEvent(QMouseEvent *); - virtual void mouseDoubleClickEvent(QMouseEvent *); - virtual void mouseMoveEvent(QMouseEvent *); + bool event(QEvent *event) Q_DECL_OVERRIDE; + virtual void mousePressEvent(QMouseEvent *event); + virtual void mouseReleaseEvent(QMouseEvent *event); + virtual void mouseDoubleClickEvent(QMouseEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); #ifndef QT_NO_WHEELEVENT - virtual void wheelEvent(QWheelEvent *); -#endif - virtual void keyPressEvent(QKeyEvent *); - virtual void keyReleaseEvent(QKeyEvent *); - virtual void focusInEvent(QFocusEvent *); - virtual void focusOutEvent(QFocusEvent *); - virtual void enterEvent(QEvent *); - virtual void leaveEvent(QEvent *); - virtual void paintEvent(QPaintEvent *); - virtual void moveEvent(QMoveEvent *); - virtual void resizeEvent(QResizeEvent *); - virtual void closeEvent(QCloseEvent *); + virtual void wheelEvent(QWheelEvent *event); +#endif + virtual void keyPressEvent(QKeyEvent *event); + virtual void keyReleaseEvent(QKeyEvent *event); + virtual void focusInEvent(QFocusEvent *event); + virtual void focusOutEvent(QFocusEvent *event); + virtual void enterEvent(QEvent *event); + virtual void leaveEvent(QEvent *event); + virtual void paintEvent(QPaintEvent *event); + virtual void moveEvent(QMoveEvent *event); + virtual void resizeEvent(QResizeEvent *event); + virtual void closeEvent(QCloseEvent *event); #ifndef QT_NO_CONTEXTMENU - virtual void contextMenuEvent(QContextMenuEvent *); + virtual void contextMenuEvent(QContextMenuEvent *event); #endif #ifndef QT_NO_TABLETEVENT - virtual void tabletEvent(QTabletEvent *); + virtual void tabletEvent(QTabletEvent *event); #endif #ifndef QT_NO_ACTION - virtual void actionEvent(QActionEvent *); + virtual void actionEvent(QActionEvent *event); #endif #ifndef QT_NO_DRAGANDDROP - virtual void dragEnterEvent(QDragEnterEvent *); - virtual void dragMoveEvent(QDragMoveEvent *); - virtual void dragLeaveEvent(QDragLeaveEvent *); - virtual void dropEvent(QDropEvent *); + virtual void dragEnterEvent(QDragEnterEvent *event); + virtual void dragMoveEvent(QDragMoveEvent *event); + virtual void dragLeaveEvent(QDragLeaveEvent *event); + virtual void dropEvent(QDropEvent *event); #endif - virtual void showEvent(QShowEvent *); - virtual void hideEvent(QHideEvent *); + virtual void showEvent(QShowEvent *event); + virtual void hideEvent(QHideEvent *event); virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result); // Misc. protected functions diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 334b6cd463..bfa1d69fa8 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1249,13 +1249,15 @@ void QWidgetBackingStore::doSync() // OpenGL content changes. Check if we have such widgets in the special // dirty list. QVarLengthArray<QWidget *, 16> paintPending; - for (int i = 0; i < dirtyRenderToTextureWidgets.count(); ++i) { + const int numPaintPending = dirtyRenderToTextureWidgets.count(); + paintPending.reserve(numPaintPending); + for (int i = 0; i < numPaintPending; ++i) { QWidget *w = dirtyRenderToTextureWidgets.at(i); paintPending << w; resetWidget(w); } dirtyRenderToTextureWidgets.clear(); - for (int i = 0; i < paintPending.count(); ++i) { + for (int i = 0; i < numPaintPending; ++i) { QWidget *w = paintPending[i]; w->d_func()->sendPaintEvent(w->rect()); if (w != tlw) { diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 0de0fe21f2..15c28d0913 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -313,6 +313,14 @@ QPointer<QWidget> qt_last_mouse_receiver = 0; void QWidgetWindow::handleEnterLeaveEvent(QEvent *event) { +#if !defined(Q_OS_OSX) && !defined(Q_OS_IOS) // Cocoa tracks popups + // Ignore all enter/leave events from QPA if we are not on the first-level context menu. + // This prevents duplicated events on most platforms. Fake events will be delivered in + // QWidgetWindow::handleMouseEvent(QMouseEvent *). Make an exception whether the widget + // is already under mouse - let the mouse leave. + if (QApplicationPrivate::inPopupMode() && m_widget != QApplication::activePopupWidget() && !m_widget->underMouse()) + return; +#endif if (event->type() == QEvent::Leave) { QWidget *enter = 0; // Check from window system event queue if the next queued enter targets a window @@ -407,14 +415,13 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) QEvent::MouseButtonRelease : QEvent::MouseButtonPress; if (qApp->d_func()->inPopupMode()) { QWidget *activePopupWidget = qApp->activePopupWidget(); - QWidget *popup = activePopupWidget; QPoint mapped = event->pos(); - if (popup != m_widget) - mapped = popup->mapFromGlobal(event->globalPos()); + if (activePopupWidget != m_widget) + mapped = activePopupWidget->mapFromGlobal(event->globalPos()); bool releaseAfter = false; - QWidget *popupChild = popup->childAt(mapped); + QWidget *popupChild = activePopupWidget->childAt(mapped); - if (popup != qt_popup_down) { + if (activePopupWidget != qt_popup_down) { qt_button_down = 0; qt_popup_down = 0; } @@ -423,7 +430,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) case QEvent::MouseButtonPress: case QEvent::MouseButtonDblClick: qt_button_down = popupChild; - qt_popup_down = popup; + qt_popup_down = activePopupWidget; break; case QEvent::MouseButtonRelease: releaseAfter = true; @@ -434,18 +441,41 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) int oldOpenPopupCount = openPopupCount; - if (popup->isEnabled()) { + if (activePopupWidget->isEnabled()) { // deliver event qt_replay_popup_mouse_event = false; - QWidget *receiver = popup; + QWidget *receiver = activePopupWidget; QPoint widgetPos = mapped; if (qt_button_down) receiver = qt_button_down; else if (popupChild) receiver = popupChild; - if (receiver != popup) + if (receiver != activePopupWidget) widgetPos = receiver->mapFromGlobal(event->globalPos()); - QWidget *alien = m_widget->childAt(m_widget->mapFromGlobal(event->globalPos())); + QWidget *alien = receiver; + +#if !defined(Q_OS_OSX) && !defined(Q_OS_IOS) // Cocoa tracks popups + const bool reallyUnderMouse = activePopupWidget->rect().contains(mapped); + const bool underMouse = activePopupWidget->underMouse(); + if (activePopupWidget != m_widget || (!underMouse && qt_button_down)) { + // If active popup menu is not the first-level popup menu then we must emulate enter/leave events, + // because first-level popup menu grabs the mouse and enter/leave events are delivered only to it + // by QPA. Make an exception for first-level popup menu when the mouse button is pressed on widget. + if (underMouse != reallyUnderMouse) { + if (reallyUnderMouse) { + QApplicationPrivate::dispatchEnterLeave(receiver, Q_NULLPTR, event->screenPos()); + qt_last_mouse_receiver = receiver; + } else { + QApplicationPrivate::dispatchEnterLeave(Q_NULLPTR, qt_last_mouse_receiver, event->screenPos()); + qt_last_mouse_receiver = receiver; + receiver = activePopupWidget; + } + } + } else if (!reallyUnderMouse) { + alien = Q_NULLPTR; + } +#endif + QMouseEvent e(event->type(), widgetPos, event->windowPos(), event->screenPos(), event->button(), event->buttons(), event->modifiers(), event->source()); e.setTimestamp(event->timestamp()); @@ -457,7 +487,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) case QEvent::MouseButtonPress: case QEvent::MouseButtonDblClick: case QEvent::MouseButtonRelease: - popup->close(); + activePopupWidget->close(); break; default: break; @@ -503,7 +533,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) } else if (event->type() == contextMenuTrigger && event->button() == Qt::RightButton && (openPopupCount == oldOpenPopupCount)) { - QWidget *popupEvent = popup; + QWidget *popupEvent = activePopupWidget; if (qt_button_down) popupEvent = qt_button_down; else if(popupChild) @@ -717,13 +747,24 @@ void QWidgetWindow::handleWheelEvent(QWheelEvent *event) if (QApplicationPrivate::instance()->modalState() && !qt_try_modal(m_widget, event->type())) return; + QWidget *rootWidget = m_widget; + QPoint pos = event->pos(); + + // Use proper popup window for wheel event. Some QPA sends the wheel + // event to the root menu, so redirect it to the proper popup window. + QWidget *activePopupWidget = QApplication::activePopupWidget(); + if (activePopupWidget && activePopupWidget != m_widget) { + rootWidget = activePopupWidget; + pos = rootWidget->mapFromGlobal(event->globalPos()); + } + // which child should have it? - QWidget *widget = m_widget->childAt(event->pos()); + QWidget *widget = rootWidget->childAt(pos); if (!widget) - widget = m_widget; + widget = rootWidget; - QPoint mapped = widget->mapFrom(m_widget, event->pos()); + QPoint mapped = widget->mapFrom(rootWidget, pos); QWheelEvent translated(mapped, event->globalPos(), event->pixelDelta(), event->angleDelta(), event->delta(), event->orientation(), event->buttons(), event->modifiers(), event->phase(), event->source()); QGuiApplication::sendSpontaneousEvent(widget, &translated); diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index ac23512f1d..4f688f6f28 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -4608,7 +4608,8 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter HIRect menuRect = qt_hirectForQRect(mi->menuRect); HIRect itemRect = qt_hirectForQRect(mi->rect); - if ((opt->state & State_Selected) && (opt->state & State_Enabled) && (opt->state & State_Sunken)){ + const bool selected = (opt->state & State_Selected) && (opt->state & State_Enabled) && (opt->state & State_Sunken); + if (selected) { // Draw a selected menu item background: HIThemeMenuItemDrawInfo mdi; mdi.version = qt_mac_hitheme_version; @@ -4636,7 +4637,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter Qt::AlignCenter | Qt::TextHideMnemonic | Qt::TextDontClip | Qt::TextSingleLine, mi->palette, mi->state & State_Enabled, - mi->text, QPalette::ButtonText); + mi->text, selected ? QPalette::HighlightedText : QPalette::ButtonText); } } break; diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h index 1e9d15c993..26d1c63195 100644 --- a/src/widgets/styles/qstyle.h +++ b/src/widgets/styles/qstyle.h @@ -66,13 +66,13 @@ public: QStyle(); virtual ~QStyle(); - virtual void polish(QWidget *); - virtual void unpolish(QWidget *); + virtual void polish(QWidget *widget); + virtual void unpolish(QWidget *widget); - virtual void polish(QApplication *); - virtual void unpolish(QApplication *); + virtual void polish(QApplication *application); + virtual void unpolish(QApplication *application); - virtual void polish(QPalette &); + virtual void polish(QPalette &palette); virtual QRect itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp index d66dbec472..28c0b41a15 100644 --- a/src/widgets/styles/qstyleoption.cpp +++ b/src/widgets/styles/qstyleoption.cpp @@ -198,7 +198,7 @@ void QStyleOption::init(const QWidget *widget) if (!(state & QStyle::State_Active) && !qt_mac_can_clickThrough(widget)) state &= ~QStyle::State_Enabled; #endif -#if defined(Q_OS_MACX) +#if defined(Q_OS_OSX) && !defined(QT_NO_STYLE_MAC) switch (QMacStyle::widgetSizePolicy(widget)) { case QMacStyle::SizeSmall: state |= QStyle::State_Small; diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index 3fa0fc899d..d900e4d181 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -213,6 +213,26 @@ void QWindowsVistaAnimation::paint(QPainter *painter, const QStyleOption *option painter->drawImage(option->rect, currentImage()); } +static inline bool supportsStateTransition(QStyle::PrimitiveElement element, + const QStyleOption *option, + const QWidget *widget) +{ + bool result = false; + switch (element) { + case QStyle::PE_IndicatorRadioButton: + case QStyle::PE_IndicatorCheckBox: + result = true; + break; + // QTBUG-40634, do not animate when color is set in palette for PE_PanelLineEdit. + case QStyle::PE_FrameLineEdit: + result = !QWindowsXPStylePrivate::isLineEditBaseColorSet(option, widget); + break; + default: + break; + } + return result; +} + /*! \internal @@ -243,6 +263,7 @@ void QWindowsVistaAnimation::paint(QPainter *painter, const QStyleOption *option starting image for the hover transition. */ + void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { @@ -259,11 +280,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt QRect oldRect; QRect newRect; - /* widgets that support state transitions : */ - if ( element == PE_FrameLineEdit - || element == PE_IndicatorRadioButton - || element == PE_IndicatorCheckBox) - { + if (supportsStateTransition(element, option, widget)) { // Retrieve and update the dynamic properties tracking // the previous state of the widget: QObject *styleObject = option->styleObject; @@ -498,26 +515,9 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt case PE_PanelLineEdit: if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) { - QBrush bg; - bool usePalette = false; bool isEnabled = option->state & State_Enabled; - uint resolve_mask = panel->palette.resolve(); - if (widget) { - // Since spin box includes a line edit we need to resolve the palette mask also from - // the parent, as while the color is always correct on the palette supplied by panel, - // the mask can still be empty. If either mask specifies custom base color, use that. -#ifndef QT_NO_SPINBOX - if (QAbstractSpinBox *spinbox = qobject_cast<QAbstractSpinBox*>(widget->parentWidget())) - resolve_mask |= spinbox->palette().resolve(); -#endif // QT_NO_SPINBOX - } - if (resolve_mask & (1 << QPalette::Base)) { - // Base color is set for this widget, so use it - bg = panel->palette.brush(QPalette::Base); - usePalette = true; - } - if (usePalette) { - painter->fillRect(panel->rect, bg); + if (QWindowsXPStylePrivate::isLineEditBaseColorSet(option, widget)) { + painter->fillRect(panel->rect, panel->palette.brush(QPalette::Base)); } else { int partId = EP_BACKGROUND; int stateId = EBS_NORMAL; diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp index c350e82c69..5b01312dfb 100644 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ b/src/widgets/styles/qwindowsxpstyle.cpp @@ -371,6 +371,22 @@ bool QWindowsXPStylePrivate::isItemViewDelegateLineEdit(const QWidget *widget) && parent2->inherits("QAbstractItemView"); } +// Returns whether base color is set for this widget +bool QWindowsXPStylePrivate::isLineEditBaseColorSet(const QStyleOption *option, const QWidget *widget) +{ + uint resolveMask = option->palette.resolve(); + if (widget) { + // Since spin box includes a line edit we need to resolve the palette mask also from + // the parent, as while the color is always correct on the palette supplied by panel, + // the mask can still be empty. If either mask specifies custom base color, use that. +#ifndef QT_NO_SPINBOX + if (const QAbstractSpinBox *spinbox = qobject_cast<QAbstractSpinBox*>(widget->parentWidget())) + resolveMask |= spinbox->palette().resolve(); +#endif // QT_NO_SPINBOX + } + return (resolveMask & (1 << QPalette::Base)) != 0; +} + /*! \internal This function will always return a valid window handle, and might create a limbo widget to do so. @@ -1600,30 +1616,12 @@ case PE_Frame: themeNumber = QWindowsXPStylePrivate::EditTheme; partId = EP_EDITTEXT; noBorder = true; - QBrush bg; - bool usePalette = false; bool isEnabled = flags & State_Enabled; - uint resolve_mask = panel->palette.resolve(); - -#ifndef QT_NO_SPINBOX - // Since spin box includes a line edit we need to resolve the palette mask also from - // the parent, as while the color is always correct on the palette supplied by panel, - // the mask can still be empty. If either mask specifies custom base color, use that. - if (widget) { - if (QAbstractSpinBox *spinbox = qobject_cast<QAbstractSpinBox*>(widget->parentWidget())) - resolve_mask |= spinbox->palette().resolve(); - } -#endif // QT_NO_SPINBOX - if (resolve_mask & (1 << QPalette::Base)) { - // Base color is set for this widget, so use it - bg = panel->palette.brush(QPalette::Base); - usePalette = true; - } stateId = isEnabled ? ETS_NORMAL : ETS_DISABLED; - if (usePalette) { - p->fillRect(panel->rect, bg); + if (QWindowsXPStylePrivate::isLineEditBaseColorSet(option, widget)) { + p->fillRect(panel->rect, panel->palette.brush(QPalette::Base)); } else { XPThemeData theme(0, p, themeNumber, partId, stateId, rect); if (!theme.isValid()) { diff --git a/src/widgets/styles/qwindowsxpstyle_p_p.h b/src/widgets/styles/qwindowsxpstyle_p_p.h index 5ee418f278..e1e1369850 100644 --- a/src/widgets/styles/qwindowsxpstyle_p_p.h +++ b/src/widgets/styles/qwindowsxpstyle_p_p.h @@ -50,18 +50,6 @@ #include <qmap.h> #include <qt_windows.h> -// Note, these tests are duplicated in qwizard_win.cpp. -#ifdef Q_CC_GNU -# include <w32api.h> -# if (__W32API_MAJOR_VERSION >= 3 || (__W32API_MAJOR_VERSION == 2 && __W32API_MINOR_VERSION >= 5)) -# ifdef _WIN32_WINNT -# undef _WIN32_WINNT -# endif -# define _WIN32_WINNT 0x0501 -# include <commctrl.h> -# endif -#endif - #include <uxtheme.h> #if WINVER >= 0x0600 @@ -415,6 +403,7 @@ public: static QString themeName(int theme); static inline bool hasTheme(int theme) { return theme >= 0 && theme < NThemes && m_themes[theme]; } static bool isItemViewDelegateLineEdit(const QWidget *widget); + static bool isLineEditBaseColorSet(const QStyleOption *option, const QWidget *widget); QIcon dockFloat, dockClose; diff --git a/src/widgets/util/qcompleter_p.h b/src/widgets/util/qcompleter_p.h index b100f24f9b..afcdfe7aa2 100644 --- a/src/widgets/util/qcompleter_p.h +++ b/src/widgets/util/qcompleter_p.h @@ -122,7 +122,7 @@ private: }; struct QMatchData { - QMatchData() : exactMatchIndex(-1) { } + QMatchData() : exactMatchIndex(-1), partial(false) { } QMatchData(const QIndexMapper& indices, int em, bool p) : indices(indices), exactMatchIndex(em), partial(p) { } QIndexMapper indices; diff --git a/src/widgets/util/qsystemtrayicon_win.cpp b/src/widgets/util/qsystemtrayicon_win.cpp index f1b86ba2df..7e0212a233 100644 --- a/src/widgets/util/qsystemtrayicon_win.cpp +++ b/src/widgets/util/qsystemtrayicon_win.cpp @@ -34,13 +34,6 @@ #include "qsystemtrayicon_p.h" #ifndef QT_NO_SYSTEMTRAYICON -#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600 -# undef _WIN32_WINNT -#endif -#if !defined(_WIN32_WINNT) -# define _WIN32_WINNT 0x0600 -#endif - #if defined(_WIN32_IE) && _WIN32_IE < 0x0600 # undef _WIN32_IE #endif diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro index ceb6f96f7c..b609e4c434 100644 --- a/src/widgets/widgets.pro +++ b/src/widgets/widgets.pro @@ -8,13 +8,8 @@ DEFINES += QT_NO_USING_NAMESPACE win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x65000000 irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused -MODULE_PLUGIN_TYPES += \ - styles - QMAKE_DOCS = $$PWD/doc/qtwidgets.qdocconf -load(qt_module) - #platforms mac:include(kernel/mac.pri) win32:include(kernel/win.pri) @@ -45,3 +40,7 @@ QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtWidgets.dynlist testcocoon { load(testcocoon) } + +MODULE_PLUGIN_TYPES += \ + styles +load(qt_module) diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp index 48b224fe13..89cde851e5 100644 --- a/src/widgets/widgets/qcalendarwidget.cpp +++ b/src/widgets/widgets/qcalendarwidget.cpp @@ -654,7 +654,6 @@ public: int dateEditAcceptDelay() const; void setDateEditAcceptDelay(int delay); - QDate date() const; void setDate(const QDate &date); bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE; @@ -690,11 +689,6 @@ void QCalendarTextNavigator::setWidget(QWidget *widget) m_widget = widget; } -QDate QCalendarTextNavigator::date() const -{ - return m_date; -} - void QCalendarTextNavigator::setDate(const QDate &date) { m_date = date; diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 4a5ae6578a..ce30ca18c3 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -2436,6 +2436,7 @@ struct IndexSetter { { cb->setCurrentIndex(index); emit cb->activated(index); + emit cb->activated(cb->itemText(index)); } }; } diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index abee788a46..7ed4564654 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -873,7 +873,7 @@ void QDateTimeEdit::setDisplayFormat(const QString &format) d->displayFormat.clear(); for (int i=d->sectionNodes.size() - 1; i>=0; --i) { d->displayFormat += d->separators.at(i + 1); - d->displayFormat += d->sectionFormat(i); + d->displayFormat += d->sectionNode(i).format(); } d->displayFormat += d->separators.at(0); d->separators = reverse(d->separators); @@ -2214,9 +2214,9 @@ void QDateTimeEditPrivate::_q_editorCursorPositionChanged(int oldpos, int newpos } } - QDTEDEBUG << "currentSectionIndex is set to" << sectionName(sectionType(s)) + QDTEDEBUG << "currentSectionIndex is set to" << sectionNode(s).name() << oldpos << newpos - << "was" << sectionName(sectionType(currentSectionIndex)); + << "was" << sectionNode(currentSectionIndex).name(); currentSectionIndex = s; Q_ASSERT_X(currentSectionIndex < sectionNodes.size(), diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index df26db57ae..2823bd6f2f 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -3350,8 +3350,9 @@ QSet<QTabBar*> QDockAreaLayout::usedTabBars() const QSet<QWidget*> QDockAreaLayout::usedSeparatorWidgets() const { QSet<QWidget*> result; - - for (int i = 0; i < separatorWidgets.count(); ++i) + const int numSeparators = separatorWidgets.count(); + result.reserve(numSeparators); + for (int i = 0; i < numSeparators; ++i) result << separatorWidgets.at(i); for (int i = 0; i < QInternal::DockCount; ++i) { const QDockAreaLayoutInfo &dock = docks[i]; diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index 67eb466ba8..da6c3431ff 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -1445,6 +1445,8 @@ bool QDockWidget::event(QEvent *event) switch (event->type()) { #ifndef QT_NO_ACTION case QEvent::Hide: + if (d->state && d->state->dragging) + d->endDrag(true); if (layout != 0) layout->keepSize(this); d->toggleViewAction->setChecked(false); diff --git a/src/widgets/widgets/qmenu_mac.mm b/src/widgets/widgets/qmenu_mac.mm index 5322a8f3f5..184e4d7bb1 100644 --- a/src/widgets/widgets/qmenu_mac.mm +++ b/src/widgets/widgets/qmenu_mac.mm @@ -67,8 +67,11 @@ inline QPlatformNativeInterface::NativeResourceForIntegrationFunction resolvePla \since 5.2 Returns the native NSMenu for this menu. Available on OS X only. + + \note Qt sets the delegate on the native menu. If you need to set your own + delegate, make sure you save the original one and forward any calls to it. */ -NSMenu* QMenu::toNSMenu() +NSMenu *QMenu::toNSMenu() { // Call into the cocoa platform plugin: qMenuToNSMenu(platformMenu()) QPlatformNativeInterface::NativeResourceForIntegrationFunction function = resolvePlatformFunction("qmenutonsmenu"); @@ -133,8 +136,11 @@ void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem* \since 5.2 Returns the native NSMenu for this menu bar. Available on OS X only. + + \note Qt may set the delegate on the native menu bar. If you need to set your + own delegate, make sure you save the original one and forward any calls to it. */ -NSMenu* QMenuBar::toNSMenu() +NSMenu *QMenuBar::toNSMenu() { // Call into the cocoa platform plugin: qMenuBarToNSMenu(platformMenuBar()) QPlatformNativeInterface::NativeResourceForIntegrationFunction function = resolvePlatformFunction("qmenubartonsmenu"); diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 2e48607f82..cca0853a8f 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -690,7 +690,8 @@ void QMenuBarPrivate::init() q->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); q->setAttribute(Qt::WA_CustomWhatsThis); - platformMenuBar = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar(); + if (!QApplication::instance()->testAttribute(Qt::AA_DontUseNativeMenuBar)) + platformMenuBar = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar(); if (platformMenuBar) q->hide(); diff --git a/src/xml/xml.pro b/src/xml/xml.pro index 57bf11e5aa..f281e35444 100644 --- a/src/xml/xml.pro +++ b/src/xml/xml.pro @@ -6,11 +6,11 @@ win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x61000000 QMAKE_DOCS = $$PWD/doc/qtxml.qdocconf -load(qt_module) - HEADERS += qtxmlglobal.h PRECOMPILED_HEADER = include(dom/dom.pri) include(sax/sax.pri) + +load(qt_module) diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index 712e3440d8..46bf1a19e8 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -45,15 +45,7 @@ #include <QtNetwork/QHostInfo> #include <stdlib.h> -#ifndef QT_NO_PROCESS # include <private/qprocess_p.h> // only so we get QPROCESS_USE_SPAWN -# if defined(Q_OS_WIN) -# include <windows.h> -# endif - -Q_DECLARE_METATYPE(QProcess::ExitStatus); -Q_DECLARE_METATYPE(QProcess::ProcessState); -#endif typedef void (QProcess::*QProcessFinishedSignal1)(int); typedef void (QProcess::*QProcessFinishedSignal2)(int, QProcess::ExitStatus); @@ -153,6 +145,8 @@ private slots: void startStopStartStop(); void startStopStartStopBuffers_data(); void startStopStartStopBuffers(); + void processEventsInAReadyReadSlot_data(); + void processEventsInAReadyReadSlot(); // keep these at the end, since they use lots of processes and sometimes // caused obscure failures to occur in tests that followed them (esp. on the Mac) @@ -165,6 +159,7 @@ private slots: protected slots: void readFromProcess(); void exitLoopSlot(); + void processApplicationEvents(); #ifndef Q_OS_WINCE void restartProcess(); void waitForReadyReadInAReadyReadSlotSlot(); @@ -483,6 +478,11 @@ void tst_QProcess::exitLoopSlot() QTestEventLoop::instance().exitLoop(); } +void tst_QProcess::processApplicationEvents() +{ + QCoreApplication::processEvents(); +} + #ifndef Q_OS_WINCE // Reading and writing to a process is not supported on Qt/CE void tst_QProcess::echoTest2() @@ -697,11 +697,7 @@ void tst_QProcess::waitForFinished() process.start("testProcessOutput/testProcessOutput"); -#if !defined(Q_OS_WINCE) - QVERIFY(process.waitForFinished(5000)); -#else - QVERIFY(process.waitForFinished(30000)); -#endif + QVERIFY(process.waitForFinished()); QCOMPARE(process.exitStatus(), QProcess::NormalExit); #if defined (Q_OS_WINCE) @@ -925,12 +921,7 @@ void tst_QProcess::hardExit() proc.start("testProcessEcho/testProcessEcho"); #endif -#ifndef Q_OS_WINCE - QVERIFY(proc.waitForStarted(5000)); -#else - QVERIFY(proc.waitForStarted(10000)); -#endif - + QVERIFY2(proc.waitForStarted(), qPrintable(proc.errorString())); proc.kill(); QVERIFY(proc.waitForFinished(5000)); @@ -1050,24 +1041,33 @@ private: void tst_QProcess::softExitInSlots_data() { QTest::addColumn<QString>("appName"); + QTest::addColumn<int>("signalToConnect"); + QByteArray dataTagPrefix("gui app "); #ifndef QT_NO_WIDGETS - QTest::newRow("gui app") << "testGuiProcess/testGuiProcess"; + for (int i = 0; i < 5; ++i) { + QTest::newRow(dataTagPrefix + QByteArray::number(i)) + << "testGuiProcess/testGuiProcess" << i; + } #endif - QTest::newRow("console app") << "testProcessEcho2/testProcessEcho2"; + + dataTagPrefix = "console app "; + for (int i = 0; i < 5; ++i) { + QTest::newRow(dataTagPrefix + QByteArray::number(i)) + << "testProcessEcho2/testProcessEcho2" << i; + } } void tst_QProcess::softExitInSlots() { QFETCH(QString, appName); + QFETCH(int, signalToConnect); - for (int i = 0; i < 5; ++i) { - SoftExitProcess proc(i); - proc.writeAfterStart("OLEBOLE", 8); // include the \0 - proc.start(appName); - QTRY_VERIFY_WITH_TIMEOUT(proc.waitedForFinished, 10000); - QCOMPARE(proc.state(), QProcess::NotRunning); - } + SoftExitProcess proc(signalToConnect); + proc.writeAfterStart("OLEBOLE", 8); // include the \0 + proc.start(appName); + QTRY_VERIFY_WITH_TIMEOUT(proc.waitedForFinished, 10000); + QCOMPARE(proc.state(), QProcess::NotRunning); } #endif @@ -1414,24 +1414,17 @@ void tst_QProcess::spaceArgsTest() QString program = programs.at(i); process.start(program, args); -#if defined(Q_OS_WINCE) - const int timeOutMS = 10000; -#else - const int timeOutMS = 5000; -#endif QByteArray errorMessage; - bool started = process.waitForStarted(timeOutMS); + bool started = process.waitForStarted(); if (!started) errorMessage = startFailMessage(program, process); QVERIFY2(started, errorMessage.constData()); - QVERIFY(process.waitForFinished(timeOutMS)); + QVERIFY(process.waitForFinished()); QCOMPARE(process.exitStatus(), QProcess::NormalExit); QCOMPARE(process.exitCode(), 0); #if !defined(Q_OS_WINCE) QStringList actual = QString::fromLatin1(process.readAll()).split("|"); -#endif -#if !defined(Q_OS_WINCE) QVERIFY(!actual.isEmpty()); // not interested in the program name, it might be different. actual.removeFirst(); @@ -1456,8 +1449,6 @@ void tst_QProcess::spaceArgsTest() #if !defined(Q_OS_WINCE) actual = QString::fromLatin1(process.readAll()).split("|"); -#endif -#if !defined(Q_OS_WINCE) QVERIFY(!actual.isEmpty()); // not interested in the program name, it might be different. actual.removeFirst(); @@ -1479,13 +1470,8 @@ void tst_QProcess::nativeArguments() proc.start(QString::fromLatin1("testProcessSpacesArgs/nospace"), QStringList()); -#if !defined(Q_OS_WINCE) - QVERIFY(proc.waitForStarted(5000)); - QVERIFY(proc.waitForFinished(5000)); -#else - QVERIFY(proc.waitForStarted(10000)); - QVERIFY(proc.waitForFinished(10000)); -#endif + QVERIFY2(proc.waitForStarted(), qPrintable(proc.errorString())); + QVERIFY(proc.waitForFinished()); QCOMPARE(proc.exitStatus(), QProcess::NormalExit); QCOMPARE(proc.exitCode(), 0); @@ -2521,6 +2507,31 @@ void tst_QProcess::startStopStartStopBuffers() } } +void tst_QProcess::processEventsInAReadyReadSlot_data() +{ + QTest::addColumn<bool>("callWaitForReadyRead"); + + QTest::newRow("no waitForReadyRead") << false; + QTest::newRow("waitForReadyRead") << true; +} + +void tst_QProcess::processEventsInAReadyReadSlot() +{ + // Test whether processing events in a readyReadXXX slot crashes. (QTBUG-48697) + QFETCH(bool, callWaitForReadyRead); + QProcess process; + QObject::connect(&process, &QProcess::readyReadStandardOutput, + this, &tst_QProcess::processApplicationEvents); + process.start("testProcessEcho/testProcessEcho"); + QVERIFY(process.waitForStarted()); + const QByteArray data(156, 'x'); + process.write(data.constData(), data.size() + 1); + if (callWaitForReadyRead) + QVERIFY(process.waitForReadyRead()); + if (process.state() == QProcess::Running) + QVERIFY(process.waitForFinished()); +} + #endif //QT_NO_PROCESS QTEST_MAIN(tst_QProcess) diff --git a/tests/auto/corelib/io/qstandardpaths/BLACKLIST b/tests/auto/corelib/io/qstandardpaths/BLACKLIST new file mode 100644 index 0000000000..8496a620b3 --- /dev/null +++ b/tests/auto/corelib/io/qstandardpaths/BLACKLIST @@ -0,0 +1,2 @@ +[testRuntimeDirectory] +rhel-7.1 diff --git a/tests/auto/corelib/io/qtextstream/test/test.pro b/tests/auto/corelib/io/qtextstream/test/test.pro index 39d181344f..073aecdfba 100644 --- a/tests/auto/corelib/io/qtextstream/test/test.pro +++ b/tests/auto/corelib/io/qtextstream/test/test.pro @@ -21,3 +21,7 @@ TESTDATA += \ ../tst_qtextstream.cpp \ ../resources DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +builtin_testdata { + DEFINES += BUILTIN_TESTDATA +} diff --git a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp index 3ab53848d8..13be58a1f1 100644 --- a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp +++ b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp @@ -65,6 +65,7 @@ public: public slots: void initTestCase(); void cleanup(); + void cleanupTestCase(); private slots: void getSetCheck(); @@ -228,6 +229,8 @@ private slots: void alignAccountingStyle(); void setCodec(); + void textModeOnEmptyRead(); + private: void generateLineData(bool for_QString); void generateAllData(bool for_QString); @@ -239,6 +242,9 @@ private: QTemporaryDir tempDir; QString testFileName; +#ifdef BUILTIN_TESTDATA + QSharedPointer<QTemporaryDir> m_dataDir; +#endif const QString m_rfc3261FilePath; const QString m_shiftJisFilePath; }; @@ -265,9 +271,14 @@ void tst_QTextStream::initTestCase() testFileName = tempDir.path() + "/testfile"; +#ifdef BUILTIN_TESTDATA + m_dataDir = QEXTRACTTESTDATA("/"); + QVERIFY2(QDir::setCurrent(m_dataDir->path()), qPrintable("Could not chdir to " + m_dataDir->path())); +#else // chdir into the testdata dir and refer to our helper apps with relative paths QString testdata_dir = QFileInfo(QFINDTESTDATA("stdinProcess")).absolutePath(); QVERIFY2(QDir::setCurrent(testdata_dir), qPrintable("Could not chdir to " + testdata_dir)); +#endif } // Testing get/set functions @@ -390,6 +401,13 @@ void tst_QTextStream::cleanup() QCoreApplication::instance()->processEvents(); } +void tst_QTextStream::cleanupTestCase() +{ +#ifdef BUILTIN_TESTDATA + QDir::setCurrent(QCoreApplication::applicationDirPath()); +#endif +} + // ------------------------------------------------------------------------------ void tst_QTextStream::construction() { @@ -3045,6 +3063,19 @@ void tst_QTextStream::int_write_with_locale() QCOMPARE(result, output); } +void tst_QTextStream::textModeOnEmptyRead() +{ + const QString filename(tempDir.path() + QLatin1String("/textmodetest.txt")); + + QFile file(filename); + QVERIFY2(file.open(QIODevice::ReadWrite | QIODevice::Text), qPrintable(file.errorString())); + QTextStream stream(&file); + QVERIFY(file.isTextModeEnabled()); + QString emptyLine = stream.readLine(); // Text mode flag cleared here + QVERIFY(file.isTextModeEnabled()); +} + + // ------------------------------------------------------------------------------ QTEST_MAIN(tst_QTextStream) diff --git a/tests/auto/corelib/json/json.pro b/tests/auto/corelib/json/json.pro index 237e20685a..899060764f 100644 --- a/tests/auto/corelib/json/json.pro +++ b/tests/auto/corelib/json/json.pro @@ -4,7 +4,7 @@ CONFIG -= app_bundle CONFIG += testcase CONFIG += parallel_test -!android:TESTDATA += test.json test.bjson test3.json test2.json +!android:TESTDATA += bom.json test.json test.bjson test3.json test2.json else:RESOURCES += json.qrc SOURCES += tst_qtjson.cpp diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index c74a43b682..e35790351d 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -1475,7 +1475,7 @@ static QByteArray createTypeName(const char *begin, const char *va) } if (tn.endsWith('>')) tn += ' '; - tn += ">"; + tn += '>'; return tn; } #endif diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index f7c1f03c0f..f3334b1222 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -279,8 +279,10 @@ static void playWithObjects() void tst_QObject::initTestCase() { +#ifndef QT_NO_PROCESS const QString testDataDir = QFileInfo(QFINDTESTDATA("signalbug")).absolutePath(); QVERIFY2(QDir::setCurrent(testDataDir), qPrintable("Could not chdir to " + testDataDir)); +#endif } void tst_QObject::disconnect() @@ -1848,6 +1850,8 @@ void tst_QObject::moveToThread() thread.wait(); } + // WinRT does not allow connection to localhost +#ifndef Q_OS_WINRT { // make sure socket notifiers are moved with the object MoveToThreadThread thread; @@ -1883,6 +1887,7 @@ void tst_QObject::moveToThread() QMetaObject::invokeMethod(socket, "deleteLater", Qt::QueuedConnection); thread.wait(); } +#endif } diff --git a/tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro b/tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro index a36b15c906..69062a9741 100644 --- a/tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro +++ b/tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro @@ -1,3 +1,5 @@ TEMPLATE = subdirs -SUBDIRS = sharedmemoryhelper test +!winrt: SUBDIRS = sharedmemoryhelper + +SUBDIRS += test diff --git a/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp b/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp index 26bb70fc66..43e25743d7 100644 --- a/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp +++ b/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp @@ -138,7 +138,9 @@ tst_QSharedMemory::~tst_QSharedMemory() void tst_QSharedMemory::initTestCase() { +#ifndef QT_NO_PROCESS QVERIFY2(!m_helperBinary.isEmpty(), "Could not find helper binary"); +#endif } void tst_QSharedMemory::init() diff --git a/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp b/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp index f49da1f5a8..95e924bd77 100644 --- a/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp +++ b/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp @@ -131,6 +131,10 @@ signals: void tst_QSocketNotifier::unexpectedDisconnection() { +#ifdef Q_OS_WINRT + // WinRT does not allow a connection to the localhost + QSKIP("Local connection not allowed", SkipAll); +#else /* Given two sockets and two QSocketNotifiers registered on each their socket. If both sockets receive data, and the first slot @@ -196,6 +200,7 @@ void tst_QSocketNotifier::unexpectedDisconnection() writeEnd1->close(); writeEnd2->close(); server.close(); +#endif // !Q_OS_WINRT } class MixingWithTimersHelper : public QObject @@ -234,6 +239,9 @@ void MixingWithTimersHelper::socketFired() void tst_QSocketNotifier::mixingWithTimers() { +#ifdef Q_OS_WINRT + QSKIP("WinRT does not allow connection to localhost", SkipAll); +#else QTimer timer; timer.setInterval(0); timer.start(); @@ -258,6 +266,7 @@ void tst_QSocketNotifier::mixingWithTimers() QCOMPARE(helper.timerActivated, true); QTRY_COMPARE(helper.socketActivated, true); +#endif // !Q_OS_WINRT } #ifdef Q_OS_UNIX diff --git a/tests/auto/corelib/kernel/qtranslator/qtranslator.pro b/tests/auto/corelib/kernel/qtranslator/qtranslator.pro index e588f44370..c9b160a8d1 100644 --- a/tests/auto/corelib/kernel/qtranslator/qtranslator.pro +++ b/tests/auto/corelib/kernel/qtranslator/qtranslator.pro @@ -5,5 +5,5 @@ SOURCES = tst_qtranslator.cpp RESOURCES += qtranslator.qrc android:!android-no-sdk: RESOURCES += android_testdata.qrc -else: TESTDATA += hellotr_la.qm msgfmt_from_po.qm +else: TESTDATA += dependencies_la.qm hellotr_la.qm msgfmt_from_po.qm diff --git a/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp b/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp index 2707b6df41..c2290add5b 100644 --- a/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp +++ b/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp @@ -58,6 +58,7 @@ private slots: private: int languageChangeEventCounter; + QSharedPointer<QTemporaryDir> dataDir; }; tst_QTranslator::tst_QTranslator() @@ -90,8 +91,16 @@ void tst_QTranslator::initTestCase() // chdir into the directory containing our testdata, // to make the code simpler (load testdata via relative paths) +#ifdef Q_OS_WINRT + // ### TODO: Use this for all platforms in 5.7 + dataDir = QEXTRACTTESTDATA(QStringLiteral("/")); + QVERIFY2(!dataDir.isNull(), qPrintable("Could not extract test data")); + QVERIFY2(QDir::setCurrent(dataDir->path()), qPrintable("Could not chdir to " + dataDir->path())); +#else // !Q_OS_WINRT QString testdata_dir = QFileInfo(QFINDTESTDATA("hellotr_la.qm")).absolutePath(); QVERIFY2(QDir::setCurrent(testdata_dir), qPrintable("Could not chdir to " + testdata_dir)); +#endif // !Q_OS_WINRT + } bool tst_QTranslator::eventFilter(QObject *, QEvent *event) diff --git a/tests/auto/corelib/plugin/plugin.pro b/tests/auto/corelib/plugin/plugin.pro index 506f6abaeb..e132d9da1a 100644 --- a/tests/auto/corelib/plugin/plugin.pro +++ b/tests/auto/corelib/plugin/plugin.pro @@ -5,3 +5,9 @@ SUBDIRS=\ qplugin \ qpluginloader \ quuid + +contains(CONFIG, static) { + message(Disabling tests requiring shared build of Qt) + SUBDIRS -= qfactoryloader \ + qpluginloader +} diff --git a/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp b/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp index d3c85c54a7..ff41ccf26b 100644 --- a/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp +++ b/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp @@ -362,28 +362,46 @@ void tst_QAtomicIntegerXX::loadAcquireStoreRelease() void tst_QAtomicIntegerXX::refDeref() { QFETCH(LargeInt, value); - T nextValue = T(value + 1); - T prevValue = T(value - 1); + const bool needToPreventOverflow = TypeIsSigned && value == std::numeric_limits<T>::max(); + const bool needToPreventUnderflow = TypeIsSigned && value == std::numeric_limits<T>::min(); + T nextValue = T(value); + if (!needToPreventOverflow) + ++nextValue; + T prevValue = T(value); + if (!needToPreventUnderflow) + --prevValue; QAtomicInteger<T> atomic(value); + if (!needToPreventOverflow) { QCOMPARE(atomic.ref(), (nextValue != 0)); QCOMPARE(atomic.load(), nextValue); QCOMPARE(atomic.deref(), (value != 0)); + } QCOMPARE(atomic.load(), T(value)); + if (!needToPreventUnderflow) { QCOMPARE(atomic.deref(), (prevValue != 0)); QCOMPARE(atomic.load(), prevValue); QCOMPARE(atomic.ref(), (value != 0)); + } QCOMPARE(atomic.load(), T(value)); + if (!needToPreventOverflow) { QCOMPARE(++atomic, nextValue); QCOMPARE(--atomic, T(value)); + } + if (!needToPreventUnderflow) { QCOMPARE(--atomic, prevValue); QCOMPARE(++atomic, T(value)); + } + if (!needToPreventOverflow) { QCOMPARE(atomic++, T(value)); QCOMPARE(atomic--, nextValue); + } + if (!needToPreventUnderflow) { QCOMPARE(atomic--, T(value)); QCOMPARE(atomic++, prevValue); + } QCOMPARE(atomic.load(), T(value)); } @@ -486,53 +504,80 @@ void tst_QAtomicIntegerXX::fetchAndAdd() QFETCH(LargeInt, value); QAtomicInteger<T> atomic(value); - // note: this test has undefined behavior for signed max and min T parcel1 = 42; T parcel2 = T(0-parcel1); - T newValue1 = T(value) + parcel1; - T newValue2 = T(value) + parcel2; + const bool needToPreventOverflow = TypeIsSigned && value > std::numeric_limits<T>::max() + parcel2; + const bool needToPreventUnderflow = TypeIsSigned && value < std::numeric_limits<T>::min() + parcel1; + + T newValue1 = T(value); + if (!needToPreventOverflow) + newValue1 += parcel1; + T newValue2 = T(value); + if (!needToPreventUnderflow) + newValue2 += parcel2; + + if (!needToPreventOverflow) { QCOMPARE(atomic.fetchAndAddRelaxed(parcel1), T(value)); QCOMPARE(atomic.load(), newValue1); QCOMPARE(atomic.fetchAndAddRelaxed(parcel2), newValue1); + } QCOMPARE(atomic.load(), T(value)); + if (!needToPreventUnderflow) { QCOMPARE(atomic.fetchAndAddRelaxed(parcel2), T(value)); QCOMPARE(atomic.load(), newValue2); QCOMPARE(atomic.fetchAndAddRelaxed(parcel1), newValue2); + } QCOMPARE(atomic.load(), T(value)); + if (!needToPreventOverflow) { QCOMPARE(atomic.fetchAndAddAcquire(parcel1), T(value)); QCOMPARE(atomic.load(), newValue1); QCOMPARE(atomic.fetchAndAddAcquire(parcel2), newValue1); + } QCOMPARE(atomic.load(), T(value)); + if (!needToPreventUnderflow) { QCOMPARE(atomic.fetchAndAddAcquire(parcel2), T(value)); QCOMPARE(atomic.load(), newValue2); QCOMPARE(atomic.fetchAndAddAcquire(parcel1), newValue2); + } QCOMPARE(atomic.load(), T(value)); + if (!needToPreventOverflow) { QCOMPARE(atomic.fetchAndAddRelease(parcel1), T(value)); QCOMPARE(atomic.loadAcquire(), newValue1); QCOMPARE(atomic.fetchAndAddRelease(parcel2), newValue1); + } QCOMPARE(atomic.loadAcquire(), T(value)); + if (!needToPreventUnderflow) { QCOMPARE(atomic.fetchAndAddRelease(parcel2), T(value)); QCOMPARE(atomic.loadAcquire(), newValue2); QCOMPARE(atomic.fetchAndAddRelease(parcel1), newValue2); + } QCOMPARE(atomic.loadAcquire(), T(value)); + if (!needToPreventOverflow) { QCOMPARE(atomic.fetchAndAddOrdered(parcel1), T(value)); QCOMPARE(atomic.loadAcquire(), newValue1); QCOMPARE(atomic.fetchAndAddOrdered(parcel2), newValue1); + } QCOMPARE(atomic.loadAcquire(), T(value)); + if (!needToPreventUnderflow) { QCOMPARE(atomic.fetchAndAddOrdered(parcel2), T(value)); QCOMPARE(atomic.loadAcquire(), newValue2); QCOMPARE(atomic.fetchAndAddOrdered(parcel1), newValue2); + } QCOMPARE(atomic.loadAcquire(), T(value)); // operator+= + if (!needToPreventOverflow) { QCOMPARE(atomic += parcel1, newValue1); QCOMPARE(atomic += parcel2, T(value)); + } + if (!needToPreventUnderflow) { QCOMPARE(atomic += parcel2, newValue2); QCOMPARE(atomic += parcel1, T(value)); + } } void tst_QAtomicIntegerXX::fetchAndSub() @@ -540,53 +585,80 @@ void tst_QAtomicIntegerXX::fetchAndSub() QFETCH(LargeInt, value); QAtomicInteger<T> atomic(value); - // note: this test has undefined behavior for signed max and min T parcel1 = 42; T parcel2 = T(0-parcel1); - T newValue1 = T(value) - parcel1; - T newValue2 = T(value) - parcel2; + const bool needToPreventOverflow = TypeIsSigned && value > std::numeric_limits<T>::max() - parcel1; + const bool needToPreventUnderflow = TypeIsSigned && value < std::numeric_limits<T>::min() - parcel2; + + T newValue1 = T(value); + if (!needToPreventUnderflow) + newValue1 -= parcel1; + T newValue2 = T(value); + if (!needToPreventOverflow) + newValue2 -= parcel2; + + if (!needToPreventUnderflow) { QCOMPARE(atomic.fetchAndSubRelaxed(parcel1), T(value)); QCOMPARE(atomic.load(), newValue1); QCOMPARE(atomic.fetchAndSubRelaxed(parcel2), newValue1); + } QCOMPARE(atomic.load(), T(value)); + if (!needToPreventOverflow) { QCOMPARE(atomic.fetchAndSubRelaxed(parcel2), T(value)); QCOMPARE(atomic.load(), newValue2); QCOMPARE(atomic.fetchAndSubRelaxed(parcel1), newValue2); + } QCOMPARE(atomic.load(), T(value)); + if (!needToPreventUnderflow) { QCOMPARE(atomic.fetchAndSubAcquire(parcel1), T(value)); QCOMPARE(atomic.load(), newValue1); QCOMPARE(atomic.fetchAndSubAcquire(parcel2), newValue1); + } QCOMPARE(atomic.load(), T(value)); + if (!needToPreventOverflow) { QCOMPARE(atomic.fetchAndSubAcquire(parcel2), T(value)); QCOMPARE(atomic.load(), newValue2); QCOMPARE(atomic.fetchAndSubAcquire(parcel1), newValue2); + } QCOMPARE(atomic.load(), T(value)); + if (!needToPreventUnderflow) { QCOMPARE(atomic.fetchAndSubRelease(parcel1), T(value)); QCOMPARE(atomic.loadAcquire(), newValue1); QCOMPARE(atomic.fetchAndSubRelease(parcel2), newValue1); + } QCOMPARE(atomic.loadAcquire(), T(value)); + if (!needToPreventOverflow) { QCOMPARE(atomic.fetchAndSubRelease(parcel2), T(value)); QCOMPARE(atomic.loadAcquire(), newValue2); QCOMPARE(atomic.fetchAndSubRelease(parcel1), newValue2); + } QCOMPARE(atomic.loadAcquire(), T(value)); + if (!needToPreventUnderflow) { QCOMPARE(atomic.fetchAndSubOrdered(parcel1), T(value)); QCOMPARE(atomic.loadAcquire(), newValue1); QCOMPARE(atomic.fetchAndSubOrdered(parcel2), newValue1); + } QCOMPARE(atomic.loadAcquire(), T(value)); + if (!needToPreventOverflow) { QCOMPARE(atomic.fetchAndSubOrdered(parcel2), T(value)); QCOMPARE(atomic.loadAcquire(), newValue2); QCOMPARE(atomic.fetchAndSubOrdered(parcel1), newValue2); + } QCOMPARE(atomic.loadAcquire(), T(value)); // operator-= + if (!needToPreventUnderflow) { QCOMPARE(atomic -= parcel1, newValue1); QCOMPARE(atomic -= parcel2, T(value)); + } + if (!needToPreventOverflow) { QCOMPARE(atomic -= parcel2, newValue2); QCOMPARE(atomic -= parcel1, T(value)); + } } void tst_QAtomicIntegerXX::addSub() diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index f6f1c05814..35c278da0e 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -718,8 +718,6 @@ void tst_QDateTime::fromMSecsSinceEpoch() QCOMPARE(dtLocal.toLocalTime(), cet); QCOMPARE(dtUtc.toLocalTime(), cet); QCOMPARE(dtOffset.toLocalTime(), cet); - } else { - QSKIP("You must test using Central European (CET/CEST) time zone, e.g. TZ=Europe/Oslo"); } // LocalTime will overflow for max diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index 5f046575c4..dc5140a010 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -212,6 +212,7 @@ tst_QLocale::tst_QLocale() void tst_QLocale::initTestCase() { +#ifndef QT_NO_PROCESS const QString syslocaleapp_dir = QFINDTESTDATA("syslocaleapp"); QVERIFY2(!syslocaleapp_dir.isEmpty(), qPrintable(QStringLiteral("Cannot find 'syslocaleapp' starting from ") @@ -224,6 +225,7 @@ void tst_QLocale::initTestCase() QVERIFY2(fi.exists() && fi.isExecutable(), qPrintable(QDir::toNativeSeparators(m_sysapp) + QStringLiteral(" does not exist or is not executable."))); +#endif // QT_NO_PROCESS #ifdef Q_OS_BLACKBERRY if ((m_languageFd = open(ppsLanguageLocalePath, O_RDONLY)) == -1) diff --git a/tests/auto/corelib/tools/qrect/tst_qrect.cpp b/tests/auto/corelib/tools/qrect/tst_qrect.cpp index 585cf5d4d0..1377e801a7 100644 --- a/tests/auto/corelib/tools/qrect/tst_qrect.cpp +++ b/tests/auto/corelib/tools/qrect/tst_qrect.cpp @@ -2349,7 +2349,7 @@ void tst_QRect::center_data() QTest::newRow( "SmallestQRect" ) << getQRectCase( SmallestQRect ) << QPoint(1,1); QTest::newRow( "MiddleQRect" ) << getQRectCase( MiddleQRect ) << QPoint(0,0); QTest::newRow( "LargestQRect" ) << getQRectCase( LargestQRect ) << QPoint(INT_MAX/2,INT_MAX/2); - QTest::newRow( "SmallestCoordQRect" ) << getQRectCase( SmallestCoordQRect ) << QPoint(0,0); + QTest::newRow( "SmallestCoordQRect" ) << getQRectCase( SmallestCoordQRect ) << QPoint(INT_MIN, INT_MIN); QTest::newRow( "LargestCoordQRect" ) << getQRectCase( LargestCoordQRect ) << QPoint(0,0); QTest::newRow( "RandomQRect" ) << getQRectCase( RandomQRect ) << QPoint(105,207); QTest::newRow( "NegativeSizeQRect" ) << getQRectCase( NegativeSizeQRect ) << QPoint(-4,-4); @@ -3171,8 +3171,7 @@ void tst_QRect::newMoveTopLeft_data() } { - QTest::newRow("LargestCoordQRect_NullQPoint") << getQRectCase(LargestCoordQRect) << getQPointCase(NullQPoint) - << QRect(QPoint(0,0), QPoint(INT_MAX+(0-INT_MIN),INT_MAX+(0-INT_MIN))); + // QTest::newRow("LargestCoordQRect_NullQPoint") -- Not tested as it would cause an overflow QTest::newRow("LargestCoordQRect_SmallestCoordQPoint") << getQRectCase(LargestCoordQRect) << getQPointCase(SmallestCoordQPoint) << QRect(QPoint(INT_MIN,INT_MIN), QPoint(INT_MAX,INT_MAX)); // QTest::newRow("LargestCoordQRect_MiddleNegCoordQPoint") -- Not tested as it would cause an overflow diff --git a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp index b511abf670..32bb2aa394 100644 --- a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp +++ b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp @@ -898,7 +898,7 @@ void tst_QTimeZone::macTest() void tst_QTimeZone::winTest() { -#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_WIN) && !defined(Q_OS_WINRT) +#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_WIN) // Known datetimes qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch(); qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch(); diff --git a/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp index 341b169113..1da29ac3bd 100644 --- a/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp @@ -905,7 +905,8 @@ void tst_QXmlStream::testFalsePrematureError() const // Regression test for crash due to using empty QStack. void tst_QXmlStream::writerHangs() const { - QFile file("test.xml"); + QTemporaryDir dir(QDir::tempPath() + QLatin1String("/tst_qxmlstream.XXXXXX")); + QFile file(dir.path() + "/test.xml"); QVERIFY(file.open(QIODevice::WriteOnly)); diff --git a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp index 1dd4d69ea8..b3fdd00eb6 100644 --- a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp +++ b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp @@ -117,7 +117,7 @@ void tst_QImageWriter::initTestCase() prefix = QFINDTESTDATA("images/"); if (prefix.isEmpty()) QFAIL("Can't find images directory!"); - writePrefix = m_temporaryDir.path(); + writePrefix = m_temporaryDir.path() + QLatin1Char('/'); } // Testing get/set functions diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp index 67d7e57fd4..4ffe357d09 100644 --- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp @@ -105,6 +105,7 @@ private slots: void drawBitmap(); void isNull(); void task_246446(); + void task_51271(); void convertFromImageNoDetach(); void convertFromImageDetach(); @@ -1441,6 +1442,14 @@ void tst_QPixmap::task_246446() QVERIFY(pm.mask().isNull()); } +void tst_QPixmap::task_51271() +{ + QPixmap pm; + QBitmap bm; + QVERIFY(!pm.isQBitmap()); // Should not crash ! + QVERIFY(bm.isQBitmap()); +} + void tst_QPixmap::preserveDepth() { QPixmap target(64, 64); diff --git a/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp b/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp index d8709baa18..73a2f83bac 100644 --- a/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp +++ b/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp @@ -346,11 +346,11 @@ struct TypeAlignment void tst_QGuiMetaType::flags_data() { QTest::addColumn<int>("type"); - QTest::addColumn<bool>("isMovable"); + QTest::addColumn<bool>("isRelocatable"); QTest::addColumn<bool>("isComplex"); #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \ - QTest::newRow(#RealType) << MetaTypeId << bool(!QTypeInfo<RealType>::isStatic) << bool(QTypeInfo<RealType>::isComplex); + QTest::newRow(#RealType) << MetaTypeId << bool(QTypeInfoQuery<RealType>::isRelocatable) << bool(QTypeInfoQuery<RealType>::isComplex); QT_FOR_EACH_STATIC_GUI_CLASS(ADD_METATYPE_TEST_ROW) #undef ADD_METATYPE_TEST_ROW } @@ -358,12 +358,12 @@ QT_FOR_EACH_STATIC_GUI_CLASS(ADD_METATYPE_TEST_ROW) void tst_QGuiMetaType::flags() { QFETCH(int, type); - QFETCH(bool, isMovable); + QFETCH(bool, isRelocatable); QFETCH(bool, isComplex); QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::NeedsConstruction), isComplex); QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::NeedsDestruction), isComplex); - QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::MovableType), isMovable); + QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::MovableType), isRelocatable); } diff --git a/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp b/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp index bd68400047..db0bfaf622 100644 --- a/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp +++ b/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp @@ -137,7 +137,7 @@ void tst_QKeyEvent::modifiers_data() for (quint64 bitmask = 1; bitmask < (1 << kNumModifiers) ; ++bitmask) { QVector<int> modifierCombination; for (quint64 modifier = 0; modifier < kNumModifiers; ++modifier) { - if (bitmask & (1 << modifier)) + if (bitmask & (quint64(1) << modifier)) modifierCombination.append(modifier); } modifierCombinations.append(modifierCombination); diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST index ee9709e68b..cfbd47745f 100644 --- a/tests/auto/gui/kernel/qwindow/BLACKLIST +++ b/tests/auto/gui/kernel/qwindow/BLACKLIST @@ -1,6 +1,10 @@ +[testInputEvents] +rhel-7.1 [positioning:default] ubuntu-14.04 [modalWindowPosition] ubuntu-14.04 [modalWithChildWindow] ubuntu-14.04 +[modalWindowEnterEventOnHide_QTBUG35109] +ubuntu-14.04 diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index a89f0da4d2..0cce5a072c 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -92,6 +92,9 @@ private slots: void modalWithChildWindow(); void modalWindowModallity(); void modalWindowPosition(); +#ifndef QT_NO_CURSOR + void modalWindowEnterEventOnHide_QTBUG35109(); +#endif void windowsTransientChildren(); void requestUpdate(); void initTestCase(); @@ -706,10 +709,24 @@ public: } } } + bool event(QEvent *e) { + switch (e->type()) { + case QEvent::Enter: + ++enterEventCount; + break; + case QEvent::Leave: + ++leaveEventCount; + break; + default: + break; + } + return QWindow::event(e); + } void resetCounters() { mousePressedCount = mouseReleasedCount = mouseMovedCount = mouseDoubleClickedCount = 0; mouseSequenceSignature = QString(); touchPressedCount = touchReleasedCount = touchMovedCount = 0; + enterEventCount = leaveEventCount = 0; } InputTestWindow() { @@ -727,6 +744,7 @@ public: QPointF mousePressScreenPos, mouseMoveScreenPos, mousePressLocalPos; int touchPressedCount, touchReleasedCount, touchMovedCount; QEvent::Type touchEventType; + int enterEventCount, leaveEventCount; bool ignoreMouse, ignoreTouch; @@ -1732,6 +1750,181 @@ void tst_QWindow::modalWindowPosition() QCOMPARE(window.geometry(), origGeo); } +#ifndef QT_NO_CURSOR +void tst_QWindow::modalWindowEnterEventOnHide_QTBUG35109() +{ + if (QGuiApplication::platformName() == QLatin1String("cocoa")) + QSKIP("This test fails on OS X on CI"); + + const QPoint center = QGuiApplication::primaryScreen()->availableGeometry().center(); + + const int childOffset = 16; + const QPoint rootPos = center - QPoint(m_testWindowSize.width(), + m_testWindowSize.height())/2; + const QPoint modalPos = rootPos + QPoint(childOffset * 5, + childOffset * 5); + const QPoint cursorPos = rootPos - QPoint(80, 80); + + // Test whether tlw can receive the enter event + { + QCursor::setPos(cursorPos); + QCoreApplication::processEvents(); + + InputTestWindow root; + root.setTitle(__FUNCTION__); + root.setGeometry(QRect(rootPos, m_testWindowSize)); + root.show(); + QVERIFY(QTest::qWaitForWindowExposed(&root)); + root.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&root)); + + // Move the mouse over the root window, but not over the modal window. + QCursor::setPos(rootPos + QPoint(childOffset * 5 / 2, + childOffset * 5 / 2)); + + // Wait for the enter event. It must be delivered here, otherwise second + // compare can PASS because of this event even after "resetCounters()". + QTRY_COMPARE(root.enterEventCount, 1); + QTRY_COMPARE(root.leaveEventCount, 0); + + QWindow modal; + modal.setTitle(QLatin1String("Modal - ") + __FUNCTION__); + modal.setTransientParent(&root); + modal.resize(m_testWindowSize/2); + modal.setFramePosition(modalPos); + modal.setModality(Qt::ApplicationModal); + modal.show(); + QVERIFY(QTest::qWaitForWindowExposed(&modal)); + modal.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&modal)); + + QCoreApplication::processEvents(); + QTRY_COMPARE(root.leaveEventCount, 1); + + root.resetCounters(); + modal.close(); + + // Check for the enter event + QTRY_COMPARE(root.enterEventCount, 1); + } + + // Test whether child window can receive the enter event + { + QCursor::setPos(cursorPos); + QCoreApplication::processEvents(); + + QWindow root; + root.setTitle(__FUNCTION__); + root.setGeometry(QRect(rootPos, m_testWindowSize)); + + QWindow childLvl1; + childLvl1.setParent(&root); + childLvl1.setGeometry(childOffset, + childOffset, + m_testWindowSize.width() - childOffset, + m_testWindowSize.height() - childOffset); + + InputTestWindow childLvl2; + childLvl2.setParent(&childLvl1); + childLvl2.setGeometry(childOffset, + childOffset, + childLvl1.width() - childOffset, + childLvl1.height() - childOffset); + + root.show(); + childLvl1.show(); + childLvl2.show(); + + QVERIFY(QTest::qWaitForWindowExposed(&root)); + root.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&root)); + QVERIFY(childLvl1.isVisible()); + QVERIFY(childLvl2.isVisible()); + + // Move the mouse over the child window, but not over the modal window. + // Be sure that the value is almost left-top of second child window for + // checking proper position mapping. + QCursor::setPos(rootPos + QPoint(childOffset * 5 / 2, + childOffset * 5 / 2)); + + // Wait for the enter event. It must be delivered here, otherwise second + // compare can PASS because of this event even after "resetCounters()". + QTRY_COMPARE(childLvl2.enterEventCount, 1); + QTRY_COMPARE(childLvl2.leaveEventCount, 0); + + QWindow modal; + modal.setTitle(QLatin1String("Modal - ") + __FUNCTION__); + modal.setTransientParent(&root); + modal.resize(m_testWindowSize/2); + modal.setFramePosition(modalPos); + modal.setModality(Qt::ApplicationModal); + modal.show(); + QVERIFY(QTest::qWaitForWindowExposed(&modal)); + modal.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&modal)); + + QCoreApplication::processEvents(); + QTRY_COMPARE(childLvl2.leaveEventCount, 1); + + childLvl2.resetCounters(); + modal.close(); + + // Check for the enter event + QTRY_COMPARE(childLvl2.enterEventCount, 1); + } + + // Test whether tlw can receive the enter event if mouse is over the invisible child windnow + { + QCursor::setPos(cursorPos); + QCoreApplication::processEvents(); + + InputTestWindow root; + root.setTitle(__FUNCTION__); + root.setGeometry(QRect(rootPos, m_testWindowSize)); + + QWindow child; + child.setParent(&root); + child.setGeometry(QRect(QPoint(), m_testWindowSize)); + + root.show(); + + QVERIFY(QTest::qWaitForWindowExposed(&root)); + root.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&root)); + QVERIFY(!child.isVisible()); + + // Move the mouse over the child window, but not over the modal window. + QCursor::setPos(rootPos + QPoint(childOffset * 5 / 2, + childOffset * 5 / 2)); + + // Wait for the enter event. It must be delivered here, otherwise second + // compare can PASS because of this event even after "resetCounters()". + QTRY_COMPARE(root.enterEventCount, 1); + QTRY_COMPARE(root.leaveEventCount, 0); + + QWindow modal; + modal.setTitle(QLatin1String("Modal - ") + __FUNCTION__); + modal.setTransientParent(&root); + modal.resize(m_testWindowSize/2); + modal.setFramePosition(modalPos); + modal.setModality(Qt::ApplicationModal); + modal.show(); + QVERIFY(QTest::qWaitForWindowExposed(&modal)); + modal.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&modal)); + + QCoreApplication::processEvents(); + QTRY_COMPARE(root.leaveEventCount, 1); + + root.resetCounters(); + modal.close(); + + // Check for the enter event + QTRY_COMPARE(root.enterEventCount, 1); + } +} +#endif + class ColoredWindow : public QRasterWindow { public: explicit ColoredWindow(const QColor &color, QWindow *parent = 0) : QRasterWindow(parent), m_color(color) {} diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 1ed78fa0ef..8c72532122 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -305,6 +305,8 @@ private slots: void drawPolyline_data(); void drawPolyline(); + void QTBUG50153_drawImage_assert(); + private: void fillData(); void setPenColor(QPainter& p); @@ -5052,6 +5054,30 @@ void tst_QPainter::drawPolyline() QCOMPARE(images[0], images[1]); } +void tst_QPainter::QTBUG50153_drawImage_assert() +{ + QImage::Format formats[] = { + QImage::Format_RGB32, // fetchTransformedBilinearARGB32PM + QImage::Format_ARGB32 // fetchTransformedBilinear + }; + + for (unsigned i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) { + QImage image(3027, 2999, formats[i]); + + QImage backingStore(image.size(), QImage::Format_ARGB32); + QPainter backingStorePainter(&backingStore); + + QTransform transform; + transform.scale( 0.999987, 0.999987 ); + + backingStorePainter.setTransform(transform); + backingStorePainter.setRenderHint(QPainter::SmoothPixmapTransform, true); + backingStorePainter.drawImage(0, 0, image); + + // No crash, all fine + } +} + QTEST_MAIN(tst_QPainter) #include "tst_qpainter.moc" diff --git a/tests/auto/gui/text/qstatictext/qstatictext.pro b/tests/auto/gui/text/qstatictext/qstatictext.pro index 435b132ffd..acffbe700b 100644 --- a/tests/auto/gui/text/qstatictext/qstatictext.pro +++ b/tests/auto/gui/text/qstatictext/qstatictext.pro @@ -3,5 +3,7 @@ CONFIG += parallel_test linux: CONFIG += insignificant_test TARGET = tst_qstatictext QT += testlib -QT += core-private gui-private + SOURCES += tst_qstatictext.cpp + +contains(QT_CONFIG, private_tests): QT += core-private gui-private diff --git a/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp b/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp index b8134291af..121584b87f 100644 --- a/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp +++ b/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp @@ -39,7 +39,9 @@ #include <qstatictext.h> #include <qpaintengine.h> +#ifdef QT_BUILD_INTERNAL #include <private/qstatictext_p.h> +#endif // #define DEBUG_SAVE_IMAGE @@ -90,8 +92,10 @@ private slots: void unprintableCharacter_qtbug12614(); +#ifdef QT_BUILD_INTERNAL void underlinedColor_qtbug20159(); void textDocumentColor(); +#endif private: bool supportsTransformations() const; @@ -610,6 +614,29 @@ void tst_QStaticText::plainTextVsRichText() QCOMPARE(imagePlainText, imageRichText); } +static bool checkPixels(const QImage &image, + Qt::GlobalColor expectedColor1, Qt::GlobalColor expectedColor2, + QByteArray *errorMessage) +{ + const QRgb expectedRgb1 = QColor(expectedColor1).rgba(); + const QRgb expectedRgb2 = QColor(expectedColor2).rgba(); + + for (int x = 0, w = image.width(); x < w; ++x) { + for (int y = 0, h = image.height(); y < h; ++y) { + const QRgb pixel = image.pixel(x, y); + if (pixel != expectedRgb1 && pixel != expectedRgb2) { + QString message; + QDebug(&message) << "Color mismatch in image" << image + << "at" << x << ',' << y << ':' << showbase << hex << pixel + << "(expected: " << expectedRgb1 << ',' << expectedRgb2 << ')'; + *errorMessage = message.toLocal8Bit(); + return false; + } + } + } + return true; +} + void tst_QStaticText::setPenPlainText_data() { QTest::addColumn<QImage::Format>("format"); @@ -640,13 +667,9 @@ void tst_QStaticText::setPenPlainText() p.drawStaticText(0, 0, staticText); } - for (int x=0; x<image.width(); ++x) { - for (int y=0; y<image.height(); ++y) { - QRgb pixel = image.pixel(x, y); - QVERIFY(pixel == QColor(Qt::white).rgba() - || pixel == QColor(Qt::yellow).rgba()); - } - } + QByteArray errorMessage; + QVERIFY2(checkPixels(image, Qt::yellow, Qt::white, &errorMessage), + errorMessage.constData()); } void tst_QStaticText::setPenRichText() @@ -668,14 +691,9 @@ void tst_QStaticText::setPenRichText() p.drawStaticText(0, 0, staticText); } - QImage img = image.toImage(); - for (int x=0; x<img.width(); ++x) { - for (int y=0; y<img.height(); ++y) { - QRgb pixel = img.pixel(x, y); - QVERIFY(pixel == QColor(Qt::white).rgba() - || pixel == QColor(Qt::green).rgba()); - } - } + QByteArray errorMessage; + QVERIFY2(checkPixels(image.toImage(), Qt::green, Qt::white, &errorMessage), + errorMessage.constData()); } void tst_QStaticText::richTextOverridesPen() @@ -697,14 +715,9 @@ void tst_QStaticText::richTextOverridesPen() p.drawStaticText(0, 0, staticText); } - QImage img = image.toImage(); - for (int x=0; x<img.width(); ++x) { - for (int y=0; y<img.height(); ++y) { - QRgb pixel = img.pixel(x, y); - QVERIFY(pixel == QColor(Qt::white).rgba() - || pixel == QColor(Qt::red).rgba()); - } - } + QByteArray errorMessage; + QVERIFY2(checkPixels(image.toImage(), Qt::red, Qt::white, &errorMessage), + errorMessage.constData()); } void tst_QStaticText::drawStruckOutText() @@ -820,6 +833,7 @@ void tst_QStaticText::unprintableCharacter_qtbug12614() QVERIFY(staticText.size().isValid()); // Force layout. Should not crash. } +#ifdef QT_BUILD_INTERNAL void tst_QStaticText::underlinedColor_qtbug20159() { QString multiScriptText; @@ -856,6 +870,7 @@ void tst_QStaticText::textDocumentColor() QCOMPARE(d->items[1].color, QColor(Qt::red)); } +#endif QTEST_MAIN(tst_QStaticText) #include "tst_qstatictext.moc" diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp index 7378ca85ee..02e2bf27e2 100644 --- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp @@ -95,6 +95,8 @@ private slots: void task240325(); + void preFont(); + void stylesheetFont_data(); void stylesheetFont(); @@ -675,6 +677,30 @@ void tst_QTextDocument::stylesheetFont() QCOMPARE(actualFont.pixelSize(), font.pixelSize()); } +void tst_QTextDocument::preFont() +{ + const QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont); + const QString html = QString::fromLatin1( "<html>" + "<body>" + "<pre>" + "Foobar" + "</pre>" + "</body>" + "</html>"); + + doc->setHtml(html); + QCOMPARE(doc->blockCount(), 1); + + // First and only block + QTextBlock block = doc->firstBlock(); + + QString text = block.text(); + QCOMPARE(text, QString::fromLatin1("Foobar")); + + QFont actualFont = block.charFormat().font(); + QCOMPARE(actualFont.family(), font.family()); +} + void tst_QTextDocument::noundo_moreIsModified() { doc->setUndoRedoEnabled(false); diff --git a/tests/auto/gui/text/text.pro b/tests/auto/gui/text/text.pro index 6c0def4d63..dc67794a98 100644 --- a/tests/auto/gui/text/text.pro +++ b/tests/auto/gui/text/text.pro @@ -30,6 +30,5 @@ win32:SUBDIRS -= qtextpiecetable !contains(QT_CONFIG, private_tests): SUBDIRS -= \ qfontcache \ qcssparser \ - qstatictext \ qtextlayout \ qtextpiecetable \ diff --git a/tests/auto/network/access/qhttpnetworkreply/tst_qhttpnetworkreply.cpp b/tests/auto/network/access/qhttpnetworkreply/tst_qhttpnetworkreply.cpp index 16faee9705..231c2de4cb 100644 --- a/tests/auto/network/access/qhttpnetworkreply/tst_qhttpnetworkreply.cpp +++ b/tests/auto/network/access/qhttpnetworkreply/tst_qhttpnetworkreply.cpp @@ -33,6 +33,9 @@ #include <QtTest/QtTest> +#include <QtCore/QBuffer> +#include <QtCore/QByteArray> + #include "private/qhttpnetworkconnection_p.h" class tst_QHttpNetworkReply: public QObject @@ -46,6 +49,9 @@ private Q_SLOTS: void parseHeader_data(); void parseHeader(); + + void parseEndOfHeader_data(); + void parseEndOfHeader(); }; @@ -122,5 +128,66 @@ void tst_QHttpNetworkReply::parseHeader() } } +class TestHeaderSocket : public QAbstractSocket +{ +public: + explicit TestHeaderSocket(const QByteArray &input) : QAbstractSocket(QAbstractSocket::TcpSocket, Q_NULLPTR) + { + inputBuffer.setData(input); + inputBuffer.open(QIODevice::ReadOnly | QIODevice::Unbuffered); + open(QIODevice::ReadOnly | QIODevice::Unbuffered); + } + + qint64 readData(char *data, qint64 maxlen) { return inputBuffer.read(data, maxlen); } + + QBuffer inputBuffer; +}; + +class TestHeaderReply : public QHttpNetworkReply +{ +public: + QHttpNetworkReplyPrivate *replyPrivate() { return static_cast<QHttpNetworkReplyPrivate *>(d_ptr.data()); } +}; + +void tst_QHttpNetworkReply::parseEndOfHeader_data() +{ + QTest::addColumn<QByteArray>("headers"); + QTest::addColumn<qint64>("lengths"); + + QTest::newRow("CRLFCRLF") << QByteArray("Content-Type: text/html; charset=utf-8\r\n" + "Content-Length:\r\n 1024\r\n" + "Content-Encoding: gzip\r\n\r\nHTTPBODY") + << qint64(90); + + QTest::newRow("CRLFLF") << QByteArray("Content-Type: text/html; charset=utf-8\r\n" + "Content-Length:\r\n 1024\r\n" + "Content-Encoding: gzip\r\n\nHTTPBODY") + << qint64(89); + + QTest::newRow("LFCRLF") << QByteArray("Content-Type: text/html; charset=utf-8\r\n" + "Content-Length:\r\n 1024\r\n" + "Content-Encoding: gzip\n\r\nHTTPBODY") + << qint64(89); + + QTest::newRow("LFLF") << QByteArray("Content-Type: text/html; charset=utf-8\r\n" + "Content-Length:\r\n 1024\r\n" + "Content-Encoding: gzip\n\nHTTPBODY") + << qint64(88); +} + +void tst_QHttpNetworkReply::parseEndOfHeader() +{ + QFETCH(QByteArray, headers); + QFETCH(qint64, lengths); + + TestHeaderSocket socket(headers); + + TestHeaderReply reply; + + QHttpNetworkReplyPrivate *replyPrivate = reply.replyPrivate(); + qint64 headerBytes = replyPrivate->readHeader(&socket); + QCOMPARE(headerBytes, lengths); +} + QTEST_MAIN(tst_QHttpNetworkReply) #include "tst_qhttpnetworkreply.moc" diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index 3ec580ddde..0605677e29 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -7,3 +7,7 @@ ubuntu-14.04 * [backgroundRequestInterruption:ftp, bg, nobg] * +[authenticationCacheAfterCancel:http+socksauth] +rhel-7.1 +[authenticationCacheAfterCancel:https+socksauth] +rhel-7.1 diff --git a/tests/auto/network/socket/qlocalsocket/BLACKLIST b/tests/auto/network/socket/qlocalsocket/BLACKLIST deleted file mode 100644 index 11ddef30a5..0000000000 --- a/tests/auto/network/socket/qlocalsocket/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[processConnection:1 client] -windows diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp index d7480a4109..d12a6b53c3 100644 --- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp @@ -498,7 +498,11 @@ void tst_QLocalSocket::connectWithOldOpen() void tst_QLocalSocket::sendData_data() { - listenAndConnect_data(); + QTest::addColumn<QString>("name"); + QTest::addColumn<bool>("canListen"); + + QTest::newRow("null") << QString() << false; + QTest::newRow("tst_localsocket") << "tst_localsocket" << true; } void tst_QLocalSocket::sendData() @@ -521,6 +525,7 @@ void tst_QLocalSocket::sendData() // test creating a connection socket.connectToServer(name); bool timedOut = true; + int expectedReadyReadSignals = 0; QCOMPARE(server.waitForNewConnection(3000, &timedOut), canListen); @@ -544,15 +549,17 @@ void tst_QLocalSocket::sendData() out << testLine << endl; bool wrote = serverSocket->waitForBytesWritten(3000); - if (!socket.canReadLine()) + if (!socket.canReadLine()) { + expectedReadyReadSignals = 1; QVERIFY(socket.waitForReadyRead()); + } QVERIFY(socket.bytesAvailable() >= 0); QCOMPARE(socket.bytesToWrite(), (qint64)0); QCOMPARE(socket.flush(), false); QCOMPARE(socket.isValid(), canListen); QCOMPARE(socket.readBufferSize(), (qint64)0); - QCOMPARE(spyReadyRead.count(), 1); + QCOMPARE(spyReadyRead.count(), expectedReadyReadSignals); QVERIFY(testLine.startsWith(in.readLine())); @@ -567,7 +574,7 @@ void tst_QLocalSocket::sendData() QCOMPARE(spyDisconnected.count(), canListen ? 1 : 0); QCOMPARE(spyError.count(), canListen ? 0 : 1); QCOMPARE(spyStateChanged.count(), canListen ? 4 : 2); - QCOMPARE(spyReadyRead.count(), canListen ? 1 : 0); + QCOMPARE(spyReadyRead.count(), canListen ? expectedReadyReadSignals : 0); server.close(); diff --git a/tests/auto/opengl/qgl/BLACKLIST b/tests/auto/opengl/qgl/BLACKLIST index fa7c829b30..547a9a2a73 100644 --- a/tests/auto/opengl/qgl/BLACKLIST +++ b/tests/auto/opengl/qgl/BLACKLIST @@ -1,3 +1,5 @@ +[] +rhel-7.1 [glWidgetRendering] windows [glFBORendering] diff --git a/tests/auto/other/gestures/BLACKLIST b/tests/auto/other/gestures/BLACKLIST index 4e8745ca78..28e4856056 100644 --- a/tests/auto/other/gestures/BLACKLIST +++ b/tests/auto/other/gestures/BLACKLIST @@ -1,2 +1,4 @@ +[] +rhel-7.1 [customGesture] opensuse-13.1 diff --git a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp index aa72be3ea8..5e7a40d3b5 100644 --- a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp +++ b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp @@ -1628,7 +1628,24 @@ void tst_QPrinter::resolution() // Test set/get int expected = 333; #ifdef Q_OS_MAC - // Set resolution does nothing on OSX, see QTBUG-7000 + // QMacPrintEngine chooses the closest supported resolution. + const QList<int> all_supported = native.supportedResolutions(); + foreach (int supported, all_supported) { + // Test setting a supported resolution + int requested = supported; + native.setResolution(requested); + QCOMPARE(native.resolution(), requested); + + // Test setting an unsupported resolution + do { + requested += 5; + } while (all_supported.contains(requested)); + native.setResolution(requested); + int result = native.resolution(); + QVERIFY(all_supported.contains(result)); + QVERIFY(qAbs(result - requested) <= qAbs(supported - requested)); + } + expected = native.resolution(); #endif // Q_OS_MAC native.setResolution(expected); diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index b98ab68ae9..bd553d5ffd 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -1753,24 +1753,6 @@ void tst_QSqlQuery::synonyms() QCOMPARE( rec.field( 2 ).name().toLower(), QString( "t_varchar" ) ); } -// This class is used to test protected QSqlResult methods -class ResultHelper: public QSqlResult -{ - -public: - ResultHelper(): QSqlResult( 0 ) {} // don't call, it's only for stupid compilers - - bool execBatch( bool bindArray = false ) - { - return QSqlResult::execBatch( bindArray ); - } - - QString boundValueName( int pos ) const - { - return QSqlResult::boundValueName( pos ); - } -}; - // It doesn't make sense to split this into several tests void tst_QSqlQuery::prepare_bind_exec() { @@ -1895,81 +1877,81 @@ void tst_QSqlQuery::prepare_bind_exec() q.bindValue( 0, 0 ); q.bindValue( 1, values[ 0 ] ); QCOMPARE( q.boundValues().size(), 2 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 0 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[0] ); + QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 0); + QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[0]); QVERIFY_SQL( q, exec() ); QCOMPARE( q.boundValues().size(), 2 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 0 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[0] ); + QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 0); + QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[0]); q.addBindValue( 1 ); q.addBindValue( values[ 1 ] ); QCOMPARE( q.boundValues().size(), 2 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 1 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[1] ); + QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 1); + QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[1]); QVERIFY_SQL( q, exec() ); QCOMPARE( q.boundValues().size(), 2 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 1 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[1] ); + QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 1); + QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[1]); q.addBindValue( 2 ); q.addBindValue( values[ 2 ] ); QCOMPARE( q.boundValues().size(), 2 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 2 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[2] ); + QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 2); + QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[2]); QVERIFY_SQL( q, exec() ); QCOMPARE( q.boundValues().size(), 2 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 2 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[2] ); + QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 2); + QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[2]); q.addBindValue( 3 ); q.addBindValue( values[ 3 ] ); QCOMPARE( q.boundValues().size(), 2 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 3 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[3] ); + QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 3); + QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[3]); QVERIFY_SQL( q, exec() ); QCOMPARE( q.boundValues().size(), 2 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 3 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[3] ); + QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 3); + QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[3]); q.addBindValue( 4 ); q.addBindValue( values[ 4 ] ); QCOMPARE( q.boundValues().size(), 2 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 4 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[4] ); + QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 4); + QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[4]); QVERIFY_SQL( q, exec() ); QCOMPARE( q.boundValues().size(), 2 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 4 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[4] ); + QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 4); + QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[4]); q.bindValue( 1, values[ 5 ] ); q.bindValue( 0, 5 ); QCOMPARE( q.boundValues().size(), 2 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 5 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[5] ); + QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 5); + QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[5]); QVERIFY_SQL( q, exec() ); QCOMPARE( q.boundValues().size(), 2 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 5 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[5] ); + QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 5); + QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), values[5]); q.bindValue( 0, 6 ); q.bindValue( 1, QString() ); QCOMPARE( q.boundValues().size(), 2 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 6 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), QString() ); + QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 6); + QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), QString()); QVERIFY_SQL( q, exec() ); QCOMPARE( q.boundValues().size(), 2 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 6 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), QString() ); + QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 6); + QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), QString()); if ( db.driver()->hasFeature( QSqlDriver::Unicode ) ) { q.bindValue( 0, 7 ); q.bindValue( 1, utf8str ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 7 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), utf8str ); + QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 7); + QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), utf8str); QVERIFY_SQL( q, exec() ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 7 ); - QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), utf8str ); + QCOMPARE(q.boundValues()[q.result()->boundValueName(0)].toInt(), 7); + QCOMPARE(q.boundValues()[q.result()->boundValueName(1)].toString(), utf8str); } QVERIFY_SQL( q, exec( "SELECT * FROM " + qtest_prepare + " order by id" ) ); diff --git a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp index 3702631275..7007664c39 100644 --- a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp +++ b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp @@ -109,7 +109,7 @@ void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db) QVERIFY_SQL( q, exec("insert into " + reltest1 + " values(5, 'nat', NULL, NULL)")); QVERIFY_SQL( q, exec("insert into " + reltest1 + " values(6, 'ale', NULL, 2)")); - QVERIFY_SQL( q, exec("create table " + reltest2 + " (tid int not null primary key, title varchar(20))")); + QVERIFY_SQL( q, exec("create table " + reltest2 + " (id int not null primary key, title varchar(20))")); QVERIFY_SQL( q, exec("insert into " + reltest2 + " values(1, 'herr')")); QVERIFY_SQL( q, exec("insert into " + reltest2 + " values(2, 'mister')")); @@ -201,7 +201,7 @@ void tst_QSqlRelationalTableModel::data() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.columnCount(), 4); @@ -246,7 +246,7 @@ void tst_QSqlRelationalTableModel::setData() model.setTable(reltest1); model.setSort(0, Qt::AscendingOrder); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QVERIFY(model.setData(model.index(0, 1), QString("harry2"))); @@ -276,7 +276,7 @@ void tst_QSqlRelationalTableModel::setData() QCOMPARE(model.data(model.index(3, 1)).toString(), QString("boris2")); QCOMPARE(model.data(model.index(3, 2)).toInt(), 1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister")); QCOMPARE(model.data(model.index(3,2)).toString(), QString("herr")); @@ -289,7 +289,7 @@ void tst_QSqlRelationalTableModel::setData() model.setTable(reltest1); model.setEditStrategy(QSqlTableModel::OnFieldChange); model.setSort(0, Qt::AscendingOrder); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QVERIFY(model.setData(model.index(1,1), QString("trond2"))); @@ -307,7 +307,7 @@ void tst_QSqlRelationalTableModel::setData() QCOMPARE(model.data(model.index(1, 1)).toString(), QString("trond2")); QCOMPARE(model.data(model.index(2, 2)).toInt(), 2); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(2, 2)).toString(), QString("mister")); } @@ -317,12 +317,12 @@ void tst_QSqlRelationalTableModel::setData() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); //sybase doesn't allow tables with the same alias used twice as col names //so don't set up an identical relation when using the tds driver if (dbType != QSqlDriver::Sybase) - model.setRelation(3, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(3, QSqlRelation(reltest2, "id", "title")); model.setEditStrategy(QSqlTableModel::OnManualSubmit); model.setSort(0, Qt::AscendingOrder); @@ -351,9 +351,9 @@ void tst_QSqlRelationalTableModel::setData() QCOMPARE(model.data(model.index(3, 2)).toInt(), 1); QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); if (dbType != QSqlDriver::Sybase) - model.setRelation(3, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(3, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); @@ -411,7 +411,7 @@ void tst_QSqlRelationalTableModel::multipleRelation() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); model.setRelation(3, QSqlRelation(reltest4, "id", "name")); model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); @@ -425,7 +425,7 @@ void tst_QSqlRelationalTableModel::multipleRelation() // Redo same test in the LeftJoin mode model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); model.setRelation(3, QSqlRelation(reltest4, "id", "name")); model.setSort(0, Qt::AscendingOrder); model.setJoinMode(QSqlRelationalTableModel::LeftJoin); @@ -448,7 +448,7 @@ void tst_QSqlRelationalTableModel::insertRecord() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); @@ -498,7 +498,7 @@ void tst_QSqlRelationalTableModel::setRecord() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); @@ -559,11 +559,11 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); model.setSort(0, Qt::AscendingOrder); if (dbType != QSqlDriver::Sybase) - model.setRelation(3, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(3, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0,0)).toInt(), 1); @@ -667,7 +667,7 @@ void tst_QSqlRelationalTableModel::removeColumn() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QVERIFY_SQL(model, removeColumn(3)); @@ -693,7 +693,7 @@ void tst_QSqlRelationalTableModel::removeColumn() QSqlRelationalTableModel lmodel(0, db); lmodel.setTable(reltest1); - lmodel.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + lmodel.setRelation(2, QSqlRelation(reltest2, "id", "title")); lmodel.setJoinMode(QSqlRelationalTableModel::LeftJoin); QVERIFY_SQL(lmodel, select()); @@ -724,7 +724,7 @@ void tst_QSqlRelationalTableModel::filter() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); model.setFilter("title = 'herr'"); QVERIFY_SQL(model, select()); @@ -751,9 +751,9 @@ void tst_QSqlRelationalTableModel::sort() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); if (dbType != QSqlDriver::Sybase) - model.setRelation(3, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(3, QSqlRelation(reltest2, "id", "title")); model.setSort(2, Qt::DescendingOrder); QVERIFY_SQL(model, select()); @@ -879,7 +879,7 @@ void tst_QSqlRelationalTableModel::revert() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); model.setRelation(3, QSqlRelation(reltest4, "id", "name")); model.setSort(0, Qt::AscendingOrder); @@ -917,10 +917,10 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); if (dbType != QSqlDriver::Sybase) - model.setRelation(3, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(3, QSqlRelation(reltest2, "id", "title")); model.setSort(1, Qt::AscendingOrder); model.setEditStrategy(QSqlTableModel::OnManualSubmit); @@ -1018,7 +1018,7 @@ void tst_QSqlRelationalTableModel::invalidData() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); //try set a non-existent relational key @@ -1048,7 +1048,7 @@ void tst_QSqlRelationalTableModel::relationModel() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QVERIFY(!model.relationModel(0)); @@ -1142,7 +1142,7 @@ void tst_QSqlRelationalTableModel::casing() QSqlRelationalTableModel model(0, db); model.setTable(qTableName("CASETEST1", db).toUpper()); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); @@ -1165,11 +1165,11 @@ void tst_QSqlRelationalTableModel::escapedRelations() //try with relation table name quoted if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2) { model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(reltest2.toUpper(),QSqlDriver::TableName), - "tid", + "id", "title")); } else { model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(reltest2,QSqlDriver::TableName), - "tid", + "id", "title")); } @@ -1190,11 +1190,11 @@ void tst_QSqlRelationalTableModel::escapedRelations() model.setJoinMode(QSqlRelationalTableModel::InnerJoin); if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2) { model.setRelation(2, QSqlRelation(reltest2, - db.driver()->escapeIdentifier("tid", QSqlDriver::FieldName).toUpper(), + db.driver()->escapeIdentifier("id", QSqlDriver::FieldName).toUpper(), "title")); } else { model.setRelation(2, QSqlRelation(reltest2, - db.driver()->escapeIdentifier("tid", QSqlDriver::FieldName), + db.driver()->escapeIdentifier("id", QSqlDriver::FieldName), "title")); } QVERIFY_SQL(model, select()); @@ -1215,11 +1215,11 @@ void tst_QSqlRelationalTableModel::escapedRelations() if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2) { model.setRelation(2, QSqlRelation(reltest2, - "tid", + "id", db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper())); } else { model.setRelation(2, QSqlRelation(reltest2, - "tid", + "id", db.driver()->escapeIdentifier("title", QSqlDriver::FieldName))); } @@ -1240,11 +1240,11 @@ void tst_QSqlRelationalTableModel::escapedRelations() model.setJoinMode(QSqlRelationalTableModel::InnerJoin); if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2) { model.setRelation(2, QSqlRelation(reltest2, - "tid", + "id", db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper())); } else { model.setRelation(2, QSqlRelation(reltest2, - "tid", + "id", db.driver()->escapeIdentifier("title", QSqlDriver::FieldName))); } QVERIFY_SQL(model, select()); @@ -1278,7 +1278,7 @@ void tst_QSqlRelationalTableModel::escapedTableName() model.setTable(db.driver()->escapeIdentifier(reltest1, QSqlDriver::TableName)); } model.setSort(0, Qt::AscendingOrder); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QVERIFY(model.setData(model.index(0, 1), QString("harry2"))); @@ -1308,7 +1308,7 @@ void tst_QSqlRelationalTableModel::escapedTableName() QCOMPARE(model.data(model.index(3, 1)).toString(), QString("boris2")); QCOMPARE(model.data(model.index(3, 2)).toInt(), 1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister")); QCOMPARE(model.data(model.index(3,2)).toString(), QString("herr")); @@ -1325,7 +1325,7 @@ void tst_QSqlRelationalTableModel::escapedTableName() model.setTable(db.driver()->escapeIdentifier(reltest1, QSqlDriver::TableName)); } model.setSort(0, Qt::AscendingOrder); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); model.setJoinMode(QSqlRelationalTableModel::LeftJoin); QVERIFY_SQL(model, select()); @@ -1357,7 +1357,7 @@ void tst_QSqlRelationalTableModel::escapedTableName() QCOMPARE(model.data(model.index(3, 1)).toString(), QString("boris2")); QCOMPARE(model.data(model.index(3, 2)).toInt(), 1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister")); QCOMPARE(model.data(model.index(3,2)).toString(), QString("herr")); @@ -1485,7 +1485,7 @@ void tst_QSqlRelationalTableModel::selectAfterUpdate() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.relationModel(2)->rowCount(), 2); { diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index c113b7cd60..5c16c7a48f 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -131,6 +131,33 @@ typedef struct { int doNotConfuseMoc; } OldStyleCStruct; +namespace { + + class GadgetInUnnamedNS + { + Q_GADGET + Q_PROPERTY(int x READ x WRITE setX) + Q_PROPERTY(int y READ y WRITE setY) + public: + explicit GadgetInUnnamedNS(int x, int y) : m_x(x), m_y(y) {} + int x() const { return m_x; } + int y() const { return m_y; } + void setX(int x) { m_x = x; } + void setY(int y) { m_y = y; } + + private: + int m_x, m_y; + }; + + class ObjectInUnnamedNS : public QObject + { + Q_OBJECT + public: + explicit ObjectInUnnamedNS(QObject *parent = Q_NULLPTR) : QObject(parent) {} + }; + +} + class Sender : public QObject { Q_OBJECT @@ -597,6 +624,7 @@ private slots: void relatedMetaObjectsNameConflict_data(); void relatedMetaObjectsNameConflict(); void strignLiteralsInMacroExtension(); + void unnamedNamespaceObjectsAndGadgets(); void veryLongStringData(); void gadgetHierarchy(); @@ -3421,6 +3449,28 @@ class VeryLongStringData : public QObject #undef repeat65534 }; +void tst_Moc::unnamedNamespaceObjectsAndGadgets() +{ + // these just test very basic functionality of gadgets and objects + // defined in unnamed namespaces. + { + GadgetInUnnamedNS gadget(21, 42); + QCOMPARE(gadget.x(), 21); + QCOMPARE(gadget.y(), 42); + gadget.staticMetaObject.property(0).writeOnGadget(&gadget, 12); + gadget.staticMetaObject.property(1).writeOnGadget(&gadget, 24); + QCOMPARE(gadget.x(), 12); + QCOMPARE(gadget.y(), 24); + } + + { + ObjectInUnnamedNS object; + QObject *qObject = &object; + QCOMPARE(static_cast<ObjectInUnnamedNS *>(qObject), + qobject_cast<ObjectInUnnamedNS *>(qObject)); + } +} + void tst_Moc::veryLongStringData() { const QMetaObject *mobj = &VeryLongStringData::staticMetaObject; diff --git a/tests/auto/tools/uic/baseline/enumnostdset.ui b/tests/auto/tools/uic/baseline/enumnostdset.ui new file mode 100644 index 0000000000..59e27b1be3 --- /dev/null +++ b/tests/auto/tools/uic/baseline/enumnostdset.ui @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Form</class> + <widget class="QWidget" name="Form"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <widget class="WorldTimeClock" name="worldTimeClock"> + <property name="geometry"> + <rect> + <x>100</x> + <y>100</y> + <width>100</width> + <height>100</height> + </rect> + </property> + <property name="penStyle" stdset="0"> + <enum>Qt::DashDotLine</enum> + </property> + </widget> + </widget> + <customwidgets> + <customwidget> + <class>WorldTimeClock</class> + <extends>QWidget</extends> + <header>worldtimeclock.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/tests/auto/tools/uic/baseline/enumnostdset.ui.h b/tests/auto/tools/uic/baseline/enumnostdset.ui.h new file mode 100644 index 0000000000..89a8411b4a --- /dev/null +++ b/tests/auto/tools/uic/baseline/enumnostdset.ui.h @@ -0,0 +1,55 @@ +/******************************************************************************** +** Form generated from reading UI file 'enumnostdset.ui' +** +** Created by: Qt User Interface Compiler version 5.6.1 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef ENUMNOSTDSET_H +#define ENUMNOSTDSET_H + +#include <QtCore/QVariant> +#include <QtWidgets/QAction> +#include <QtWidgets/QApplication> +#include <QtWidgets/QButtonGroup> +#include <QtWidgets/QHeaderView> +#include <QtWidgets/QWidget> +#include "worldtimeclock.h" + +QT_BEGIN_NAMESPACE + +class Ui_Form +{ +public: + WorldTimeClock *worldTimeClock; + + void setupUi(QWidget *Form) + { + if (Form->objectName().isEmpty()) + Form->setObjectName(QStringLiteral("Form")); + Form->resize(400, 300); + worldTimeClock = new WorldTimeClock(Form); + worldTimeClock->setObjectName(QStringLiteral("worldTimeClock")); + worldTimeClock->setGeometry(QRect(100, 100, 100, 100)); + worldTimeClock->setProperty("penStyle", QVariant::fromValue(Qt::DashDotLine)); + + retranslateUi(Form); + + QMetaObject::connectSlotsByName(Form); + } // setupUi + + void retranslateUi(QWidget *Form) + { + Form->setWindowTitle(QApplication::translate("Form", "Form", 0)); + } // retranslateUi + +}; + +namespace Ui { + class Form: public Ui_Form {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // ENUMNOSTDSET_H diff --git a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp index 37afa7f0a5..dc796dbd73 100644 --- a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp +++ b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp @@ -55,7 +55,7 @@ QT_FORWARD_DECLARE_CLASS(QDialog) class DummyDialog : public QDialog { public: - DummyDialog(): QDialog(0, Qt::X11BypassWindowManagerHint) {} + DummyDialog(): QDialog() {} using QDialog::showExtension; }; @@ -65,10 +65,8 @@ class tst_QDialog : public QObject public: tst_QDialog(); -public slots: - void initTestCase(); - void cleanupTestCase(); private slots: + void cleanup(); void getSetCheck(); void showExtension_data(); void showExtension(); @@ -91,9 +89,6 @@ private slots: void transientParent_data(); void transientParent(); void dialogInGraphicsView(); - -private: - DummyDialog *testWidget; }; // Testing get/set functions @@ -149,25 +144,12 @@ private: }; tst_QDialog::tst_QDialog() - { } -void tst_QDialog::initTestCase() +void tst_QDialog::cleanup() { - // Create the test class - testWidget = new DummyDialog; - testWidget->resize(200,200); - testWidget->show(); - qApp->setActiveWindow(testWidget); -} - -void tst_QDialog::cleanupTestCase() -{ - if (testWidget) { - delete testWidget; - testWidget = 0; - } + QVERIFY(QApplication::topLevelWidgets().isEmpty()); } void tst_QDialog::showExtension_data() @@ -190,44 +172,52 @@ void tst_QDialog::showExtension() QFETCH( QSize, extSize ); QFETCH( bool, horizontal ); - // set geometry of main dialog and extension widget - testWidget->setFixedSize( dlgSize ); - QWidget *ext = new QWidget( testWidget ); + DummyDialog testWidget; + testWidget.resize(200, 200); + testWidget.setWindowTitle(QLatin1String(QTest::currentTestFunction()) + QLatin1Char(':') + + QLatin1String(QTest::currentDataTag())); + testWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&testWidget)); + + testWidget.setFixedSize( dlgSize ); + QWidget *ext = new QWidget( &testWidget ); ext->setFixedSize( extSize ); - testWidget->setExtension( ext ); - testWidget->setOrientation( horizontal ? Qt::Horizontal : Qt::Vertical ); + testWidget.setExtension( ext ); + testWidget.setOrientation( horizontal ? Qt::Horizontal : Qt::Vertical ); - QCOMPARE( testWidget->size(), dlgSize ); - QPoint oldPosition = testWidget->pos(); + QCOMPARE( testWidget.size(), dlgSize ); + QPoint oldPosition = testWidget.pos(); // show - testWidget->showExtension( true ); + testWidget.showExtension( true ); // while ( testWidget->size() == dlgSize ) // qApp->processEvents(); - QTEST( testWidget->size(), "result" ); + QTEST( testWidget.size(), "result" ); - QCOMPARE(testWidget->pos(), oldPosition); + QCOMPARE(testWidget.pos(), oldPosition); // hide extension. back to old size ? - testWidget->showExtension( false ); - QCOMPARE( testWidget->size(), dlgSize ); + testWidget.showExtension( false ); + QCOMPARE( testWidget.size(), dlgSize ); - testWidget->setExtension( 0 ); + testWidget.setExtension( 0 ); } void tst_QDialog::defaultButtons() { - QLineEdit *lineEdit = new QLineEdit(testWidget); - QPushButton *push = new QPushButton("Button 1", testWidget); - QPushButton *pushTwo = new QPushButton("Button 2", testWidget); - QPushButton *pushThree = new QPushButton("Button 3", testWidget); + DummyDialog testWidget; + testWidget.resize(200, 200); + testWidget.setWindowTitle(QTest::currentTestFunction()); + QLineEdit *lineEdit = new QLineEdit(&testWidget); + QPushButton *push = new QPushButton("Button 1", &testWidget); + QPushButton *pushTwo = new QPushButton("Button 2", &testWidget); + QPushButton *pushThree = new QPushButton("Button 3", &testWidget); pushThree->setAutoDefault(false); - //we need to show the buttons. Otherwise they won't get the focus - push->show(); - pushTwo->show(); - pushThree->show(); + testWidget.show(); + QApplication::setActiveWindow(&testWidget); + QVERIFY(QTest::qWaitForWindowActive(&testWidget)); push->setDefault(true); QVERIFY(push->isDefault()); @@ -380,11 +370,15 @@ void tst_QDialog::showAsTool() #if defined(Q_OS_UNIX) QSKIP("Qt/X11: Skipped since activeWindow() is not respected by all window managers"); #endif - ToolDialog dialog(testWidget); - testWidget->activateWindow(); + DummyDialog testWidget; + testWidget.resize(200, 200); + testWidget.setWindowTitle(QTest::currentTestFunction()); + ToolDialog dialog(&testWidget); + testWidget.show(); + testWidget.activateWindow(); + QVERIFY(QTest::qWaitForWindowActive(&testWidget)); dialog.exec(); - QTest::qWait(100); - if (testWidget->style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, testWidget)) { + if (testWidget.style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, &testWidget)) { QCOMPARE(dialog.wasActive(), true); } else { QCOMPARE(dialog.wasActive(), false); @@ -560,6 +554,11 @@ void tst_QDialog::reject() QCOMPARE(dialog.called, 4); } +static QByteArray formatPoint(QPoint p) +{ + return QByteArray::number(p.x()) + ", " + QByteArray::number(p.y()); +} + void tst_QDialog::snapToDefaultButton() { #ifdef QT_NO_CURSOR @@ -568,9 +567,9 @@ void tst_QDialog::snapToDefaultButton() if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: Wayland does not support setting the cursor position."); - QPoint topLeftPos = QApplication::desktop()->availableGeometry().topLeft(); - topLeftPos = QPoint(topLeftPos.x() + 100, topLeftPos.y() + 100); - QPoint startingPos(topLeftPos.x() + 250, topLeftPos.y() + 250); + const QRect dialogGeometry(QApplication::desktop()->availableGeometry().topLeft() + + QPoint(100, 100), QSize(200, 200)); + const QPoint startingPos = dialogGeometry.bottomRight() + QPoint(100, 100); QCursor::setPos(startingPos); #ifdef Q_OS_OSX // On OS X we use CGEventPost to move the cursor, it needs at least @@ -581,17 +580,14 @@ void tst_QDialog::snapToDefaultButton() QDialog dialog; QPushButton *button = new QPushButton(&dialog); button->setDefault(true); - dialog.setGeometry(QRect(topLeftPos, QSize(200, 200))); + dialog.setGeometry(dialogGeometry); dialog.show(); QVERIFY(QTest::qWaitForWindowExposed(&dialog)); - if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { - if (theme->themeHint(QPlatformTheme::DialogSnapToDefaultButton).toBool()) { - QPoint localPos = button->mapFromGlobal(QCursor::pos()); - QVERIFY(button->rect().contains(localPos)); - } else { - QCOMPARE(startingPos, QCursor::pos()); - } - } + const QPoint localPos = button->mapFromGlobal(QCursor::pos()); + if (QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::DialogSnapToDefaultButton).toBool()) + QVERIFY2(button->rect().contains(localPos), formatPoint(localPos).constData()); + else + QVERIFY2(!button->rect().contains(localPos), formatPoint(localPos).constData()); #endif // !QT_NO_CURSOR } @@ -605,7 +601,6 @@ void tst_QDialog::transientParent_data() void tst_QDialog::transientParent() { QFETCH(bool, nativewidgets); - testWidget->hide(); QWidget topLevel; topLevel.resize(200, 200); topLevel.move(QGuiApplication::primaryScreen()->availableGeometry().center() - QPoint(100, 100)); diff --git a/tests/auto/widgets/dialogs/qfontdialog/BLACKLIST b/tests/auto/widgets/dialogs/qfontdialog/BLACKLIST index 6d3c17f35f..5fd026537e 100644 --- a/tests/auto/widgets/dialogs/qfontdialog/BLACKLIST +++ b/tests/auto/widgets/dialogs/qfontdialog/BLACKLIST @@ -1,5 +1,7 @@ [task256466_wrongStyle] opensuse-13.1 +rhel-7.1 [setFont] ubuntu-14.04 redhatenterpriselinuxworkstation-6.6 +rhel-7.1 diff --git a/tests/auto/widgets/gestures/qgesturerecognizer/BLACKLIST b/tests/auto/widgets/gestures/qgesturerecognizer/BLACKLIST index 7f55c2dae0..14c41711ac 100644 --- a/tests/auto/widgets/gestures/qgesturerecognizer/BLACKLIST +++ b/tests/auto/widgets/gestures/qgesturerecognizer/BLACKLIST @@ -1,2 +1,8 @@ [panGesture:Two finger] xcb +[swipeGesture:SmallDirectionChange] +rhel-7.1 +[swipeGesture:Line] +rhel-7.1 +[pinchGesture:Standard] +rhel-7.1 diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/BLACKLIST index 717c791280..373343fa22 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/BLACKLIST +++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/BLACKLIST @@ -1,2 +1,5 @@ [hoverEnterLeaveEvent] ubuntu-14.04 +rhel-7.1 +[QTBUG_6986_sendMouseEventToAlienWidget] +rhel-7.1 diff --git a/tests/auto/widgets/graphicsview/qgraphicswidget/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicswidget/BLACKLIST index 5db5c97917..c8d93585b2 100644 --- a/tests/auto/widgets/graphicsview/qgraphicswidget/BLACKLIST +++ b/tests/auto/widgets/graphicsview/qgraphicswidget/BLACKLIST @@ -1,2 +1,3 @@ [initialShow2] ubuntu-14.04 +rhel-7.1 diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index 5b206af357..3cf9f7fe0b 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -152,6 +152,7 @@ private slots: void taskQTBUG_39902_mutualScrollBars_data(); void taskQTBUG_39902_mutualScrollBars(); void horizontalScrollingByVerticalWheelEvents(); + void taskQTBUG_51086_skippingIndexesInSelectedIndexes(); }; // Testing get/set functions @@ -2493,5 +2494,32 @@ void tst_QListView::horizontalScrollingByVerticalWheelEvents() QVERIFY(lv.verticalScrollBar()->value() > vValue); } +void tst_QListView::taskQTBUG_51086_skippingIndexesInSelectedIndexes() +{ + // simple way to get access to selectedIndexes() + class QListViewWithPublicSelectedIndexes : public QListView + { + public: + using QListView::selectedIndexes; + }; + + QStandardItemModel data(10, 1); + QItemSelectionModel selections(&data); + QListViewWithPublicSelectedIndexes list; + list.setModel(&data); + list.setSelectionModel(&selections); + + list.setRowHidden(7, true); + list.setRowHidden(8, true); + + for (int i = 0, count = data.rowCount(); i < count; ++i) + selections.select(data.index(i, 0), QItemSelectionModel::Select); + + const QModelIndexList indexes = list.selectedIndexes(); + + QVERIFY(!indexes.contains(data.index(7, 0))); + QVERIFY(!indexes.contains(data.index(8, 0))); +} + QTEST_MAIN(tst_QListView) #include "tst_qlistview.moc" diff --git a/tests/auto/widgets/itemviews/qtreeview/BLACKLIST b/tests/auto/widgets/itemviews/qtreeview/BLACKLIST new file mode 100644 index 0000000000..5eb80007c4 --- /dev/null +++ b/tests/auto/widgets/itemviews/qtreeview/BLACKLIST @@ -0,0 +1,2 @@ +[setSortingEnabledChild] +windows diff --git a/tests/auto/widgets/itemviews/qtreeview/qtreeview.pro b/tests/auto/widgets/itemviews/qtreeview/qtreeview.pro index e8406dab7b..3abd58e73d 100644 --- a/tests/auto/widgets/itemviews/qtreeview/qtreeview.pro +++ b/tests/auto/widgets/itemviews/qtreeview/qtreeview.pro @@ -4,5 +4,3 @@ QT += widgets testlib QT += widgets-private gui-private core-private SOURCES += tst_qtreeview.cpp HEADERS += ../../../../shared/fakedirmodel.h - -win32: CONFIG += insignificant_test diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 033464c9db..ea85c8e057 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -202,7 +202,8 @@ private slots: void hiddenItems(); void spanningItems(); void rowSizeHint(); - void setSortingEnabled(); + void setSortingEnabledTopLevel(); + void setSortingEnabledChild(); void headerHidden(); void indentation(); @@ -2527,33 +2528,31 @@ void tst_QTreeView::rowSizeHint() //From task 155449 (QTreeWidget has a large width for the first section when sorting //is turned on before items are added) -void tst_QTreeView::setSortingEnabled() + +void tst_QTreeView::setSortingEnabledTopLevel() { - //1st the treeview is a top-level - { - QTreeView view; - QStandardItemModel model(1,1); - view.setModel(&model); - const int size = view.header()->sectionSize(0); - view.setSortingEnabled(true); - model.setColumnCount(3); - //we test that changing the column count doesn't change the 1st column size - QCOMPARE(view.header()->sectionSize(0), size); - } + QTreeView view; + QStandardItemModel model(1,1); + view.setModel(&model); + const int size = view.header()->sectionSize(0); + view.setSortingEnabled(true); + model.setColumnCount(3); + //we test that changing the column count doesn't change the 1st column size + QCOMPARE(view.header()->sectionSize(0), size); +} - //then it is no more a top-level - { - QMainWindow win; - QTreeView view; - QStandardItemModel model(1,1); - view.setModel(&model); - win.setCentralWidget(&view); - const int size = view.header()->sectionSize(0); - view.setSortingEnabled(true); - model.setColumnCount(3); - //we test that changing the column count doesn't change the 1st column size - QCOMPARE(view.header()->sectionSize(0), size); - } +void tst_QTreeView::setSortingEnabledChild() +{ + QMainWindow win; + QTreeView view; + QStandardItemModel model(1,1); + view.setModel(&model); + win.setCentralWidget(&view); + const int size = view.header()->sectionSize(0); + view.setSortingEnabled(true); + model.setColumnCount(3); + //we test that changing the column count doesn't change the 1st column size + QCOMPARE(view.header()->sectionSize(0), size); } void tst_QTreeView::headerHidden() diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index 78ccbe302a..8d18d40e05 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -10,6 +10,7 @@ ubuntu-14.04 osx [updateWhileMinimized] ubuntu-14.04 +rhel-7.1 osx [focusProxyAndInputMethods] linux @@ -31,6 +32,7 @@ osx osx [widgetAt] osx +rhel-7.1 [sheetOpacity] osx [resizeEvent] @@ -63,8 +65,10 @@ osx osx [taskQTBUG_4055_sendSyntheticEnterLeave] osx +rhel-7.1 [syntheticEnterLeave] osx +rhel-7.1 [maskedUpdate] osx [hideWhenFocusWidgetIsChild] diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 8a5250aad4..fb3e644a5c 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -447,6 +447,7 @@ private slots: void touchEventSynthesizedMouseEvent(); void touchUpdateOnNewTouch(); + void touchEventsForGesturePendingWidgets(); void styleSheetPropagation(); @@ -4979,7 +4980,9 @@ static inline QByteArray msgRgbMismatch(unsigned actual, unsigned expected) static QPixmap grabWindow(QWindow *window, int x, int y, int width, int height) { QScreen *screen = window->screen(); - return screen ? screen->grabWindow(window->winId(), x, y, width, height) : QPixmap(); + Q_ASSERT(screen); + QPixmap result = screen->grabWindow(window->winId(), x, y, width, height); + return result.devicePixelRatio() > 1 ? result.scaled(width, height) : result; } #define VERIFY_COLOR(child, region, color) verifyColor(child, region, color, __LINE__) @@ -8505,7 +8508,7 @@ void tst_QWidget::translucentWidget() #ifdef Q_OS_WIN QWidget *desktopWidget = QApplication::desktop()->screen(0); if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA) - widgetSnapshot = qApp->primaryScreen()->grabWindow(desktopWidget->winId(), labelPos.x(), labelPos.y(), label.width(), label.height()); + widgetSnapshot = grabWindow(desktopWidget->windowHandle(), labelPos.x(), labelPos.y(), label.width(), label.height()); else #endif widgetSnapshot = label.grab(QRect(QPoint(0, 0), label.size())); @@ -9786,6 +9789,7 @@ public: m_touchUpdateCount(0), m_touchEndCount(0), m_touchEventCount(0), + m_gestureEventCount(0), m_acceptTouch(false), m_mouseEventCount(0), m_acceptMouse(true) @@ -9823,6 +9827,9 @@ protected: else e->ignore(); return true; + case QEvent::Gesture: + ++m_gestureEventCount; + return true; case QEvent::MouseButtonPress: case QEvent::MouseMove: @@ -9845,6 +9852,7 @@ public: int m_touchUpdateCount; int m_touchEndCount; int m_touchEventCount; + int m_gestureEventCount; bool m_acceptTouch; int m_mouseEventCount; bool m_acceptMouse; @@ -10000,6 +10008,48 @@ void tst_QWidget::touchUpdateOnNewTouch() QCOMPARE(widget.m_touchEndCount, 1); } +void tst_QWidget::touchEventsForGesturePendingWidgets() +{ + QTouchDevice *device = new QTouchDevice; + device->setType(QTouchDevice::TouchScreen); + QWindowSystemInterface::registerTouchDevice(device); + + TouchMouseWidget parent; + TouchMouseWidget child(&parent); + parent.grabGesture(Qt::TapAndHoldGesture); + parent.show(); + + QWindow* window = parent.windowHandle(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + QTest::qWait(500); // needed for QApplication::topLevelAt(), which is used by QGestureManager + QCOMPARE(child.m_touchEventCount, 0); + QCOMPARE(child.m_gestureEventCount, 0); + QCOMPARE(parent.m_touchEventCount, 0); + QCOMPARE(parent.m_gestureEventCount, 0); + QTest::touchEvent(window, device).press(0, QPoint(20, 20), window); + QCOMPARE(child.m_touchEventCount, 0); + QCOMPARE(child.m_gestureEventCount, 0); + QCOMPARE(parent.m_touchBeginCount, 1); // QTapAndHoldGestureRecognizer::create() sets Qt::WA_AcceptTouchEvents + QCOMPARE(parent.m_touchUpdateCount, 0); + QCOMPARE(parent.m_touchEndCount, 0); + QCOMPARE(parent.m_gestureEventCount, 0); + QTest::touchEvent(window, device).move(0, QPoint(25, 25), window); + QCOMPARE(child.m_touchEventCount, 0); + QCOMPARE(child.m_gestureEventCount, 0); + QCOMPARE(parent.m_touchBeginCount, 1); + QCOMPARE(parent.m_touchUpdateCount, 0); + QCOMPARE(parent.m_touchEndCount, 0); + QCOMPARE(parent.m_gestureEventCount, 0); + QTest::qWait(1000); + QTest::touchEvent(window, device).release(0, QPoint(25, 25), window); + QCOMPARE(child.m_touchEventCount, 0); + QCOMPARE(child.m_gestureEventCount, 0); + QCOMPARE(parent.m_touchBeginCount, 1); + QCOMPARE(parent.m_touchUpdateCount, 0); + QCOMPARE(parent.m_touchEndCount, 0); + QVERIFY(parent.m_gestureEventCount > 0); +} + void tst_QWidget::styleSheetPropagation() { QTableView tw; diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp index 5188dfbcfa..58e85d6b58 100644 --- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp +++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp @@ -206,32 +206,20 @@ void tst_QWidget_window::tst_show_resize_hide_show() // QCoreApplication::processEvents(QEventLoop::AllEvents, 1000); } -class TestWidget : public QWidget +class PaintTestWidget : public QWidget { public: - int m_first, m_next; - bool paintEventReceived; + int paintEventCount; - void reset(){ m_first = m_next = 0; paintEventReceived = false; } - bool event(QEvent *event) + explicit PaintTestWidget(QWidget *parent = Q_NULLPTR) + : QWidget(parent) + , paintEventCount(0) + {} + + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE { - switch (event->type()) { - case QEvent::WindowActivate: - case QEvent::WindowDeactivate: - case QEvent::Hide: - case QEvent::Show: - if (m_first) - m_next = event->type(); - else - m_first = event->type(); - break; - case QEvent::Paint: - paintEventReceived = true; - break; - default: - break; - } - return QWidget::event(event); + ++paintEventCount; + QWidget::paintEvent(event); } }; @@ -366,15 +354,15 @@ void tst_QWidget_window::tst_showWithoutActivating() void tst_QWidget_window::tst_paintEventOnSecondShow() { - TestWidget w; + PaintTestWidget w; w.show(); w.hide(); - w.reset(); + w.paintEventCount = 0; w.show(); QVERIFY(QTest::qWaitForWindowExposed(&w)); QApplication::processEvents(); - QTRY_VERIFY(w.paintEventReceived); + QTRY_VERIFY(w.paintEventCount > 0); } #ifndef QT_NO_DRAGANDDROP diff --git a/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp b/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp index 9f03e9b3a0..464a42b4e8 100644 --- a/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp +++ b/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp @@ -624,13 +624,13 @@ void tst_QUndoGroup::commandTextFormat() const QString tsFile = QFINDTESTDATA("testdata/qundogroup.ts"); QVERIFY(!tsFile.isEmpty()); - QVERIFY(!QProcess::execute(binDir + "/lrelease " + tsFile)); + QFile::remove("qundogroup.qm"); // Avoid confusion by strays. + QVERIFY(!QProcess::execute(binDir + "/lrelease -silent " + tsFile + " -qm qundogroup.qm")); QTranslator translator; - const QString qmFile = QFINDTESTDATA("testdata/qundogroup.qm"); - QVERIFY(!qmFile.isEmpty()); - QVERIFY(translator.load(qmFile)); + QVERIFY(translator.load("qundogroup.qm")); + QFile::remove("qundogroup.qm"); qApp->installTranslator(&translator); QUndoGroup group; diff --git a/tests/auto/widgets/util/qundostack/tst_qundostack.cpp b/tests/auto/widgets/util/qundostack/tst_qundostack.cpp index 2c8a9a3ee5..07c5be417a 100644 --- a/tests/auto/widgets/util/qundostack/tst_qundostack.cpp +++ b/tests/auto/widgets/util/qundostack/tst_qundostack.cpp @@ -2968,12 +2968,12 @@ void tst_QUndoStack::commandTextFormat() const QString tsFile = QFINDTESTDATA("testdata/qundostack.ts"); QVERIFY(!tsFile.isEmpty()); - QVERIFY(!QProcess::execute(binDir + "/lrelease " + tsFile)); + QFile::remove("qundostack.qm"); // Avoid confusion by strays. + QVERIFY(!QProcess::execute(binDir + "/lrelease -silent " + tsFile + " -qm qundostack.qm")); QTranslator translator; - const QString qmFile = QFINDTESTDATA("testdata/qundostack.qm"); - QVERIFY(!qmFile.isEmpty()); - QVERIFY(translator.load(qmFile)); + QVERIFY(translator.load("qundostack.qm")); + QFile::remove("qundostack.qm"); qApp->installTranslator(&translator); QUndoStack stack; diff --git a/tests/auto/widgets/widgets/qdockwidget/BLACKLIST b/tests/auto/widgets/widgets/qdockwidget/BLACKLIST deleted file mode 100644 index 60adfb9f4b..0000000000 --- a/tests/auto/widgets/widgets/qdockwidget/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[restoreDockWidget] -ubuntu-14.04 diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index e23634c515..aa86e02465 100644 --- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp @@ -497,9 +497,10 @@ void tst_QMdiArea::subWindowActivated2() spy.clear(); mdiArea.show(); - QVERIFY(QTest::qWaitForWindowExposed(&mdiArea)); + QVERIFY(QTest::qWaitForWindowActive(&mdiArea)); QTRY_COMPARE(spy.count(), 1); - QCOMPARE(mdiArea.activeSubWindow(), activeSubWindow); + QVERIFY(mdiArea.currentSubWindow()); + QTRY_COMPARE(mdiArea.activeSubWindow(), activeSubWindow); spy.clear(); if (qGuiApp->styleHints()->showIsFullScreen()) diff --git a/tests/auto/widgets/widgets/qmdisubwindow/BLACKLIST b/tests/auto/widgets/widgets/qmdisubwindow/BLACKLIST new file mode 100644 index 0000000000..a10cf663d0 --- /dev/null +++ b/tests/auto/widgets/widgets/qmdisubwindow/BLACKLIST @@ -0,0 +1,2 @@ +[setSystemMenu] +rhel-7.1 diff --git a/tests/auto/widgets/widgets/qmenu/BLACKLIST b/tests/auto/widgets/widgets/qmenu/BLACKLIST index de49d5ff45..dbc3e26837 100644 --- a/tests/auto/widgets/widgets/qmenu/BLACKLIST +++ b/tests/auto/widgets/widgets/qmenu/BLACKLIST @@ -1,2 +1,5 @@ [task258920_mouseBorder] osx +rhel-7.1 +[pushButtonPopulateOnAboutToShow] +rhel-7.1 diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index b3f9c54f24..20f17f6e9e 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -110,6 +110,9 @@ private slots: void QTBUG7411_submenus_activate(); void QTBUG30595_rtl_submenu(); void QTBUG20403_nested_popup_on_shortcut_trigger(); +#ifndef QT_NO_CURSOR + void QTBUG47515_widgetActionEnterLeave(); +#endif void QTBUG_10735_crashWithDialog(); #ifdef Q_OS_MAC void QTBUG_37933_ampersands_data(); @@ -1070,6 +1073,112 @@ void tst_QMenu::QTBUG20403_nested_popup_on_shortcut_trigger() QVERIFY(!subsub1.isVisible()); } +class MyWidget : public QWidget +{ +public: + MyWidget(QWidget *parent) : + QWidget(parent), + move(0), enter(0), leave(0) + { + setMinimumSize(100, 100); + setMouseTracking(true); + } + + bool event(QEvent *e) Q_DECL_OVERRIDE + { + switch (e->type()) { + case QEvent::MouseMove: + ++move; + break; + case QEvent::Enter: + ++enter; + break; + case QEvent::Leave: + ++leave; + break; + default: + break; + } + return QWidget::event(e); + } + + int move, enter, leave; +}; + +#ifndef QT_NO_CURSOR +void tst_QMenu::QTBUG47515_widgetActionEnterLeave() +{ + if (QGuiApplication::platformName() == QLatin1String("cocoa")) + QSKIP("This test fails on OS X on CI"); + + const QPoint center = QGuiApplication::primaryScreen()->availableGeometry().center(); + const QPoint cursorPos = center - QPoint(100, 100); + + QScopedPointer<QMenu> menu1(new QMenu("Menu1")); + QScopedPointer<QMenu> menu2(new QMenu("Menu2")); + + QWidgetAction *wA1 = new QWidgetAction(menu1.data()); + MyWidget *w1 = new MyWidget(menu1.data()); + wA1->setDefaultWidget(w1); + + QWidgetAction *wA2 = new QWidgetAction(menu2.data()); + MyWidget *w2 = new MyWidget(menu2.data()); + wA2->setDefaultWidget(w2); + + QAction *nextMenuAct = menu1->addMenu(menu2.data()); + + menu1->addAction(wA1); + menu2->addAction(wA2); + + // Root menu + { + QCursor::setPos(cursorPos); + QCoreApplication::processEvents(); + + menu1->popup(center); + QVERIFY(QTest::qWaitForWindowExposed(menu1.data())); + + QCursor::setPos(w1->mapToGlobal(w1->rect().center())); + QVERIFY(w1->isVisible()); + QTRY_COMPARE(w1->leave, 0); + QTRY_COMPARE(w1->enter, 1); + + // Check whether leave event is not delivered on mouse move + w1->move = 0; + QCursor::setPos(w1->mapToGlobal(w1->rect().center()) + QPoint(1, 1)); + QTRY_COMPARE(w1->move, 1); + QTRY_COMPARE(w1->leave, 0); + QTRY_COMPARE(w1->enter, 1); + + QCursor::setPos(cursorPos); + QTRY_COMPARE(w1->leave, 1); + QTRY_COMPARE(w1->enter, 1); + } + + // Submenu + { + menu1->setActiveAction(nextMenuAct); + QVERIFY(QTest::qWaitForWindowExposed(menu2.data())); + + QCursor::setPos(w2->mapToGlobal(w2->rect().center())); + QVERIFY(w2->isVisible()); + QTRY_COMPARE(w2->leave, 0); + QTRY_COMPARE(w2->enter, 1); + + // Check whether leave event is not delivered on mouse move + w2->move = 0; + QCursor::setPos(w2->mapToGlobal(w2->rect().center()) + QPoint(1, 1)); + QTRY_COMPARE(w2->move, 1); + QTRY_COMPARE(w2->leave, 0); + QTRY_COMPARE(w2->enter, 1); + + QCursor::setPos(cursorPos); + QTRY_COMPARE(w2->leave, 1); + QTRY_COMPARE(w2->enter, 1); + } +} +#endif // !QT_NO_CURSOR + class MyMenu : public QMenu { Q_OBJECT diff --git a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp index ced2253a74..3f1badeda1 100644 --- a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp +++ b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp @@ -279,36 +279,30 @@ void tst_QTabBar::sizeHints() { QTabBar tabBar; tabBar.setFont(QFont("Arial", 10)); - tabBar.addTab("tab 01"); - tabBar.addTab("tab 02"); - tabBar.addTab("tab 03"); - tabBar.addTab("tab 04"); - tabBar.addTab("tab 05"); - tabBar.addTab("tab 06"); - tabBar.addTab("This is tab7"); - tabBar.addTab("This is tab8"); - tabBar.addTab("This is tab9 with a very long title"); // No eliding and no scrolling -> tabbar becomes very wide tabBar.setUsesScrollButtons(false); tabBar.setElideMode(Qt::ElideNone); -// qDebug() << tabBar.minimumSizeHint() << tabBar.sizeHint(); -#ifdef Q_OS_MAC - QEXPECT_FAIL("", "QTBUG-27230", Abort); -#endif + tabBar.addTab("tab 01"); + + // Fetch the minimum size hint width and make sure that we create enough + // tabs. + int minimumSizeHintWidth = tabBar.minimumSizeHint().width(); + for (int i = 0; i <= 700 / minimumSizeHintWidth; ++i) + tabBar.addTab(QString("tab 0%1").arg(i+2)); + + //qDebug() << tabBar.minimumSizeHint() << tabBar.sizeHint(); QVERIFY(tabBar.minimumSizeHint().width() > 700); QVERIFY(tabBar.sizeHint().width() > 700); // Scrolling enabled -> no reason to become very wide tabBar.setUsesScrollButtons(true); - // qDebug() << tabBar.minimumSizeHint() << tabBar.sizeHint(); QVERIFY(tabBar.minimumSizeHint().width() < 200); QVERIFY(tabBar.sizeHint().width() > 700); // unchanged // Eliding enabled -> no reason to become very wide tabBar.setUsesScrollButtons(false); tabBar.setElideMode(Qt::ElideRight); -// qDebug() << tabBar.minimumSizeHint() << tabBar.sizeHint(); // The sizeHint is very much dependent on the screen DPI value // so we can not really predict it. @@ -317,7 +311,7 @@ void tst_QTabBar::sizeHints() QVERIFY(tabBarMinSizeHintWidth < tabBarSizeHintWidth); QVERIFY(tabBarSizeHintWidth > 700); // unchanged - tabBar.addTab("This is tab10 with a very long title"); + tabBar.addTab("This is tab with a very long title"); QVERIFY(tabBar.minimumSizeHint().width() > tabBarMinSizeHintWidth); QVERIFY(tabBar.sizeHint().width() > tabBarSizeHintWidth); } diff --git a/tests/manual/foreignwindows/foreignwindows.pro b/tests/manual/foreignwindows/foreignwindows.pro new file mode 100644 index 0000000000..6a370a6813 --- /dev/null +++ b/tests/manual/foreignwindows/foreignwindows.pro @@ -0,0 +1,6 @@ +TEMPLATE = app +QT += widgets +CONFIG += console c++11 +CONFIG -= app_bundle +SOURCES += main.cpp +include(../diaglib/diaglib.pri) diff --git a/tests/manual/foreignwindows/main.cpp b/tests/manual/foreignwindows/main.cpp new file mode 100644 index 0000000000..6c722a3f6f --- /dev/null +++ b/tests/manual/foreignwindows/main.cpp @@ -0,0 +1,329 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** 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 <QtWidgets/QAction> +#include <QtWidgets/QApplication> +#include <QtWidgets/QDesktopWidget> +#include <QtWidgets/QMainWindow> +#include <QtWidgets/QMenu> +#include <QtWidgets/QMenuBar> +#include <QtWidgets/QToolBar> + +#include <QtGui/QScreen> +#include <QtGui/QWindow> + +#include <QtCore/QCommandLineOption> +#include <QtCore/QCommandLineParser> +#include <QtCore/QDebug> +#include <QtCore/QSharedPointer> +#include <QtCore/QStringList> +#include <QtCore/QTextStream> +#include <QtCore/QTimer> + +#ifdef Q_OS_WIN +# include <QtCore/qt_windows.h> +#endif + +#include <eventfilter.h> // diaglib +#include <nativewindowdump.h> +#include <qwidgetdump.h> +#include <qwindowdump.h> + +#include <iostream> +#include <algorithm> + +QT_USE_NAMESPACE + +typedef QSharedPointer<QWidget> WidgetPtr; +typedef QList<WidgetPtr> WidgetPtrList; +typedef QList<WId> WIdList; + +// Create some pre-defined Windows controls by class name +static WId createInternalWindow(const QString &name) +{ + WId result = 0; +#ifdef Q_OS_WIN + if (name == QLatin1String("BUTTON") || name == QLatin1String("COMBOBOX") + || name == QLatin1String("EDIT") || name.startsWith(QLatin1String("RICHEDIT"))) { + const HWND hwnd = + CreateWindowEx(0, reinterpret_cast<const wchar_t *>(name.utf16()), + L"NativeCtrl", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + 0, 0, GetModuleHandle(NULL), NULL); + if (hwnd) { + SetWindowText(hwnd, L"Demo"); + result = WId(hwnd); + } else { + qErrnoWarning("Cannot create window \"%s\"", qPrintable(name)); + } + } +#else // Q_OS_WIN + Q_UNUSED(name) +#endif + return result; +} + +// Embed a foreign window using createWindowContainer() providing +// menu actions to dump information. +class EmbeddingWindow : public QMainWindow +{ + Q_OBJECT +public: + explicit EmbeddingWindow(QWindow *window); + +public slots: + void releaseForeignWindow(); + +private: + QWindow *m_window; + QAction *m_releaseAction; +}; + +EmbeddingWindow::EmbeddingWindow(QWindow *window) : m_window(window) +{ + const QString title = QLatin1String("Qt ") + QLatin1String(QT_VERSION_STR) + + QLatin1String(" 0x") + QString::number(window->winId(), 16); + setWindowTitle(title); + setObjectName("MainWindow"); + QWidget *container = QWidget::createWindowContainer(window, Q_NULLPTR, Qt::Widget); + container->setObjectName("Container"); + setCentralWidget(container); + + QMenu *fileMenu = menuBar()->addMenu("File"); + fileMenu->setObjectName("FileMenu"); + QToolBar *toolbar = new QToolBar; + addToolBar(Qt::TopToolBarArea, toolbar); + + // Manipulation + QAction *action = fileMenu->addAction("Visible"); + action->setCheckable(true); + action->setChecked(true); + connect(action, &QAction::toggled, m_window, &QWindow::setVisible); + toolbar->addAction(action); + + m_releaseAction = fileMenu->addAction("Release", this, &EmbeddingWindow::releaseForeignWindow); + toolbar->addAction(m_releaseAction); + + fileMenu->addSeparator(); // Diaglib actions + action = fileMenu->addAction("Dump Widgets", + this, [] () { QtDiag::dumpAllWidgets(); }); + toolbar->addAction(action); + action = fileMenu->addAction("Dump Windows", + this, [] () { QtDiag::dumpAllWindows(); }); + toolbar->addAction(action); + action = fileMenu->addAction("Dump Native Windows", + this, [this] () { QtDiag::dumpNativeWindows(winId()); }); + toolbar->addAction(action); + + fileMenu->addSeparator(); + action = fileMenu->addAction("Quit", qApp, &QCoreApplication::quit); + toolbar->addAction(action); + action->setShortcut(Qt::CTRL + Qt::Key_Q); +} + +void EmbeddingWindow::releaseForeignWindow() +{ + if (m_window) { + m_window->setParent(Q_NULLPTR); + m_window = Q_NULLPTR; + m_releaseAction->setEnabled(false); + } +} + +// Dump information about foreign windows. +class WindowDumper : public QObject { + Q_OBJECT +public: + explicit WindowDumper(const QWindowList &watchedWindows) + : m_watchedWindows(watchedWindows) {} + +public slots: + void dump() const; + +private: + const QWindowList m_watchedWindows; +}; + +void WindowDumper::dump() const +{ + static int n = 0; + QString s; + QDebug debug(&s); + debug.nospace(); + debug.setVerbosity(3); + debug << '#' << n++; + if (m_watchedWindows.size() > 1) + debug << '\n'; + foreach (const QWindow *w, m_watchedWindows) { + const QPoint globalPos = w->mapToGlobal(QPoint()); + debug << " " << w << " pos=" << globalPos.x() << ',' << globalPos.y() << '\n'; + } + + std::cout << qPrintable(s); +} + +static QString description(const QString &appName) +{ + QString result; + QTextStream(&result) + << "\nDumps information about foreign windows passed on the command line or\n" + "tests embedding foreign windows into Qt.\n\nUse cases:\n\n" + << appName << " -a Dump a list of all native window ids.\n" + << appName << " <winid> Dump information on the window.\n" + << appName << " -c <winid> Dump information on the window continuously.\n" + << appName << " -e <winid> Embed window into a Qt widget.\n" + << "\nOn Windows, class names of well known controls (EDIT, BUTTON...) can be\n" + "passed as <winid> along with -e, which will create the control.\n"; + return result; +} + +struct EventFilterOption +{ + const char *name; + const char *description; + QtDiag::EventFilter::EventCategories categories; +}; + +EventFilterOption eventFilterOptions[] = { +{"mouse-events", "Dump mouse events.", QtDiag::EventFilter::MouseEvents}, +{"keyboard-events", "Dump keyboard events.", QtDiag::EventFilter::KeyEvents}, +{"state-events", "Dump state/focus change events.", QtDiag::EventFilter::StateChangeEvents | QtDiag::EventFilter::FocusEvents} +}; + +static inline bool isOptionSet(int argc, char *argv[], const char *option) +{ + return (argv + argc) != + std::find_if(argv + 1, argv + argc, + [option] (const char *arg) { return !qstrcmp(arg, option); }); +} + +int main(int argc, char *argv[]) +{ + // Check for no scaling before QApplication is instantiated. + if (isOptionSet(argc, argv, "-s")) + QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling); + QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR)); + QGuiApplication::setApplicationDisplayName("Foreign window tester"); + + QApplication app(argc, argv); + + QCommandLineParser parser; + parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); + parser.setApplicationDescription(description(QCoreApplication::applicationName())); + parser.addHelpOption(); + parser.addVersionOption(); + QCommandLineOption noScalingDummy(QStringLiteral("s"), + QStringLiteral("Disable High DPI scaling.")); + parser.addOption(noScalingDummy); + QCommandLineOption outputAllOption(QStringList() << QStringLiteral("a") << QStringLiteral("all"), + QStringLiteral("Output all native window ids (requires diaglib).")); + parser.addOption(outputAllOption); + QCommandLineOption continuousOption(QStringList() << QStringLiteral("c") << QStringLiteral("continuous"), + QStringLiteral("Output continuously.")); + parser.addOption(continuousOption); + QCommandLineOption embedOption(QStringList() << QStringLiteral("e") << QStringLiteral("embed"), + QStringLiteral("Embed a foreign window into a Qt widget.")); + parser.addOption(embedOption); + const int eventFilterOptionCount = int(sizeof(eventFilterOptions) / sizeof(eventFilterOptions[0])); + for (int i = 0; i < eventFilterOptionCount; ++i) { + parser.addOption(QCommandLineOption(QLatin1String(eventFilterOptions[i].name), + QLatin1String(eventFilterOptions[i].description))); + } + parser.addPositionalArgument(QStringLiteral("[windows]"), QStringLiteral("Window IDs.")); + + parser.process(QCoreApplication::arguments()); + + if (parser.isSet(outputAllOption)) { + QtDiag::dumpNativeWindows(); + return 0; + } + + QWindowList windows; + foreach (const QString &argument, parser.positionalArguments()) { + bool ok = true; + WId wid = createInternalWindow(argument); + if (!wid) + wid = argument.toULongLong(&ok, 0); + if (!wid || !ok) { + std::cerr << "Invalid window id: \"" << qPrintable(argument) << "\"\n"; + return -1; + } + QWindow *foreignWindow = QWindow::fromWinId(wid); + foreignWindow->setObjectName("ForeignWindow" + QString::number(wid, 16)); + windows.append(foreignWindow); + } + + if (windows.isEmpty()) + parser.showHelp(0); + + int exitCode = 0; + + if (parser.isSet(embedOption)) { + QtDiag::EventFilter::EventCategories eventCategories = 0; + for (int i = 0; i < eventFilterOptionCount; ++i) { + if (parser.isSet(QLatin1String(eventFilterOptions[i].name))) + eventCategories |= eventFilterOptions[i].categories; + } + if (eventCategories) + app.installEventFilter(new QtDiag::EventFilter(eventCategories, &app)); + + const QRect availableGeometry = QApplication::desktop()->availableGeometry(0); + QPoint pos = availableGeometry.topLeft() + QPoint(availableGeometry.width(), availableGeometry.height()) / 3; + + WidgetPtrList mainWindows; + foreach (QWindow *window, windows) { + WidgetPtr mainWindow(new EmbeddingWindow(window)); + mainWindow->move(pos); + mainWindow->resize(availableGeometry.size() / 4); + mainWindow->show(); + pos += QPoint(40, 40); + mainWindows.append(mainWindow); + } + exitCode = app.exec(); + + } else if (parser.isSet(continuousOption)) { + WindowDumper dumper(windows); + dumper.dump(); + QTimer *timer = new QTimer(&dumper); + QObject::connect(timer, &QTimer::timeout, &dumper, &WindowDumper::dump); + timer->start(1000); + exitCode = app.exec(); + + } else { + WindowDumper(windows).dump(); + } + + return exitCode; +} + +#include "main.moc" diff --git a/tests/manual/highdpi/dragwidget.cpp b/tests/manual/highdpi/dragwidget.cpp index b203566696..193a90cd18 100644 --- a/tests/manual/highdpi/dragwidget.cpp +++ b/tests/manual/highdpi/dragwidget.cpp @@ -168,7 +168,11 @@ void DragWidget::mousePressEvent(QMouseEvent *event) mimeData->setData("application/x-hotspot", QByteArray::number(hotSpot.x()) + " " + QByteArray::number(hotSpot.y())); - QPixmap pixmap(child->size()); + const qreal dpr = devicePixelRatioF() > 1 && !(QGuiApplication::keyboardModifiers() & Qt::ShiftModifier) + ? devicePixelRatioF() : 1; + + QPixmap pixmap(child->size() * dpr); + pixmap.setDevicePixelRatio(dpr); child->render(&pixmap); QDrag *drag = new QDrag(this); diff --git a/tests/manual/highdpi/main.cpp b/tests/manual/highdpi/main.cpp index 692a60d511..83aefdb88a 100644 --- a/tests/manual/highdpi/main.cpp +++ b/tests/manual/highdpi/main.cpp @@ -380,16 +380,22 @@ Labels::Labels() class MainWindow : public QMainWindow { + Q_OBJECT public: MainWindow(); QMenu *addNewMenu(const QString &title, int itemCount = 5); +private slots: + void maskActionToggled(bool t); + +private: QIcon qtIcon; QIcon qtIcon1x; QIcon qtIcon2x; QToolBar *fileToolBar; int menuCount; + QAction *m_maskAction; }; MainWindow::MainWindow() @@ -408,7 +414,12 @@ MainWindow::MainWindow() addNewMenu("&Edit"); addNewMenu("&Build"); addNewMenu("&Debug", 4); - addNewMenu("&Transmogrify", 7); + QMenu *menu = addNewMenu("&Transmogrify", 7); + menu->addSeparator(); + m_maskAction = menu->addAction("Mask"); + m_maskAction->setCheckable(true); + connect(m_maskAction, &QAction::toggled, this, &MainWindow::maskActionToggled); + fileToolBar->addAction(m_maskAction); addNewMenu("T&ools"); addNewMenu("&Help", 2); } @@ -431,6 +442,16 @@ QMenu *MainWindow::addNewMenu(const QString &title, int itemCount) return menu; } +void MainWindow::maskActionToggled(bool t) +{ + if (t) { + QVector<QPoint> upperLeftTriangle; + upperLeftTriangle << QPoint(0, 0) << QPoint(width(), 0) << QPoint(0, height()); + setMask(QRegion(QPolygon(upperLeftTriangle))); + } else { + clearMask(); + } +} class StandardIcons : public QWidget { diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index cffe76b2b4..8777cc6e11 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -2,6 +2,7 @@ TEMPLATE=subdirs SUBDIRS = bearerex \ filetest \ +foreignwindows \ gestures \ inputmethodhints \ keypadnavigation \ @@ -62,4 +63,5 @@ win32 { } lessThan(QT_MAJOR_VERSION, 5): SUBDIRS -= bearerex lance qnetworkaccessmanager/qget qmimedatabase qnetworkreply \ -qpainfo qscreen socketengine xembed-raster xembed-widgets windowtransparency +qpainfo qscreen socketengine xembed-raster xembed-widgets windowtransparency \ +foreignwindows diff --git a/tests/manual/touch/main.cpp b/tests/manual/touch/main.cpp index b7029767c9..2a5c2b508e 100644 --- a/tests/manual/touch/main.cpp +++ b/tests/manual/touch/main.cpp @@ -91,24 +91,6 @@ static void drawArrow(const QPointF ¢er, qreal length, qreal angleDegrees, painter.restore(); } -QDebug operator<<(QDebug debug, const QTouchDevice *d) -{ - QDebugStateSaver saver(debug); - debug.nospace(); - debug << "QTouchDevice(" << d->name() << ','; - switch (d->type()) { - case QTouchDevice::TouchScreen: - debug << "TouchScreen"; - break; - case QTouchDevice::TouchPad: - debug << "TouchPad"; - break; - } - debug << ", capabilities=" << d->capabilities() - << ", maximumTouchPoints=" << d->maximumTouchPoints() << ')'; - return debug; -} - // Hierarchy of classes containing gesture parameters and drawing functionality. class Gesture { Q_DISABLE_COPY(Gesture) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 555ccbf740..f63892b6cc 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -903,8 +903,10 @@ void Configure::parseCmdLine() dictionary[ "OPENSSL"] = "no"; } else if (configCmdLine.at(i) == "-openssl") { dictionary[ "OPENSSL" ] = "yes"; + dictionary[ "SSL" ] = "yes"; } else if (configCmdLine.at(i) == "-openssl-linked") { dictionary[ "OPENSSL" ] = "linked"; + dictionary[ "SSL" ] = "yes"; } else if (configCmdLine.at(i) == "-no-libproxy") { dictionary[ "LIBPROXY"] = "no"; } else if (configCmdLine.at(i) == "-libproxy") { @@ -1368,6 +1370,14 @@ void Configure::parseCmdLine() dictionary[ "ANDROID_PLATFORM" ] = configCmdLine.at(i); } + else if (configCmdLine.at(i) == "-android-ndk-host") { + ++i; + if (i == argCount) + break; + + dictionary[ "ANDROID_HOST" ] = configCmdLine.at(i); + } + else if (configCmdLine.at(i) == "-android-arch") { ++i; if (i == argCount) @@ -1700,8 +1710,6 @@ void Configure::applySpecSpecifics() dictionary[ "STYLE_WINDOWSCE" ] = "yes"; dictionary[ "STYLE_WINDOWSMOBILE" ] = "yes"; dictionary[ "OPENGL" ] = "no"; - dictionary[ "SSL" ] = "no"; - dictionary[ "OPENSSL" ] = "no"; dictionary[ "RTTI" ] = "no"; dictionary[ "SSE2" ] = "no"; dictionary[ "SSE3" ] = "no"; @@ -3464,7 +3472,9 @@ void Configure::generateQDevicePri() deviceStream << "android_install {" << endl; deviceStream << " DEFAULT_ANDROID_SDK_ROOT = " << formatPath(dictionary["ANDROID_SDK_ROOT"]) << endl; deviceStream << " DEFAULT_ANDROID_NDK_ROOT = " << formatPath(dictionary["ANDROID_NDK_ROOT"]) << endl; - if (QSysInfo::WordSize == 64) + if (dictionary.contains("ANDROID_HOST")) + deviceStream << " DEFAULT_ANDROID_NDK_HOST = " << dictionary["ANDROID_HOST"] << endl; + else if (QSysInfo::WordSize == 64) deviceStream << " DEFAULT_ANDROID_NDK_HOST = windows-x86_64" << endl; else deviceStream << " DEFAULT_ANDROID_NDK_HOST = windows" << endl; |