diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2016-02-11 12:57:10 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2016-02-11 12:57:10 +0000 |
commit | 321658d288b8f790ecfe5ab5198bf6c0d27f0f73 (patch) | |
tree | 24a4be4408ad31f82f4f1c3374c66dd986148844 | |
parent | 7e85e7ced7079d620ae73f8664a68530992c6af1 (diff) | |
parent | d456f87ece0323982b7601047712545ab95426ad (diff) |
Merge "Merge remote-tracking branch 'origin/5.6' into dev" into refs/staging/dev
105 files changed, 875 insertions, 960 deletions
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 @@ -4829,6 +4829,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" 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/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/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index e2046c3c17..7c7a70b09a 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -1492,21 +1492,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"); @@ -1709,9 +1709,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 3071e633c6..dffc3d6acb 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1131,8 +1131,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; @@ -2283,7 +2283,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()); @@ -3184,7 +3184,7 @@ MakefileGenerator::pkgConfigFixPath(QString path) const { QString prefix = pkgConfigPrefix(); if(path.startsWith(prefix)) - path.replace(prefix, "${prefix}"); + path.replace(prefix, QLatin1String("${prefix}")); return path; } @@ -3336,7 +3336,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) @@ -3365,8 +3365,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 c6627f804d..f062605dd4 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -173,12 +173,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) @@ -192,7 +192,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)); } } diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 6049b717c8..9312f19418 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -532,7 +532,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)"; @@ -700,7 +700,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"; @@ -1079,8 +1079,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"); @@ -1099,9 +1099,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") @@ -1147,7 +1147,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 e0b5adb99a..f45cbf74a9 100644 --- a/qmake/generators/win32/cesdkhandler.cpp +++ b/qmake/generators/win32/cesdkhandler.cpp @@ -142,7 +142,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 3f150b5726..382b10c37b 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -46,7 +46,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 6485366f16..4539058cbf 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -323,7 +323,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 3c0b56cfeb..25a2765a01 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -49,7 +49,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) @@ -327,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 6219252161..1b3b328243 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -697,12 +697,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; @@ -1698,12 +1698,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 e7b57d46be..0846cb2d8f 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -398,7 +398,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")) @@ -768,8 +768,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 c1c8f5f493..e92749a126 100644 --- a/qmake/generators/xmloutput.cpp +++ b/qmake/generators/xmloutput.cpp @@ -136,11 +136,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/main.cpp b/qmake/main.cpp index 55eeb29be0..8410e83cbf 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -125,7 +125,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/corelib/codecs/qicucodec.cpp b/src/corelib/codecs/qicucodec.cpp index 17ce045aaa..aa2095d9da 100644 --- a/src/corelib/codecs/qicucodec.cpp +++ b/src/corelib/codecs/qicucodec.cpp @@ -423,6 +423,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/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 7d558cbf81..c962f1b4b7 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -53,7 +53,7 @@ QT_END_NAMESPACE # include "qcoreapplication.h" #endif -#ifdef Q_OS_MAC +#ifdef Q_OS_DARWIN # include "private/qcore_mac_p.h" #endif @@ -171,7 +171,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, @@ -409,12 +409,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 @@ -433,7 +432,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 @@ -549,25 +548,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 { @@ -576,8 +576,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/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index 21c6fd89a9..2e92f8fbba 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -266,17 +266,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/qfilesystemwatcher_win.cpp b/src/corelib/io/qfilesystemwatcher_win.cpp index 5edabe50bc..e8b49db9f3 100644 --- a/src/corelib/io/qfilesystemwatcher_win.cpp +++ b/src/corelib/io/qfilesystemwatcher_win.cpp @@ -171,7 +171,7 @@ QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths, // now look for a thread to insert bool found = false; for (QWindowsFileSystemWatcherEngineThread *thread : qAsConst(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/itemmodels/qstringlistmodel.cpp b/src/corelib/itemmodels/qstringlistmodel.cpp index e28348474c..61323ad9c7 100644 --- a/src/corelib/itemmodels/qstringlistmodel.cpp +++ b/src/corelib/itemmodels/qstringlistmodel.cpp @@ -282,7 +282,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/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index b9e8b2573e..dea8c200ef 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3543,7 +3543,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/plugin/plugin.pri b/src/corelib/plugin/plugin.pri index 9dc60c5d39..544dd41742 100644 --- a/src/corelib/plugin/plugin.pri +++ b/src/corelib/plugin/plugin.pri @@ -39,4 +39,4 @@ darwin { OBJECTIVE_SOURCES += plugin/quuid_darwin.mm } -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 25fbc884b6..f6a947b61a 100644 --- a/src/corelib/plugin/qlibrary_unix.cpp +++ b/src/corelib/plugin/qlibrary_unix.cpp @@ -292,7 +292,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/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 853903619f..9ffef05d78 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -161,7 +161,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; } @@ -212,7 +212,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; } @@ -241,7 +241,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; } @@ -296,7 +296,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; @@ -520,7 +520,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; @@ -631,7 +631,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: @@ -697,7 +697,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; } @@ -705,7 +705,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; @@ -855,7 +855,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; } @@ -916,7 +916,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); @@ -934,7 +934,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); @@ -954,7 +954,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) { @@ -962,7 +962,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; @@ -1046,15 +1046,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 { @@ -1168,7 +1169,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; @@ -1182,7 +1183,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; @@ -1194,7 +1195,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; @@ -1360,22 +1361,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(); @@ -1452,10 +1451,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; @@ -1471,7 +1469,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; @@ -1481,8 +1479,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 @@ -1493,7 +1490,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) { @@ -1521,30 +1518,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; @@ -1559,7 +1542,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()) { @@ -1657,7 +1640,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"); @@ -1675,7 +1658,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)); } } @@ -1684,7 +1667,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 64e73346f2..ad403f695b 100644 --- a/src/corelib/tools/qdatetimeparser_p.h +++ b/src/corelib/tools/qdatetimeparser_p.h @@ -103,7 +103,7 @@ public: none.zeroesAdded = 0; } virtual ~QDateTimeParser() {} - enum { + enum AmPmFinder { Neither = -1, AM = 0, PM = 1, @@ -113,25 +113,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, @@ -140,11 +141,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 @@ -201,16 +207,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 d1f079e07b..c1a1b9715f 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -364,7 +364,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 d6efd5af38..9b0d338e46 100644 --- a/src/corelib/tools/qlocale_unix.cpp +++ b/src/corelib/tools/qlocale_unix.cpp @@ -253,7 +253,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/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index cb8511d0ed..d03e3129aa 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -133,7 +133,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 @@ -345,7 +345,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/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 2ccee3dcd6..db5fb00361 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -1629,6 +1629,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; @@ -1653,6 +1654,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/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index f98b4236fe..53599a3a37 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -244,11 +244,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; @@ -285,7 +287,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; @@ -342,7 +344,7 @@ void QWindowGeometrySpecification::applyTo(QWindow *window) const } } -static QWindowGeometrySpecification windowGeometrySpecification; +static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOMETRY_SPECIFICATION_INITIALIZER; /*! \class QGuiApplication diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 38cc9506ee..c23dbbb3be 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -1267,7 +1267,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; @@ -1318,14 +1339,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 492546616b..eeea0f5772 100644 --- a/src/gui/kernel/qkeysequence_p.h +++ b/src/gui/kernel/qkeysequence_p.h @@ -81,6 +81,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/qwindow.cpp b/src/gui/kernel/qwindow.cpp index e7f7f230f1..c8cf7ddb91 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -983,7 +983,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; } diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 0915fb763a..dcfa3f0647 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1945,9 +1945,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; @@ -2455,12 +2456,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) { diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index dbae48a7ee..52bf44c64a 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1009,7 +1009,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('\\'); @@ -2013,10 +2014,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.)); @@ -2025,7 +2027,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/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index b680bb4717..32cf1b0e83 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -697,7 +697,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('\'')))) @@ -1613,6 +1615,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/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp index 82695ef1f3..34db39e4a8 100644 --- a/src/gui/text/qfontsubset.cpp +++ b/src/gui/text/qfontsubset.cpp @@ -1165,7 +1165,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 @@ -1200,12 +1199,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/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 40689afd9a..d8e12f7024 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -1935,13 +1935,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/platformsupport/dbusmenu/qdbusmenuadaptor.cpp b/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp index fccab420c8..f6a5144e2b 100644 --- a/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp +++ b/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp @@ -57,8 +57,9 @@ QT_BEGIN_NAMESPACE -QDBusMenuAdaptor::QDBusMenuAdaptor(QObject *parent) - : QDBusAbstractAdaptor(parent) +QDBusMenuAdaptor::QDBusMenuAdaptor(QDBusPlatformMenu *topLevelMenu) + : QDBusAbstractAdaptor(topLevelMenu) + , m_topLevelMenu(topLevelMenu) { setAutoRelaySignals(true); } @@ -86,7 +87,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) @@ -94,6 +105,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 } @@ -103,15 +116,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) @@ -122,7 +147,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 327f357b06..6612f019a7 100644 --- a/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h +++ b/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h @@ -146,7 +146,7 @@ class QDBusMenuAdaptor: public QDBusAbstractAdaptor " </interface>\n" "") public: - QDBusMenuAdaptor(QObject *parent); + QDBusMenuAdaptor(QDBusPlatformMenu *topLevelMenu); virtual ~QDBusMenuAdaptor(); public: // PROPERTIES @@ -163,7 +163,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); @@ -172,6 +172,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 b4f5904309..ee25f1a2b0 100644 --- a/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp +++ b/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp @@ -86,6 +86,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()); @@ -101,14 +109,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 02eae7d5b9..b9434ee4d7 100644 --- a/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h +++ b/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h @@ -71,6 +71,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 fbd487aec7..546483fcec 100644 --- a/src/platformsupport/dbusmenu/qdbusmenutypes.cpp +++ b/src/platformsupport/dbusmenu/qdbusmenutypes.cpp @@ -48,6 +48,7 @@ #include <QDebug> #include <QtEndian> #include <QBuffer> +#include <private/qkeysequence_p.h> #include <qpa/qplatformmenu.h> #include "qdbusplatformmenu_p.h" @@ -85,29 +86,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 } @@ -123,11 +122,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) @@ -171,6 +172,7 @@ void QDBusMenuItem::registerDBusTypes() qDBusRegisterMetaType<QDBusMenuLayoutItemList>(); qDBusRegisterMetaType<QDBusMenuEvent>(); qDBusRegisterMetaType<QDBusMenuEventList>(); + qDBusRegisterMetaType<QDBusMenuShortcut>(); } QDBusMenuItem::QDBusMenuItem(const QDBusPlatformMenuItem *item) @@ -188,13 +190,11 @@ QDBusMenuItem::QDBusMenuItem(const QDBusPlatformMenuItem *item) m_properties.insert(QLatin1String("toggle-type"), toggleType); 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()); @@ -204,8 +204,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) @@ -231,6 +230,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 31abc70b1d..1de71b69e4 100644 --- a/src/platformsupport/dbusmenu/qdbusmenutypes_p.h +++ b/src/platformsupport/dbusmenu/qdbusmenutypes_p.h @@ -64,6 +64,7 @@ class QDBusPlatformMenu; class QDBusPlatformMenuItem; class QDBusMenuItem; typedef QVector<QDBusMenuItem> QDBusMenuItemList; +typedef QVector<QStringList> QDBusMenuShortcut; class QDBusMenuItem { @@ -73,6 +74,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; @@ -100,7 +102,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); @@ -146,5 +148,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 70a908a9d6..5e4cf113e0 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp @@ -47,9 +47,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 @@ -92,7 +90,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) @@ -142,7 +144,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) @@ -161,18 +167,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) @@ -186,38 +187,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) @@ -245,6 +267,11 @@ 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); diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h index f8316ef89d..f641ff5d8e 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h @@ -139,6 +139,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); } @@ -147,14 +148,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 { @@ -175,9 +178,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(); @@ -193,12 +193,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 c3fbf9c083..5351bc9f59 100644 --- a/src/platformsupport/dbustray/qdbustrayicon.cpp +++ b/src/platformsupport/dbustray/qdbustrayicon.cpp @@ -190,16 +190,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) { @@ -211,6 +208,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/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm index 49cf9968cc..7028b4d9ec 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm @@ -41,6 +41,8 @@ #include <QtGui/qaccessible.h> #include <private/qcore_mac_p.h> +#include <Carbon/Carbon.h> + QT_BEGIN_NAMESPACE #ifndef QT_NO_ACCESSIBILITY @@ -201,6 +203,8 @@ NSString *macSubrole(QAccessibleInterface *interface) QAccessible::State s = interface->state(); if (s.searchEdit) return NSAccessibilitySearchFieldSubrole; + if (s.passwordEdit) + return NSAccessibilitySecureTextFieldSubrole; return nil; } @@ -359,18 +363,23 @@ id getValueAttribute(QAccessibleInterface *interface) } 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/direct2d/qwindowsdirect2dpaintdevice.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp index 5cea082873..29b01391e2 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp @@ -69,6 +69,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 27be326150..f434ef993c 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h @@ -56,6 +56,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/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp index 79413622a8..201d9d7443 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp @@ -307,8 +307,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/windows/accessible/comutils.cpp b/src/plugins/platforms/windows/accessible/comutils.cpp index 060d5a40b6..ac3683f4d5 100644 --- a/src/plugins/platforms/windows/accessible/comutils.cpp +++ b/src/plugins/platforms/windows/accessible/comutils.cpp @@ -278,348 +278,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/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index 849a97c1ba..d81044cdda 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -1705,12 +1705,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 13eee8e0fa..f91e57ae2f 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp @@ -225,24 +225,6 @@ IAccessible *QWindowsAccessibility::wrap(QAccessibleInterface *acc) #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) @@ -251,12 +233,10 @@ bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, W } 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; diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h index 157b4cac8e..e035e3924a 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h @@ -53,12 +53,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/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp index 9bd23577cc..95e595b88e 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.cpp +++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp @@ -57,9 +57,6 @@ QT_BEGIN_NAMESPACE -static const char formatTextPlainC[] = "text/plain"; -static const char formatTextHtmlC[] = "text/html"; - /*! \class QWindowsClipboard \brief Clipboard implementation. diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 1f66de23ca..8501ec6731 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -95,20 +95,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 diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index 166328cf5e..5c2610a3fe 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -252,9 +252,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 diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 594208ab17..72d9d5a71b 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -743,7 +743,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; } @@ -757,7 +757,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; } @@ -777,13 +777,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(); @@ -1590,11 +1590,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 @@ -1610,8 +1605,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 23ab8d9991..b643d9a920 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.h +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.h @@ -70,9 +70,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; } @@ -81,7 +81,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/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index eee264c5dc..da28b5b19b 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -348,8 +348,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) { } @@ -416,7 +416,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() diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h index 944bdff9b6..ccc2cdcad1 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.h +++ b/src/plugins/platforms/windows/qwindowseglcontext.h @@ -263,9 +263,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; @@ -276,10 +276,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_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index be9cc8bf77..8b61379c42 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -458,6 +458,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) diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index ed7fa441b2..1b88f8bbe4 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -110,17 +110,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; @@ -272,7 +261,6 @@ QWindowsFontEngine::QWindowsFontEngine(const QString &name, m_logfont(lf), ttf(0), hasOutline(0), - lw(0), cmap(0), cmapSize(0), lbearing(SHRT_MIN), @@ -1168,7 +1156,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); @@ -1207,7 +1197,7 @@ QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xfo // Cleanup... delete mask; - if (m_fontEngineData->clearTypeEnabled) { + if (clearTypeTemporarilyDisabled) { DeleteObject(font); } diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h index 75bff00326..7d85b7ef24 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.h +++ b/src/plugins/platforms/windows/qwindowsfontengine.h @@ -150,7 +150,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/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index 4b002799b6..6fc49c1384 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -620,10 +620,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 ]--- diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index cd5deaf8c0..84428c2b1f 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -83,22 +83,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) diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 439f220046..5c283a3113 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -84,11 +84,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)); @@ -105,30 +100,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; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index e83d44bbfe..22a2922235 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -254,13 +254,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()) { diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 4d29cdc316..998f4884aa 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -619,8 +619,8 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra initializeScreens(); initializeXRender(); - m_xi2Enabled = false; #if defined(XCB_USE_XINPUT2) + m_xi2Enabled = false; initializeXInput2(); #endif initializeXShape(); @@ -1142,8 +1142,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: @@ -1930,6 +1938,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" @@ -2224,13 +2233,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 839b51fc49..6a2ecacd77 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -267,6 +267,7 @@ namespace QXcbAtom { AbsMTPositionY, AbsMTTouchMajor, AbsMTTouchMinor, + AbsMTOrientation, AbsMTPressure, AbsMTTrackingID, MaxContacts, @@ -353,8 +354,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 *) {} +#ifdef XCB_USE_XINPUT22 virtual void handleXIMouseEvent(xcb_ge_event_t *) {} - + virtual void handleXIEnterLeave(xcb_ge_event_t *) {} +#endif virtual QXcbWindow *toWindow() { return 0; } }; @@ -491,8 +494,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 @@ -506,7 +509,9 @@ public: QXcbGlIntegration *glIntegration() const { return m_glIntegration; } +#ifdef XCB_USE_XINPUT22 bool xi2MouseEvents() const; +#endif protected: bool event(QEvent *e) Q_DECL_OVERRIDE; @@ -540,9 +545,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 e2bf6e8eb4..ca19c3dce8 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -54,6 +54,7 @@ struct XInput2TouchDeviceData { XInput2TouchDeviceData() : xiDeviceInfo(0) , qtTouchDevice(0) + , providesTouchOrientation(false) { } XIDeviceInfo *xiDeviceInfo; @@ -65,6 +66,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() @@ -299,6 +301,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; @@ -313,9 +320,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()) { @@ -419,6 +429,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)) { @@ -480,6 +492,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) { @@ -494,14 +507,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; @@ -512,11 +527,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 @@ -549,6 +572,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 } @@ -580,7 +610,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) { @@ -605,7 +637,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); @@ -622,8 +671,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) { @@ -687,7 +746,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())) @@ -724,6 +783,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); @@ -833,9 +894,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) { @@ -851,8 +912,8 @@ void QXcbConnection::handleEnterEvent(const xcb_enter_notify_event_t *) XIFreeDeviceInfo(xiDeviceInfo); ++it; } -#endif } +#endif void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice) { diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 68a999d55f..6e8755a220 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -180,9 +180,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 457e58d6ef..4de7716703 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -803,9 +803,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); @@ -821,12 +821,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 ed9ab09ed8..75e6d2ec82 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -74,7 +74,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/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 848cd85b03..240a1dbc74 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -900,8 +900,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) { @@ -2171,6 +2176,85 @@ void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, handleMouseEvent(timestamp, local, global, modifiers); } +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) { @@ -2205,12 +2289,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) { -#ifdef XCB_USE_XINPUT22 QXcbConnection *conn = connection(); xXIDeviceEvent *ev = reinterpret_cast<xXIDeviceEvent *>(event); const Qt::KeyboardModifiers modifiers = conn->keyboard()->translateModifiers(ev->mods.effective_mods); @@ -2248,12 +2330,41 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event) qWarning() << "Unrecognized XI2 mouse event" << ev->evtype; break; } -#else - Q_UNUSED(event); - Q_ASSERT(false); // this can't be -#endif } +// With XI 2.2+ enter/leave comes here and are blocked in plain xcb events +void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event) +{ + xXIEnterEvent *ev = reinterpret_cast<xXIEnterEvent *>(event); + + // 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; + } + + const int root_x = fixed1616ToInt(ev->root_x); + const int root_y = fixed1616ToInt(ev->root_y); + + 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 + QXcbWindow *QXcbWindow::toWindow() { return this; } void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers) @@ -2262,74 +2373,14 @@ void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, con QWindowSystemInterface::handleMouseEvent(window(), time, local, global, connection()->buttons(), modifiers); } -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; -} - -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); -} - -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)) - return false; - - return true; - } -}; - 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) @@ -2383,14 +2434,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(); } @@ -2433,7 +2492,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); diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 0efd78452c..72688cdf16 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -138,7 +138,10 @@ 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; +#ifdef XCB_USE_XINPUT22 void handleXIMouseEvent(xcb_ge_event_t *) Q_DECL_OVERRIDE; + void handleXIEnterLeave(xcb_ge_event_t *) Q_DECL_OVERRIDE; +#endif QXcbWindow *toWindow() Q_DECL_OVERRIDE; @@ -219,6 +222,12 @@ protected: void handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); + 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; uint m_depth; diff --git a/src/testlib/qtestblacklist.cpp b/src/testlib/qtestblacklist.cpp index 8b4b2ab731..4ef2dd3f67 100644 --- a/src/testlib/qtestblacklist.cpp +++ b/src/testlib/qtestblacklist.cpp @@ -40,7 +40,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 1a634a0f75..7b567674e4 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -332,7 +332,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/tools/qdbuscpp2xml/qdbuscpp2xml.cpp b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp index 6fb42ee758..083187555d 100644 --- a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp +++ b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp @@ -392,6 +392,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 ae5178fffc..8fc54794bc 100644 --- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp +++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp @@ -381,7 +381,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()) @@ -392,7 +395,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()) @@ -1137,7 +1140,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 cb480a4b46..4d7bf0a7f3 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -2195,8 +2195,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/dialogs/qsidebar.cpp b/src/widgets/dialogs/qsidebar.cpp index df1e61be1c..2e884e238d 100644 --- a/src/widgets/dialogs/qsidebar.cpp +++ b/src/widgets/dialogs/qsidebar.cpp @@ -466,6 +466,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 4049bd10f2..a188833ef3 100644 --- a/src/widgets/dialogs/qwizard.h +++ b/src/widgets/dialogs/qwizard.h @@ -188,7 +188,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/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp index 7f76ceedfd..bb6d867280 100644 --- a/src/widgets/graphicsview/qgraphicswidget.cpp +++ b/src/widgets/graphicsview/qgraphicswidget.cpp @@ -313,6 +313,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/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index c431e0bcd6..ebdbdbd3e6 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -3154,9 +3154,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(); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index d123bba1d9..7e2e02b58e 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -6443,13 +6443,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); } @@ -7946,8 +7946,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; @@ -8081,8 +8084,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 @@ -12875,9 +12881,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/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index e6dc579f67..38b23ec439 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1248,13 +1248,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/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index 3136118cdd..c8ecc3f192 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -219,6 +219,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 @@ -249,6 +269,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 { @@ -265,11 +286,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; @@ -504,26 +521,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 7529bcaafb..fecfb02782 100644 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ b/src/widgets/styles/qwindowsxpstyle.cpp @@ -377,6 +377,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. @@ -1606,30 +1622,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 b88e171e99..7daef62ce0 100644 --- a/src/widgets/styles/qwindowsxpstyle_p_p.h +++ b/src/widgets/styles/qwindowsxpstyle_p_p.h @@ -421,6 +421,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/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index 2efccdeaf2..c3f9198598 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -879,7 +879,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); @@ -2220,9 +2220,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 69be43a51e..29089311c6 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -3356,8 +3356,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 7eaab2f7ba..03faca157f 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -1451,6 +1451,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/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index c945fd03d2..352d82796d 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -163,6 +163,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 ") @@ -175,6 +176,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 } void tst_QLocale::cleanupTestCase() diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index d9c823273c..8a97a9261f 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -295,6 +295,8 @@ private slots: void drawPolyline_data(); void drawPolyline(); + void QTBUG50153_drawImage_assert(); + private: void fillData(); void setPenColor(QPainter& p); @@ -5035,6 +5037,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/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp index e302788134..04e6bba91e 100644 --- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp @@ -88,6 +88,8 @@ private slots: void task240325(); + void preFont(); + void stylesheetFont_data(); void stylesheetFont(); @@ -664,6 +666,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/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp index 6488b38c9f..cd8bce173b 100644 --- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp +++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp @@ -201,32 +201,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); } }; @@ -361,15 +349,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 b7fc382bef..02ed912323 100644 --- a/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp +++ b/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp @@ -619,13 +619,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 90f29f5eb9..f21780c2c2 100644 --- a/tests/auto/widgets/util/qundostack/tst_qundostack.cpp +++ b/tests/auto/widgets/util/qundostack/tst_qundostack.cpp @@ -2963,12 +2963,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; |