Merge remote-tracking branch 'origin/5.7' into dev

Conflicts:
	configure
5.7 now supports clang on android; but dev re-worked configure

	src/gui/kernel/qevent.h
One side renamed a parameter of a constructor; the other added an
alternate constructor on the next line.  Applied the rename to both
for consistency.

	tests/auto/tools/moc/tst_moc.cpp
Each side added a new test at the end.

	.qmake.conf
Ignored 5.7's change to MODULE_VERSION.

	configure.json
No conflict noticed by git; but changes in 5.7 were needed for the
re-worked configure to accommodate 5.7's stricter handling of C++11.

Change-Id: I9cda53836a32d7bf83828212c7ea00b1de3e09d2
This commit is contained in:
Edward Welbourne 2016-07-28 13:20:41 +02:00
commit f6fc34294f
96 changed files with 2144 additions and 786 deletions

2
.gitignore vendored
View File

@ -152,6 +152,8 @@ tools/activeqt/testcon/testcon.tlb
translations/*.qm
translations/*_untranslated.ts
qrc_*.cpp
*.version
*.version.in
# Test generated files
QObject.log

View File

@ -1,49 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the configuration of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__INTEL_CXX11_MODE__)
// Compiler claims to support C++11, trust it
#else
# error "__cplusplus must be >= 201103L, or one of __GXX_EXPERIMENTAL_CXX0X__ or __INTEL_CXX11_MODE__ must be defined"
#endif
#include <utility>
#include <initializer_list>
int main(int, char **) { return std::move(0); }

View File

@ -1,3 +0,0 @@
SOURCES = c++11.cpp
CONFIG += c++11 console
CONFIG -= qt

View File

@ -5,7 +5,7 @@ COMPILER=$1
VERBOSE=$2
case "$COMPILER" in
icpc)
*icpc)
cat >header.h <<EOF
#define HEADER_H

11
configure vendored
View File

@ -417,7 +417,7 @@ if [ "$BUILD_ON_MAC" = "yes" ]; then
exit 2
fi
if ! /usr/bin/xcrun -find xcrun >/dev/null 2>&1; then
if ! /usr/bin/xcrun -find xcodebuild >/dev/null 2>&1; then
echo >&2
echo " Xcode not set up properly. You may need to confirm the license" >&2
echo " agreement by running /usr/bin/xcodebuild without arguments." >&2
@ -1027,7 +1027,10 @@ case "$XPLATFORM" in
*unsupported*)
;;
*android-g++*)
XPLATFORM_ANDROID=yes
XPLATFORM_ANDROID=g++
;;
*android-clang*)
XPLATFORM_ANDROID=clang
;;
esac
@ -1193,7 +1196,7 @@ fi
# command line and environment validation
#-------------------------------------------------------------------------------
if [ "$XPLATFORM_ANDROID" = "yes" ]; then
if [ "$XPLATFORM_ANDROID" != "no" ]; then
if [ -z "$CFG_DEFAULT_ANDROID_NDK_HOST" ]; then
case $PLATFORM in
linux-*)
@ -1336,7 +1339,7 @@ if [ "$OPT_SHADOW" = "yes" ]; then
mkdir -p "$outpath/mkspecs"
fi
if [ "$XPLATFORM_ANDROID" != "yes" ]; then
if [ "$XPLATFORM_ANDROID" = "no" ]; then
TEST_COMPILER=`getXQMakeConf QMAKE_CXX`
GCC_MACHINE_DUMP=
case "$TEST_COMPILER" in *g++) GCC_MACHINE_DUMP=$($TEST_COMPILER -dumpmachine);; esac

View File

@ -81,18 +81,18 @@ if not "%icl.exe%" == "" (
rem This must have a trailing space.
echo QTSRC = %QTSRC% >> Makefile
set tmpl=win32
) else if not "%clang-cl.exe%" == "" (
echo CXX = clang-cl>>Makefile
echo EXTRA_CXXFLAGS = -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-value>>Makefile
rem This must have a trailing space.
echo QTSRC = %QTSRC% >> Makefile
set tmpl=win32
) else if not "%cl.exe%" == "" (
echo CXX = cl>>Makefile
echo EXTRA_CXXFLAGS =>>Makefile
rem This must have a trailing space.
echo QTSRC = %QTSRC% >> Makefile
set tmpl=win32
) else if not "%clang-cl.exe%" == "" (
echo CXX = clang-cl>>Makefile
echo EXTRA_CXXFLAGS = -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-value>>Makefile
rem This must have a trailing space.
echo QTSRC = %QTSRC% >> Makefile
set tmpl=win32
) else if not "%g++.exe%" == "" (
echo CXX = g++>>Makefile
echo EXTRA_CXXFLAGS =>>Makefile

View File

@ -225,11 +225,6 @@
"type": "compile",
"test": "unix/stl"
},
"c++11": {
"description": "C++11 support",
"type": "compile",
"test": "common/c++11"
},
"c++14": {
"description": "C++14 support",
"type": "compile",
@ -1178,7 +1173,6 @@
},
"c++11": {
"description": "C++11",
"condition": "tests.c++11",
"output": [ "publicQtConfig" ]
},
"c++14": {
@ -2330,11 +2324,6 @@ Please apply the patch corresponding to your Standard Library vendor, found in
"type": "error",
"condition": "!features.stl",
"message": "Qt requires a compliant STL library."
},
{
"type": "error",
"condition": "!features.c++11",
"message": "Qt requires a C++11 compiler."
}
],

View File

@ -250,6 +250,7 @@ manifestmeta.thumbnail.names = "QtCore/Contiguous Cache Example" \
"QtHelp/*" \
"QtMultimedia/AudioEngine Example" \
"QtQml/Extending QML*" \
"QtQuick/C++ Extensions: Image Response Provider Example" \
"QtQuick/Qt Quick Examples - Accessibility" \
"QtSensors/Qt Sensors - SensorGesture QML Type example" \
"QtWinExtras/Icon Extractor"

View File

@ -172,7 +172,8 @@ QString MimetypeModel::formatMimeTypeInfo(const QMimeType &t)
str << "</td></tr>"
<< "<tr><td>Comment:</td><td>" << t.comment() << "</td></tr>"
<< "<tr><td>Icon name:</td><td>" << t.iconName() << "</td></tr>";
<< "<tr><td>Icon name:</td><td>" << t.iconName() << "</td></tr>"
<< "<tr><td>Generic icon name</td><td>" << t.genericIconName() << "</td></tr>";
const QString &filter = t.filterString();
if (!filter.isEmpty())

View File

@ -61,6 +61,7 @@
#include <QDialog>
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QSignalBlocker>
#include <QSpinBox>
#include <QLabel>
#include <QPainterPath>
@ -426,20 +427,22 @@ void ColorSwatch::updateContextMenu()
allowBottomAction->setEnabled(area != Qt::BottomDockWidgetArea);
}
leftAction->blockSignals(true);
rightAction->blockSignals(true);
topAction->blockSignals(true);
bottomAction->blockSignals(true);
leftAction->setChecked(area == Qt::LeftDockWidgetArea);
rightAction->setChecked(area == Qt::RightDockWidgetArea);
topAction->setChecked(area == Qt::TopDockWidgetArea);
bottomAction->setChecked(area == Qt::BottomDockWidgetArea);
leftAction->blockSignals(false);
rightAction->blockSignals(false);
topAction->blockSignals(false);
bottomAction->blockSignals(false);
{
const QSignalBlocker blocker(leftAction);
leftAction->setChecked(area == Qt::LeftDockWidgetArea);
}
{
const QSignalBlocker blocker(rightAction);
rightAction->setChecked(area == Qt::RightDockWidgetArea);
}
{
const QSignalBlocker blocker(topAction);
topAction->setChecked(area == Qt::TopDockWidgetArea);
}
{
const QSignalBlocker blocker(bottomAction);
bottomAction->setChecked(area == Qt::BottomDockWidgetArea);
}
if (areaActions->isEnabled()) {
leftAction->setEnabled(areas & Qt::LeftDockWidgetArea);

View File

@ -167,25 +167,27 @@ void MainWindow::findSizes(const QFont &font)
{
QFontDatabase fontDatabase;
QString currentSize = sizeCombo->currentText();
sizeCombo->blockSignals(true);
sizeCombo->clear();
int size;
if(fontDatabase.isSmoothlyScalable(font.family(), fontDatabase.styleString(font))) {
foreach(size, QFontDatabase::standardSizes()) {
sizeCombo->addItem(QVariant(size).toString());
sizeCombo->setEditable(true);
}
{
const QSignalBlocker blocker(sizeCombo);
// sizeCombo signals are now blocked until end of scope
sizeCombo->clear();
} else {
foreach(size, fontDatabase.smoothSizes(font.family(), fontDatabase.styleString(font))) {
sizeCombo->addItem(QVariant(size).toString());
sizeCombo->setEditable(false);
int size;
if (fontDatabase.isSmoothlyScalable(font.family(), fontDatabase.styleString(font))) {
foreach (size, QFontDatabase::standardSizes()) {
sizeCombo->addItem(QVariant(size).toString());
sizeCombo->setEditable(true);
}
} else {
foreach (size, fontDatabase.smoothSizes(font.family(), fontDatabase.styleString(font))) {
sizeCombo->addItem(QVariant(size).toString());
sizeCombo->setEditable(false);
}
}
}
sizeCombo->blockSignals(false);
int sizeIndex = sizeCombo->findText(currentSize);
if(sizeIndex == -1)

View File

@ -0,0 +1,32 @@
# qmake configuration for building with android-g++
MAKEFILE_GENERATOR = UNIX
QMAKE_PLATFORM = android
QMAKE_COMPILER = gcc clang llvm
CONFIG += android_install unversioned_soname unversioned_libname android_deployment_settings
include(../common/linux.conf)
include(../common/clang.conf)
include(../common/android-base-head.conf)
NDK_LLVM_PATH = $$NDK_ROOT/toolchains/llvm/prebuilt/$$NDK_HOST
QMAKE_CC = $$NDK_LLVM_PATH/bin/clang
QMAKE_CXX = $$NDK_LLVM_PATH/bin/clang++
QMAKE_GCC = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-g++
equals(ANDROID_TARGET_ARCH, armeabi-v7a): \
QMAKE_CFLAGS = -target armv7-none-linux-androideabi
else: equals(ANDROID_TARGET_ARCH, armeabi): \
QMAKE_CFLAGS = -target armv5te-none-linux-androideabi
else: equals(ANDROID_TARGET_ARCH, arm64-v8a): \
QMAKE_CFLAGS = -target aarch64-none-linux-android
else: equals(ANDROID_TARGET_ARCH, x86): \
QMAKE_CFLAGS = -target i686-none-linux-android
else: equals(ANDROID_TARGET_ARCH, x86_64): \
QMAKE_CFLAGS = -target x86_64-none-linux-android
else: equals(ANDROID_TARGET_ARCH, mips): \
QMAKE_CFLAGS += -target mipsel-none-linux-android
else: equals(ANDROID_TARGET_ARCH, mips64): \
QMAKE_CFLAGS = -target mips64el-none-linux-android
include(../common/android-base-tail.conf)

View File

@ -0,0 +1,176 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake spec of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QPLATFORMDEFS_H
#define QPLATFORMDEFS_H
#define QT_QPA_DEFAULT_PLATFORM_NAME "android"
// Get Qt defines/settings
#include "qglobal.h"
// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs
// 1) need to reset default environment if _BSD_SOURCE is defined
// 2) need to specify POSIX thread interfaces explicitly in glibc 2.0
// 3) it seems older glibc need this to include the X/Open stuff
#include <unistd.h>
// We are hot - unistd.h should have turned on the specific APIs we requested
#include <features.h>
#include <pthread.h>
#include <dirent.h>
#include <fcntl.h>
#include <grp.h>
#include <pwd.h>
#include <signal.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/ipc.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/wait.h>
#ifndef QT_NO_IPV6IFNAME
#include <net/if.h>
#endif
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#ifdef QT_LARGEFILE_SUPPORT
#define QT_STATBUF struct stat64
#define QT_STATBUF4TSTAT struct stat64
#define QT_STAT ::stat64
#define QT_FSTAT ::fstat64
#define QT_LSTAT ::lstat64
#define QT_OPEN ::open64
#define QT_TRUNCATE ::truncate64
#define QT_FTRUNCATE ::ftruncate64
#define QT_LSEEK ::lseek64
#else
#define QT_STATBUF struct stat
#define QT_STATBUF4TSTAT struct stat
#define QT_STAT ::stat
#define QT_FSTAT ::fstat
#define QT_LSTAT ::lstat
#define QT_OPEN ::open
#define QT_TRUNCATE ::truncate
#define QT_FTRUNCATE ::ftruncate
#define QT_LSEEK ::lseek
#endif
#ifdef QT_LARGEFILE_SUPPORT
#define QT_FOPEN ::fopen64
#define QT_FSEEK ::fseeko64
#define QT_FTELL ::ftello64
#define QT_FGETPOS ::fgetpos64
#define QT_FSETPOS ::fsetpos64
#define QT_MMAP ::mmap64
#define QT_FPOS_T fpos64_t
#define QT_OFF_T off64_t
#else
#define QT_FOPEN ::fopen
#define QT_FSEEK ::fseek
#define QT_FTELL ::ftell
#define QT_FGETPOS ::fgetpos
#define QT_FSETPOS ::fsetpos
#define QT_MMAP ::mmap
#define QT_FPOS_T fpos_t
#define QT_OFF_T long
#endif
#define QT_STAT_REG S_IFREG
#define QT_STAT_DIR S_IFDIR
#define QT_STAT_MASK S_IFMT
#define QT_STAT_LNK S_IFLNK
#define QT_SOCKET_CONNECT ::connect
#define QT_SOCKET_BIND ::bind
#define QT_FILENO fileno
#define QT_CLOSE ::close
#define QT_READ ::read
#define QT_WRITE ::write
#define QT_ACCESS ::access
#define QT_GETCWD ::getcwd
#define QT_CHDIR ::chdir
#define QT_MKDIR ::mkdir
#define QT_RMDIR ::rmdir
#define QT_OPEN_LARGEFILE O_LARGEFILE
#define QT_OPEN_RDONLY O_RDONLY
#define QT_OPEN_WRONLY O_WRONLY
#define QT_OPEN_RDWR O_RDWR
#define QT_OPEN_CREAT O_CREAT
#define QT_OPEN_TRUNC O_TRUNC
#define QT_OPEN_APPEND O_APPEND
// Directory iteration
#define QT_DIR DIR
#define QT_OPENDIR ::opendir
#define QT_CLOSEDIR ::closedir
#if defined(QT_LARGEFILE_SUPPORT) \
&& defined(QT_USE_XOPEN_LFS_EXTENSIONS) \
&& !defined(QT_NO_READDIR64)
#define QT_DIRENT struct dirent64
#define QT_READDIR ::readdir64
#define QT_READDIR_R ::readdir64_r
#else
#define QT_DIRENT struct dirent
#define QT_READDIR ::readdir
#define QT_READDIR_R ::readdir_r
#endif
#define QT_SOCKET_CONNECT ::connect
#define QT_SOCKET_BIND ::bind
#define QT_SIGNAL_RETTYPE void
#define QT_SIGNAL_ARGS int
#define QT_SIGNAL_IGNORE SIG_IGN
#define QT_SOCKLEN_T socklen_t
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
#define QT_SNPRINTF ::snprintf
#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H

View File

@ -7,202 +7,12 @@ CONFIG += android_install unversioned_soname unversioned_libname
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/android-base-head.conf)
load(device_config)
NDK_ROOT = $$(ANDROID_NDK_ROOT)
!exists($$NDK_ROOT) {
NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT
}
NDK_HOST = $$(ANDROID_NDK_HOST)
isEmpty(NDK_HOST): NDK_HOST = $$DEFAULT_ANDROID_NDK_HOST
ANDROID_PLATFORM = $$(ANDROID_NDK_PLATFORM)
isEmpty(ANDROID_PLATFORM): ANDROID_PLATFORM = $$DEFAULT_ANDROID_PLATFORM
ANDROID_TARGET_ARCH = $$(ANDROID_TARGET_ARCH)
isEmpty(ANDROID_TARGET_ARCH): ANDROID_TARGET_ARCH = $$DEFAULT_ANDROID_TARGET_ARCH
NDK_TOOLCHAIN_PREFIX = $$(ANDROID_NDK_TOOLCHAIN_PREFIX)
isEmpty(NDK_TOOLCHAIN_PREFIX) {
equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLCHAIN_PREFIX = x86
else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLCHAIN_PREFIX = x86_64
else: equals(ANDROID_TARGET_ARCH, mips): NDK_TOOLCHAIN_PREFIX = mipsel-linux-android
else: equals(ANDROID_TARGET_ARCH, mips64): NDK_TOOLCHAIN_PREFIX = mips64el-linux-android
else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLCHAIN_PREFIX = aarch64-linux-android
else: NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi
}
NDK_TOOLS_PREFIX = $$(ANDROID_NDK_TOOLS_PREFIX)
isEmpty(NDK_TOOLS_PREFIX) {
equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLS_PREFIX = i686-linux-android
else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLS_PREFIX = x86_64-linux-android
else: equals(ANDROID_TARGET_ARCH, mips): NDK_TOOLS_PREFIX = mipsel-linux-android
else: equals(ANDROID_TARGET_ARCH, mips64): NDK_TOOLS_PREFIX = mips64el-linux-android
else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLS_PREFIX = aarch64-linux-android
else: NDK_TOOLS_PREFIX = arm-linux-androideabi
}
NDK_TOOLCHAIN_VERSION = $$(ANDROID_NDK_TOOLCHAIN_VERSION)
isEmpty(NDK_TOOLCHAIN_VERSION): NDK_TOOLCHAIN_VERSION = $$DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION
equals(ANDROID_TARGET_ARCH, x86): ANDROID_ARCHITECTURE = x86
else: equals(ANDROID_TARGET_ARCH, x86_64): ANDROID_ARCHITECTURE = x86_64
else: equals(ANDROID_TARGET_ARCH, mips): ANDROID_ARCHITECTURE = mips
else: equals(ANDROID_TARGET_ARCH, mips64): ANDROID_ARCHITECTURE = mips64
else: equals(ANDROID_TARGET_ARCH, arm64-v8a): ANDROID_ARCHITECTURE = arm64
else: ANDROID_ARCHITECTURE = arm
!equals(NDK_TOOLCHAIN_VERSION, 4.4.3): ANDROID_CXXSTL_SUFFIX = -$$NDK_TOOLCHAIN_VERSION
NDK_TOOLCHAIN = $$NDK_TOOLCHAIN_PREFIX-$$NDK_TOOLCHAIN_VERSION
NDK_TOOLCHAIN_PATH = $$NDK_ROOT/toolchains/$$NDK_TOOLCHAIN/prebuilt/$$NDK_HOST
ANDROID_SDK_ROOT = $$(ANDROID_SDK_ROOT)
isEmpty(ANDROID_SDK_ROOT): ANDROID_SDK_ROOT = $$DEFAULT_ANDROID_SDK_ROOT
ANDROID_SDK_BUILD_TOOLS_REVISION = $$(ANDROID_BUILD_TOOLS_REVISION)
isEmpty(ANDROID_SDK_BUILD_TOOLS_REVISION) {
SDK_BUILD_TOOLS_REVISIONS = $$files($$ANDROID_SDK_ROOT/build-tools/*)
for (REVISION, SDK_BUILD_TOOLS_REVISIONS) {
BASENAME = $$basename(REVISION)
greaterThan(BASENAME, $$ANDROID_SDK_BUILD_TOOLS_REVISION): ANDROID_SDK_BUILD_TOOLS_REVISION = $$BASENAME
}
}
CONFIG += $$ANDROID_PLATFORM
ANDROID_PLATFORM_ROOT_PATH = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/
ANDROID_PLATFORM_PATH = $$ANDROID_PLATFORM_ROOT_PATH/usr
# used to compile platform plugins for android-4 and android-5
QMAKE_ANDROID_PLATFORM_INCDIR = $$ANDROID_PLATFORM_PATH/include
QMAKE_ANDROID_PLATFORM_LIBDIR = $$ANDROID_PLATFORM_PATH/lib
ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/libs/$$ANDROID_TARGET_ARCH
ANDROID_SOURCES_CXX_STL_INCDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/include $$ANDROID_SOURCES_CXX_STL_LIBDIR/include
equals(ANDROID_TARGET_ARCH, x86_64)|equals(ANDROID_TARGET_ARCH, mips64): \
QMAKE_ANDROID_PLATFORM_LIBDIR = $${QMAKE_ANDROID_PLATFORM_LIBDIR}64
# modifications to g++.conf
QMAKE_CC = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-gcc
equals(ANDROID_TARGET_ARCH, armeabi-v7a): \
QMAKE_CFLAGS = -Wno-psabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -DANDROID -Wa,--noexecstack -fno-builtin-memmove
else: equals(ANDROID_TARGET_ARCH, armeabi): \
QMAKE_CFLAGS = -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -DANDROID -Wa,--noexecstack -fno-builtin-memmove
else: equals(ANDROID_TARGET_ARCH, arm64-v8a): \
QMAKE_CFLAGS = -ffunction-sections -funwind-tables -fstack-protector -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300 -DANDROID -Wa,--noexecstack
else: equals(ANDROID_TARGET_ARCH, x86): \
QMAKE_CFLAGS = -ffunction-sections -funwind-tables -O2 -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300 -DANDROID -Wa,--noexecstack
else: equals(ANDROID_TARGET_ARCH, x86_64): \
QMAKE_CFLAGS = -ffunction-sections -funwind-tables -fstack-protector -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300 -DANDROID -Wa,--noexecstack
else: equals(ANDROID_TARGET_ARCH, mips): \
QMAKE_CFLAGS = -fno-strict-aliasing -finline-functions -ffunction-sections -funwind-tables -fmessage-length=0 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers -O2 -fomit-frame-pointer -funswitch-loops -finline-limit=300 -DANDROID -Wa,--noexecstack
else: equals(ANDROID_TARGET_ARCH, mips64): \
QMAKE_CFLAGS = -fno-strict-aliasing -finline-functions -ffunction-sections -funwind-tables -fmessage-length=0 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers -fomit-frame-pointer -funswitch-loops -finline-limit=300 -DANDROID -Werror -Wa,--noexecstack
QMAKE_CFLAGS_WARN_ON = -Wall -Wno-psabi -W
QMAKE_CFLAGS_WARN_OFF = -Wno-psabi
equals(ANDROID_TARGET_ARCH, x86) {
QMAKE_CFLAGS_RELEASE = -O2
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2
QMAKE_CFLAGS_DEBUG = -g
} else: equals(ANDROID_TARGET_ARCH, x86_64) {
QMAKE_CFLAGS_RELEASE = -O2
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2
QMAKE_CFLAGS_DEBUG = -g
} else: equals(ANDROID_TARGET_ARCH, mips) {
QMAKE_CFLAGS_RELEASE = -O2
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2
QMAKE_CFLAGS_DEBUG = -g -fno-omit-frame-pointer
} else: equals(ANDROID_TARGET_ARCH, mips64) {
QMAKE_CFLAGS_RELEASE = -O2
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2
QMAKE_CFLAGS_DEBUG = -g -fno-omit-frame-pointer
} else: equals(ANDROID_TARGET_ARCH, arm64-v8a) {
QMAKE_CFLAGS_RELEASE = -O2
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2
QMAKE_CFLAGS_DEBUG = -g -fno-omit-frame-pointer
} else { # arm
QMAKE_CFLAGS_RELEASE = -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64
QMAKE_CFLAGS_DEBUG = -g -marm -O0 -fno-omit-frame-pointer
equals(ANDROID_TARGET_ARCH, armeabi):if(equals(NDK_TOOLCHAIN_VERSION, 4.8)|equals(NDK_TOOLCHAIN_VERSION, 4.9)) {
DEFINES += QT_OS_ANDROID_GCC_48_WORKAROUND
} else {
QMAKE_CFLAGS_RELEASE += -mthumb
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb
}
}
QMAKE_CFLAGS_SHLIB = -fPIC
QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
QMAKE_CFLAGS_THREAD = -D_REENTRANT
QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden
QMAKE_CXX = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-g++
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -std=c++11
QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE
QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG
QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
QMAKE_GCC = $$QMAKE_CXX
QMAKE_LINK = $$QMAKE_CXX
QMAKE_LINK_SHLIB = $$QMAKE_LINK
QMAKE_CFLAGS =
# modifications to linux.conf
QMAKE_AR = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-ar cqs
QMAKE_OBJCOPY = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-objcopy
QMAKE_NM = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-nm -P
QMAKE_STRIP =
#$$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-strip
QMAKE_RANLIB = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-ranlib
equals(ANDROID_TARGET_ARCH, armeabi)|equals(ANDROID_TARGET_ARCH, armeabi-v7a): \
LIBGCC_PATH_FULL = $$system("$$QMAKE_CC -mthumb-interwork -print-libgcc-file-name")
else: \
LIBGCC_PATH_FULL = $$system("$$QMAKE_CC -print-libgcc-file-name")
LIBGCC_PATH = $$dirname(LIBGCC_PATH_FULL)
QMAKE_INCDIR = $$ANDROID_SOURCES_CXX_STL_INCDIR $$QMAKE_ANDROID_PLATFORM_INCDIR
QMAKE_LIBDIR = $$ANDROID_SOURCES_CXX_STL_LIBDIR $$QMAKE_ANDROID_PLATFORM_LIBDIR $$LIBGCC_PATH
QMAKE_INCDIR_X11 =
QMAKE_LIBDIR_X11 =
QMAKE_INCDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_INCDIR
QMAKE_LIBDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_LIBDIR
QMAKE_LINK = $$QMAKE_CXX
QMAKE_LINK_SHLIB = $$QMAKE_CXX
QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH
QMAKE_RPATHLINK = $$QMAKE_ANDROID_PLATFORM_LIBDIR
QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared
QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared
QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined
QMAKE_LFLAGS_RPATH = -Wl,-rpath=
QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link=
QMAKE_LIBS_PRIVATE = -lgnustl_shared -llog -lz -lm -ldl -lc -lgcc
QMAKE_LIBS_X11 =
QMAKE_LIBS_THREAD =
QMAKE_LIBS_EGL = -lEGL
QMAKE_LIBS_OPENGL =
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
!exists($$NDK_ROOT): error("You need to set the ANDROID_NDK_ROOT environment variable to point to your Android NDK.")
load(qt_config)
QMAKE_DEFAULT_LIBDIRS = $$QMAKE_LIBDIR
QMAKE_DEFAULT_INCDIRS = $$QMAKE_INCDIR
include(../common/android-base-tail.conf)

View File

@ -0,0 +1,78 @@
load(device_config)
NDK_ROOT = $$(ANDROID_NDK_ROOT)
!exists($$NDK_ROOT) {
NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT
}
NDK_HOST = $$(ANDROID_NDK_HOST)
isEmpty(NDK_HOST): NDK_HOST = $$DEFAULT_ANDROID_NDK_HOST
ANDROID_PLATFORM = $$(ANDROID_NDK_PLATFORM)
isEmpty(ANDROID_PLATFORM): ANDROID_PLATFORM = $$DEFAULT_ANDROID_PLATFORM
ANDROID_TARGET_ARCH = $$(ANDROID_TARGET_ARCH)
isEmpty(ANDROID_TARGET_ARCH): ANDROID_TARGET_ARCH = $$DEFAULT_ANDROID_TARGET_ARCH
NDK_TOOLCHAIN_PREFIX = $$(ANDROID_NDK_TOOLCHAIN_PREFIX)
isEmpty(NDK_TOOLCHAIN_PREFIX) {
equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLCHAIN_PREFIX = x86
else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLCHAIN_PREFIX = x86_64
else: equals(ANDROID_TARGET_ARCH, mips): NDK_TOOLCHAIN_PREFIX = mipsel-linux-android
else: equals(ANDROID_TARGET_ARCH, mips64): NDK_TOOLCHAIN_PREFIX = mips64el-linux-android
else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLCHAIN_PREFIX = aarch64-linux-android
else: NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi
}
NDK_TOOLS_PREFIX = $$(ANDROID_NDK_TOOLS_PREFIX)
isEmpty(NDK_TOOLS_PREFIX) {
equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLS_PREFIX = i686-linux-android
else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLS_PREFIX = x86_64-linux-android
else: equals(ANDROID_TARGET_ARCH, mips): NDK_TOOLS_PREFIX = mipsel-linux-android
else: equals(ANDROID_TARGET_ARCH, mips64): NDK_TOOLS_PREFIX = mips64el-linux-android
else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLS_PREFIX = aarch64-linux-android
else: NDK_TOOLS_PREFIX = arm-linux-androideabi
}
NDK_TOOLCHAIN_VERSION = $$(ANDROID_NDK_TOOLCHAIN_VERSION)
isEmpty(NDK_TOOLCHAIN_VERSION): NDK_TOOLCHAIN_VERSION = $$DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION
equals(ANDROID_TARGET_ARCH, x86): ANDROID_ARCHITECTURE = x86
else: equals(ANDROID_TARGET_ARCH, x86_64): ANDROID_ARCHITECTURE = x86_64
else: equals(ANDROID_TARGET_ARCH, mips): ANDROID_ARCHITECTURE = mips
else: equals(ANDROID_TARGET_ARCH, mips64): ANDROID_ARCHITECTURE = mips64
else: equals(ANDROID_TARGET_ARCH, arm64-v8a): ANDROID_ARCHITECTURE = arm64
else: ANDROID_ARCHITECTURE = arm
!equals(NDK_TOOLCHAIN_VERSION, 4.4.3): ANDROID_CXXSTL_SUFFIX = -$$NDK_TOOLCHAIN_VERSION
NDK_TOOLCHAIN = $$NDK_TOOLCHAIN_PREFIX-$$NDK_TOOLCHAIN_VERSION
NDK_TOOLCHAIN_PATH = $$NDK_ROOT/toolchains/$$NDK_TOOLCHAIN/prebuilt/$$NDK_HOST
ANDROID_SDK_ROOT = $$(ANDROID_SDK_ROOT)
isEmpty(ANDROID_SDK_ROOT): ANDROID_SDK_ROOT = $$DEFAULT_ANDROID_SDK_ROOT
ANDROID_SDK_BUILD_TOOLS_REVISION = $$(ANDROID_BUILD_TOOLS_REVISION)
isEmpty(ANDROID_SDK_BUILD_TOOLS_REVISION) {
SDK_BUILD_TOOLS_REVISIONS = $$files($$ANDROID_SDK_ROOT/build-tools/*)
for (REVISION, SDK_BUILD_TOOLS_REVISIONS) {
BASENAME = $$basename(REVISION)
greaterThan(BASENAME, $$ANDROID_SDK_BUILD_TOOLS_REVISION): ANDROID_SDK_BUILD_TOOLS_REVISION = $$BASENAME
}
}
CONFIG += $$ANDROID_PLATFORM
ANDROID_PLATFORM_ROOT_PATH = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/
ANDROID_PLATFORM_PATH = $$ANDROID_PLATFORM_ROOT_PATH/usr
# used to compile platform plugins for android-4 and android-5
QMAKE_ANDROID_PLATFORM_INCDIR = $$ANDROID_PLATFORM_PATH/include
QMAKE_ANDROID_PLATFORM_LIBDIR = $$ANDROID_PLATFORM_PATH/lib
ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/libs/$$ANDROID_TARGET_ARCH
ANDROID_SOURCES_CXX_STL_INCDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/include $$ANDROID_SOURCES_CXX_STL_LIBDIR/include
equals(ANDROID_TARGET_ARCH, x86_64)|equals(ANDROID_TARGET_ARCH, mips64): \
QMAKE_ANDROID_PLATFORM_LIBDIR = $${QMAKE_ANDROID_PLATFORM_LIBDIR}64

View File

@ -0,0 +1,105 @@
# -fstack-protector-strong offers good protection against stack smashing attacks.
# It is (currently) enabled only on Android because we know for sure that Andoroid compilers supports it
QMAKE_CFLAGS += -fstack-protector-strong -DANDROID
equals(ANDROID_TARGET_ARCH, armeabi-v7a): \
QMAKE_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -fno-builtin-memmove
else: equals(ANDROID_TARGET_ARCH, armeabi): \
QMAKE_CFLAGS += -march=armv5te -mtune=xscale -msoft-float -fno-builtin-memmove
# -fno-builtin-memmove is used to workaround https://code.google.com/p/android/issues/detail?id=81692
QMAKE_CFLAGS += --sysroot=$$ANDROID_PLATFORM_ROOT_PATH
QMAKE_CFLAGS_WARN_ON = -Wall -W
QMAKE_CFLAGS_WARN_OFF =
equals(ANDROID_TARGET_ARCH, armeabi-v7a) | equals(ANDROID_TARGET_ARCH, armeabi) {
QMAKE_CFLAGS_RELEASE = -Os
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -Os
QMAKE_CFLAGS_DEBUG = -g -marm -O0
equals(ANDROID_TARGET_ARCH, armeabi):if(equals(NDK_TOOLCHAIN_VERSION, 4.8)|equals(NDK_TOOLCHAIN_VERSION, 4.9)) {
DEFINES += QT_OS_ANDROID_GCC_48_WORKAROUND
} else {
QMAKE_CFLAGS_RELEASE += -mthumb
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb
}
# Don't override our options with -O3
QMAKE_CFLAGS_OPTIMIZE_FULL =
} else {
QMAKE_CFLAGS_RELEASE = -O2
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2
QMAKE_CFLAGS_DEBUG = -g
}
QMAKE_CFLAGS_SHLIB = -fPIC
QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
QMAKE_CFLAGS_THREAD = -D_REENTRANT
QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden
QMAKE_CFLAGS_NEON = -mfpu=neon
QMAKE_CXXFLAGS_CXX11 = -std=c++11
QMAKE_CXXFLAGS_CXX14 = -std=c++14
QMAKE_CXXFLAGS_CXX1Z = -std=c++1z
QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++11
QMAKE_CXXFLAGS_GNUCXX14 = -std=gnu++14
QMAKE_CXXFLAGS_GNUCXX1Z = -std=gnu++1z
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE
QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG
QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
# modifications to linux.conf
QMAKE_AR = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-ar cqs
QMAKE_OBJCOPY = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-objcopy
QMAKE_NM = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-nm -P
QMAKE_STRIP =
#$$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-strip
QMAKE_RANLIB = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-ranlib
equals(ANDROID_TARGET_ARCH, armeabi)|equals(ANDROID_TARGET_ARCH, armeabi-v7a): \
LIBGCC_PATH_FULL = $$system("$$QMAKE_GCC -mthumb-interwork -print-libgcc-file-name")
else: \
LIBGCC_PATH_FULL = $$system("$$QMAKE_GCC -print-libgcc-file-name")
LIBGCC_PATH = $$dirname(LIBGCC_PATH_FULL)
QMAKE_INCDIR = $$ANDROID_SOURCES_CXX_STL_INCDIR $$QMAKE_ANDROID_PLATFORM_INCDIR
QMAKE_LIBDIR = $$ANDROID_SOURCES_CXX_STL_LIBDIR $$QMAKE_ANDROID_PLATFORM_LIBDIR $$LIBGCC_PATH
QMAKE_INCDIR_X11 =
QMAKE_LIBDIR_X11 =
QMAKE_INCDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_INCDIR
QMAKE_LIBDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_LIBDIR
QMAKE_LINK = $$QMAKE_GCC
QMAKE_LINK_SHLIB = $$QMAKE_GCC
QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH
QMAKE_RPATHLINK = $$QMAKE_ANDROID_PLATFORM_LIBDIR
QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared
QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared
QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined
QMAKE_LFLAGS_RPATH = -Wl,-rpath=
QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link=
QMAKE_LIBS_PRIVATE = -lgnustl_shared -llog -lz -lm -ldl -lc -lgcc
QMAKE_LIBS_X11 =
QMAKE_LIBS_THREAD =
QMAKE_LIBS_EGL = -lEGL
QMAKE_LIBS_OPENGL =
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
!exists($$NDK_ROOT): error("You need to set the ANDROID_NDK_ROOT environment variable to point to your Android NDK.")
load(qt_config)
QMAKE_DEFAULT_LIBDIRS = $$QMAKE_LIBDIR
QMAKE_DEFAULT_INCDIRS = $$QMAKE_INCDIR

View File

@ -12,7 +12,7 @@ isEmpty(QMAKE_XCODE_DEVELOPER_PATH) {
error("Xcode is not installed in $${QMAKE_XCODE_DEVELOPER_PATH}. Please use xcode-select to choose Xcode installation path.")
# Make sure Xcode is set up properly
isEmpty($$list($$system("/usr/bin/xcrun -find xcrun 2>/dev/null"))): \
isEmpty($$list($$system("/usr/bin/xcrun -find xcodebuild 2>/dev/null"))): \
error("Xcode not set up properly. You may need to confirm the license agreement by running /usr/bin/xcodebuild.")
}

View File

@ -57,6 +57,8 @@
#include <utime.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#else
@ -1610,9 +1612,14 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
runProcess(&proc, args.at(0).toQString(m_tmp2));
return returnBool(proc.exitStatus() == QProcess::NormalExit && proc.exitCode() == 0);
#else
return returnBool(system((QLatin1String("cd ")
+ IoUtils::shellQuote(QDir::toNativeSeparators(currentDirectory()))
+ QLatin1String(" && ") + args.at(0)).toLocal8Bit().constData()) == 0);
int ec = system((QLatin1String("cd ")
+ IoUtils::shellQuote(QDir::toNativeSeparators(currentDirectory()))
+ QLatin1String(" && ") + args.at(0)).toLocal8Bit().constData());
# ifdef Q_OS_UNIX
if (ec != -1 && WIFSIGNALED(ec) && (WTERMSIG(ec) == SIGQUIT || WTERMSIG(ec) == SIGINT))
raise(WTERMSIG(ec));
# endif
return returnBool(ec == 0);
#endif
#else
return ReturnTrue;

View File

@ -23,7 +23,10 @@ win32: DEFINES += HB_NO_WIN1256
android: DEFINES += _POSIX_C_SOURCE=200112L
INCLUDEPATH += $$PWD/include
# Harfbuzz-NG inside Qt uses the Qt atomics (inline code only)
INCLUDEPATH += $$QT.core.includes
DEFINES += QT_NO_VERSION_TAGGING
SOURCES += \
$$PWD/src/hb-blob.cc \

View File

@ -921,7 +921,7 @@ static void shapedString(const HB_UChar16 *uc, hb_uint32 stringLength, hb_uint32
for (i = 0; i < len; i++) {
hb_uint8 r = *ch >> 8;
int gpos = data - shapeBuffer;
const int gpos = int(data - shapeBuffer);
if (r != 0x06) {
if (r == 0x20) {
@ -981,7 +981,7 @@ static void shapedString(const HB_UChar16 *uc, hb_uint32 stringLength, hb_uint32
/* qDebug("glyph %d (char %d) is mark!", gpos, i); */
} else {
attributes[gpos].mark = FALSE;
clusterStart = data - shapeBuffer;
clusterStart = int(data - shapeBuffer);
}
attributes[gpos].clusterStart = !attributes[gpos].mark;
attributes[gpos].combiningClass = HB_GetUnicodeCharCombiningClass(*ch);
@ -992,7 +992,7 @@ static void shapedString(const HB_UChar16 *uc, hb_uint32 stringLength, hb_uint32
ch++;
logClusters[i] = clusterStart;
}
*shapedLength = data - shapeBuffer;
*shapedLength = int(data - shapeBuffer);
HB_FREE_STACKARRAY(props);
}

View File

@ -94,7 +94,7 @@ static inline void positionCluster(HB_ShaperItem *item, int gfrom, int glast)
offsetBase = ((size * 10) - markTotalHeight) / 2; // Use offset that just fits
}
bool rightToLeft = item->item.bidiLevel % 2;
const bool rightToLeft = (item->item.bidiLevel % 2) != 0;
int i;
unsigned char lastCmb = 0;
@ -281,7 +281,7 @@ void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item)
// first char in a run is never (treated as) a mark
int cStart = 0;
const bool symbolFont = item->face->isSymbolFont;
const bool symbolFont = item->face->isSymbolFont != 0;
attributes[0].mark = false;
attributes[0].clusterStart = true;
attributes[0].dontPrint = (!symbolFont && uc[0] == 0x00ad) || HB_IsControlChar(uc[0]);

View File

@ -489,11 +489,19 @@ public class QtActivityDelegate
continue;
try {
@SuppressWarnings("rawtypes")
Class<?> initClass = classLoader.loadClass(className);
Object staticInitDataObject = initClass.newInstance(); // create an instance
Method m = initClass.getMethod("setActivity", Activity.class, Object.class);
m.invoke(staticInitDataObject, m_activity, this);
Class<?> initClass = classLoader.loadClass(className);
Object staticInitDataObject = initClass.newInstance(); // create an instance
try {
Method m = initClass.getMethod("setActivity", Activity.class, Object.class);
m.invoke(staticInitDataObject, m_activity, this);
} catch (Exception e) {
}
try {
Method m = initClass.getMethod("setContext", Context.class);
m.invoke(staticInitDataObject, (Context)m_activity);
} catch (Exception e) {
}
} catch (Exception e) {
e.printStackTrace();
}

View File

@ -120,12 +120,20 @@ public class QtServiceDelegate
for (String className: loaderParams.getStringArray(STATIC_INIT_CLASSES_KEY)) {
if (className.length() == 0)
continue;
try {
Class<?> initClass = classLoader.loadClass(className);
Object staticInitDataObject = initClass.newInstance(); // create an instance
Method m = initClass.getMethod("setService", Service.class, Object.class);
m.invoke(staticInitDataObject, m_service, this);
Class<?> initClass = classLoader.loadClass(className);
Object staticInitDataObject = initClass.newInstance(); // create an instance
try {
Method m = initClass.getMethod("setService", Service.class, Object.class);
m.invoke(staticInitDataObject, m_service, this);
} catch (Exception e) {
}
try {
Method m = initClass.getMethod("setContext", Context.class);
m.invoke(staticInitDataObject, (Context)m_service);
} catch (Exception e) {
}
} catch (Exception e) {
e.printStackTrace();
}

View File

@ -557,6 +557,12 @@
* Q_COMPILER_RESTRICTED_VLA variable-length arrays, prior to __cpp_runtime_arrays
*/
#ifdef __cplusplus
# if __cplusplus < 201103L && !(defined(Q_CC_MSVC) && Q_CC_MSVC >= 1800)
# error Qt requires a C++11 compiler and yours does not seem to be that.
# endif
#endif
#ifdef Q_CC_INTEL
# define Q_COMPILER_RESTRICTED_VLA
# define Q_COMPILER_VARIADIC_MACROS // C++11 feature supported as an extension in other modes, too
@ -1023,6 +1029,33 @@
// critical definitions. (Reported as Intel Issue ID 6000117277)
# define __USE_CONSTEXPR 1
# define __USE_NOEXCEPT 1
# elif defined(Q_CC_MSVC) && (defined(Q_CC_CLANG) || defined(Q_CC_INTEL))
// Clang and the Intel compiler support more C++ features than the Microsoft compiler
// so make sure we don't enable them if the MS headers aren't properly adapted.
# ifndef _HAS_CONSTEXPR
# undef Q_COMPILER_CONSTEXPR
# endif
# ifndef _HAS_DECLTYPE
# undef Q_COMPILER_DECLTYPE
# endif
# ifndef _HAS_INITIALIZER_LISTS
# undef Q_COMPILER_INITIALIZER_LISTS
# endif
# ifndef _HAS_NULLPTR_T
# undef Q_COMPILER_NULLPTR
# endif
# ifndef _HAS_RVALUE_REFERENCES
# undef Q_COMPILER_RVALUE_REFS
# endif
# ifndef _HAS_SCOPED_ENUM
# undef Q_COMPILER_CLASS_ENUM
# endif
# ifndef _HAS_TEMPLATE_ALIAS
# undef Q_COMPILER_TEMPLATE_ALIAS
# endif
# ifndef _HAS_VARIADIC_TEMPLATES
# undef Q_COMPILER_VARIADIC_TEMPLATES
# endif
# elif defined(_LIBCPP_VERSION)
// libc++ uses __has_feature(cxx_atomic), so disable the feature if the compiler
// doesn't support it. That's required for the Intel compiler 14.x or earlier on OS X, for example.

View File

@ -63,6 +63,9 @@ template <class Key, class T> class QMap;
#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED)
class QDataStreamPrivate;
namespace QtPrivate {
class StreamStateSaver;
}
class Q_CORE_EXPORT QDataStream
{
public:
@ -193,6 +196,7 @@ private:
Status q_status;
int readBlock(char *data, int len);
friend class QtPrivate::StreamStateSaver;
};
namespace QtPrivate {
@ -202,7 +206,8 @@ class StreamStateSaver
public:
inline StreamStateSaver(QDataStream *s) : stream(s), oldStatus(s->status())
{
stream->resetStatus();
if (!stream->dev || !stream->dev->isTransactionStarted())
stream->resetStatus();
}
inline ~StreamStateSaver()
{

View File

@ -378,15 +378,13 @@ qint64 QFSFileEnginePrivate::nativeWrite(const char *data, qint64 len)
if (fileHandle == INVALID_HANDLE_VALUE)
return -1;
qint64 bytesToWrite = DWORD(len); // <- lossy
qint64 bytesToWrite = len;
// Writing on Windows fails with ERROR_NO_SYSTEM_RESOURCES when
// the chunks are too large, so we limit the block size to 32MB.
static const DWORD maxBlockSize = 32 * 1024 * 1024;
const DWORD blockSize = DWORD(qMin(bytesToWrite, qint64(32 * 1024 * 1024)));
qint64 totalWritten = 0;
do {
DWORD blockSize = qMin<DWORD>(bytesToWrite, maxBlockSize);
DWORD bytesWritten;
if (!WriteFile(fileHandle, data + totalWritten, blockSize, &bytesWritten, NULL)) {
if (totalWritten == 0) {

View File

@ -51,8 +51,12 @@
#include "qcoreapplication.h"
#endif
#if !defined(Q_OS_QNX) && !defined(Q_OS_WIN) && !defined(Q_OS_ANDROID) && !defined(Q_OS_INTEGRITY)
# define USE_SYSTEM_MKDTEMP
#endif
#include <stdlib.h> // mkdtemp
#if defined(Q_OS_QNX) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID) || defined(Q_OS_INTEGRITY)
#ifndef USE_SYSTEM_MKDTEMP
#include <private/qfilesystemengine_p.h>
#endif
@ -98,8 +102,7 @@ static QString defaultTemplateName()
return QDir::tempPath() + QLatin1Char('/') + baseName + QLatin1String("-XXXXXX");
}
#if defined(Q_OS_QNX ) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID) || defined(Q_OS_INTEGRITY)
#ifndef USE_SYSTEM_MKDTEMP
static int nextRand(int &v)
{
int r = v % 62;
@ -109,30 +112,28 @@ static int nextRand(int &v)
return r;
}
QPair<QString, bool> q_mkdtemp(char *templateName)
QPair<QString, bool> q_mkdtemp(QString templateName)
{
Q_ASSERT(templateName.endsWith(QLatin1String("XXXXXX")));
static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
const size_t length = strlen(templateName);
const int length = templateName.size();
char *XXXXXX = templateName + length - 6;
Q_ASSERT((length >= 6u) && strncmp(XXXXXX, "XXXXXX", 6) == 0);
QChar *XXXXXX = templateName.data() + length - 6;
for (int i = 0; i < 256; ++i) {
int v = qrand();
/* Fill in the random bits. */
XXXXXX[0] = letters[nextRand(v)];
XXXXXX[1] = letters[nextRand(v)];
XXXXXX[2] = letters[nextRand(v)];
XXXXXX[3] = letters[nextRand(v)];
XXXXXX[4] = letters[nextRand(v)];
XXXXXX[5] = letters[v % 62];
XXXXXX[0] = QLatin1Char(letters[nextRand(v)]);
XXXXXX[1] = QLatin1Char(letters[nextRand(v)]);
XXXXXX[2] = QLatin1Char(letters[nextRand(v)]);
XXXXXX[3] = QLatin1Char(letters[nextRand(v)]);
XXXXXX[4] = QLatin1Char(letters[nextRand(v)]);
XXXXXX[5] = QLatin1Char(letters[v % 62]);
QString templateNameStr = QFile::decodeName(templateName);
QFileSystemEntry fileSystemEntry(templateNameStr);
QFileSystemEntry fileSystemEntry(templateName);
if (QFileSystemEngine::createDirectory(fileSystemEntry, false)) {
QSystemError error;
QFileSystemEngine::setPermissions(fileSystemEntry,
@ -141,10 +142,10 @@ QPair<QString, bool> q_mkdtemp(char *templateName)
QFile::ExeOwner, error);
if (error.error() != 0) {
if (!QFileSystemEngine::removeDirectory(fileSystemEntry, false))
qWarning() << "Unable to remove unused directory" << templateNameStr;
qWarning() << "Unable to remove unused directory" << templateName;
continue;
}
return qMakePair(QFile::decodeName(templateName), true);
return qMakePair(templateName, true);
}
# ifdef Q_OS_WIN
const int exists = ERROR_ALREADY_EXISTS;
@ -159,7 +160,7 @@ QPair<QString, bool> q_mkdtemp(char *templateName)
return qMakePair(qt_error_string(), false);
}
#else // defined(Q_OS_QNX ) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID)
#else // !USE_SYSTEM_MKDTEMP
QPair<QString, bool> q_mkdtemp(char *templateName)
{
@ -167,14 +168,21 @@ QPair<QString, bool> q_mkdtemp(char *templateName)
return qMakePair(ok ? QFile::decodeName(templateName) : qt_error_string(), ok);
}
#endif
#endif // USE_SYSTEM_MKDTEMP
void QTemporaryDirPrivate::create(const QString &templateName)
{
#ifndef USE_SYSTEM_MKDTEMP
QString buffer = templateName;
if (!buffer.endsWith(QLatin1String("XXXXXX")))
buffer += QLatin1String("XXXXXX");
const QPair<QString, bool> result = q_mkdtemp(buffer);
#else // !USE_SYSTEM_MKDTEMP
QByteArray buffer = QFile::encodeName(templateName);
if (!buffer.endsWith("XXXXXX"))
buffer += "XXXXXX";
QPair<QString, bool> result = q_mkdtemp(buffer.data()); // modifies buffer
#endif // USE_SYSTEM_MKDTEMP
pathOrError = result.first;
success = result.second;
}

View File

@ -421,7 +421,12 @@ void QEventDispatcherUNIX::unregisterSocketNotifier(QSocketNotifier *notifier)
QSocketNotifier::Type type = notifier->type();
#ifndef QT_NO_DEBUG
if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread");
qWarning("QSocketNotifier: socket notifier (fd %d) cannot be disabled from another thread.\n"
"(Notifier's thread is %s(%p), event dispatcher's thread is %s(%p), current thread is %s(%p))",
sockfd,
notifier->thread() ? notifier->thread()->metaObject()->className() : "QThread", notifier->thread(),
thread() ? thread()->metaObject()->className() : "QThread", thread(),
QThread::currentThread() ? QThread::currentThread()->metaObject()->className() : "QThread", QThread::currentThread());
return;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -44,6 +44,11 @@ Q_CORE_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
Q_UNUSED(reserved)
static bool initialized = false;
if (initialized)
return JNI_VERSION_1_6;
initialized = true;
typedef union {
JNIEnv *nenv;
void *venv;

View File

@ -3693,7 +3693,6 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
continue;
#ifndef QT_NO_THREAD
} else if (c->connectionType == Qt::BlockingQueuedConnection) {
locker.unlock();
if (receiverInSameThread) {
qWarning("Qt: Dead lock detected while activating a BlockingQueuedConnection: "
"Sender is %s(%p), receiver is %s(%p)",
@ -3705,6 +3704,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
new QMetaCallEvent(c->slotObj, sender, signal_index, 0, 0, argv ? argv : empty_argv, &semaphore) :
new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal_index, 0, 0, argv ? argv : empty_argv, &semaphore);
QCoreApplication::postEvent(receiver, ev);
locker.unlock();
semaphore.acquire();
locker.relock();
continue;
@ -4272,7 +4272,7 @@ QDebug operator<<(QDebug dbg, const QObject *o)
\relates QObject
\since 5.5
This macro registers a single \l{QFlags}{flags types} with the
This macro registers a single \l{QFlags}{flags type} with the
meta-object system. It is typically used in a class definition to declare
that values of a given enum can be used as flags and combined using the
bitwise OR operator.

View File

@ -180,6 +180,8 @@ inline void qYouForgotTheQ_OBJECT_Macro(T1, T2) {}
#if defined(Q_CC_CLANG) && Q_CC_CLANG >= 306
# define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_CLANG("-Winconsistent-missing-override")
#elif defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 510
# define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_GCC("-Wsuggest-override")
#else
# define Q_OBJECT_NO_OVERRIDE_WARNING
#endif

View File

@ -536,8 +536,13 @@ bool QLibraryPrivate::load()
return false;
bool ret = load_sys();
if (qt_debug_component())
qDebug() << "loaded library" << fileName;
if (qt_debug_component()) {
if (ret) {
qDebug() << "loaded library" << fileName;
} else {
qDebug() << qUtf8Printable(errorString);
}
}
if (ret) {
//when loading a library we add a reference to it so that the QLibraryPrivate won't get deleted
//this allows to unload the library at a later time

View File

@ -123,8 +123,8 @@ QT_DEPRECATED inline bool setYMD(int y, int m, int d)
static bool isValid(int y, int m, int d);
static bool isLeapYear(int year);
static Q_DECL_CONSTEXPR inline QDate fromJulianDay(qint64 jd)
{ return jd >= minJd() && jd <= maxJd() ? QDate(jd) : QDate() ; }
static Q_DECL_CONSTEXPR inline QDate fromJulianDay(qint64 jd_)
{ return jd_ >= minJd() && jd_ <= maxJd() ? QDate(jd_) : QDate() ; }
Q_DECL_CONSTEXPR inline qint64 toJulianDay() const { return jd; }
private:

View File

@ -499,14 +499,14 @@ private:
void deref() Q_DECL_NOTHROW
{ deref(d); }
static void deref(Data *d) Q_DECL_NOTHROW
static void deref(Data *dd) Q_DECL_NOTHROW
{
if (!d) return;
if (!d->strongref.deref()) {
d->destroy();
if (!dd) return;
if (!dd->strongref.deref()) {
dd->destroy();
}
if (!d->weakref.deref())
delete d;
if (!dd->weakref.deref())
delete dd;
}
template <class X>

View File

@ -656,10 +656,11 @@ QTimeZonePrivate *QUtcTimeZonePrivate::clone()
QTimeZonePrivate::Data QUtcTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
{
Data d = invalidData();
Data d;
d.abbreviation = m_abbreviation;
d.atMSecsSinceEpoch = forMSecsSinceEpoch;
d.offsetFromUtc = m_offsetFromUtc;
d.standardTimeOffset = d.offsetFromUtc = m_offsetFromUtc;
d.daylightTimeOffset = 0;
return d;
}

View File

@ -907,7 +907,7 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
{
// If the required time is after the last transition and we have a POSIX rule then use it
if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch
&&!m_posixRule.isEmpty() && forMSecsSinceEpoch >= 0) {
&& !m_posixRule.isEmpty() && forMSecsSinceEpoch >= 0) {
const int year = QDateTime::fromMSecsSinceEpoch(forMSecsSinceEpoch, Qt::UTC).date().year();
const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0;
QVector<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1,
@ -951,7 +951,7 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSince
{
// If the required time is after the last transition and we have a POSIX rule then use it
if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < afterMSecsSinceEpoch
&&!m_posixRule.isEmpty() && afterMSecsSinceEpoch >= 0) {
&& !m_posixRule.isEmpty() && afterMSecsSinceEpoch >= 0) {
const int year = QDateTime::fromMSecsSinceEpoch(afterMSecsSinceEpoch, Qt::UTC).date().year();
const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0;
QVector<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1,
@ -977,7 +977,7 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecs
{
// If the required time is after the last transition and we have a POSIX rule then use it
if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < beforeMSecsSinceEpoch
&&!m_posixRule.isEmpty() && beforeMSecsSinceEpoch > 0) {
&& !m_posixRule.isEmpty() && beforeMSecsSinceEpoch > 0) {
const int year = QDateTime::fromMSecsSinceEpoch(beforeMSecsSinceEpoch, Qt::UTC).date().year();
const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0;
QVector<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1,

View File

@ -397,7 +397,11 @@ void QVector<T>::reserve(int asize)
{
if (asize > int(d->alloc))
reallocData(d->size, asize);
if (isDetached())
if (isDetached()
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
&& d != Data::unsharableEmpty()
#endif
)
d->capacityReserved = 1;
Q_ASSERT(capacity() >= asize);
}

View File

@ -1181,6 +1181,10 @@ inline int QXmlStreamReaderPrivate::fastScanLiteralContent()
}
// fall through
default:
if (c < 0x20) {
putChar(c);
return n;
}
textBuffer += QChar(c);
++n;
}

View File

@ -840,17 +840,6 @@ QImageData *QImageData::create(uchar *data, int width, int height, int bpl, QIm
d->cleanupFunction = cleanupFunction;
d->cleanupInfo = cleanupInfo;
switch (format) {
case QImage::Format_Mono:
case QImage::Format_MonoLSB:
d->colortable.resize(2);
d->colortable[0] = QColor(Qt::black).rgba();
d->colortable[1] = QColor(Qt::white).rgba();
break;
default:
break;
}
return d;
}
@ -2249,21 +2238,30 @@ QRgb QImage::pixel(int x, int y) const
}
const uchar *s = d->data + y * d->bytes_per_line;
switch(d->format) {
int index = -1;
switch (d->format) {
case Format_Mono:
return d->colortable.at((*(s + (x >> 3)) >> (~x & 7)) & 1);
index = (*(s + (x >> 3)) >> (~x & 7)) & 1;
break;
case Format_MonoLSB:
return d->colortable.at((*(s + (x >> 3)) >> (x & 7)) & 1);
index = (*(s + (x >> 3)) >> (x & 7)) & 1;
break;
case Format_Indexed8:
{
int index = (int)s[x];
if (index < d->colortable.size()) {
return d->colortable.at(index);
} else {
qWarning("QImage::pixel: color table index %d out of range.", index);
return 0;
}
index = s[x];
break;
default:
break;
}
if (index >= 0) { // Indexed format
if (index >= d->colortable.size()) {
qWarning("QImage::pixel: color table index %d out of range.", index);
return 0;
}
return d->colortable.at(index);
}
switch (d->format) {
case Format_RGB32:
return 0xff000000 | reinterpret_cast<const QRgb *>(s)[x];
case Format_ARGB32: // Keep old behaviour.
@ -4250,6 +4248,8 @@ void QImage::setAlphaChannel(const QImage &alphaChannel)
} else {
const QImage sourceImage = alphaChannel.convertToFormat(QImage::Format_RGB32);
if (sourceImage.isNull())
return;
const uchar *src_data = sourceImage.d->data;
uchar *dest_data = d->data;
for (int y=0; y<h; ++y) {

View File

@ -1410,10 +1410,8 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode)
QPixmap using the fromImage(). If this is too expensive an
operation, you can use QBitmap::fromImage() instead.
The QPixmap class also supports conversion to and from HICON:
the toWinHICON() function creates a HICON equivalent to the
QPixmap, and returns the HICON handle. The fromWinHICON()
function returns a QPixmap that is equivalent to the given icon.
To convert a QPixmap to and from HICON you can use the QtWinExtras
functions QtWin::toHICON() and QtWin::fromHICON() respectively.
\section1 Pixmap Transformations

View File

@ -537,8 +537,8 @@ public:
};
class Attribute {
public:
Attribute(AttributeType t, int s, int l, QVariant val) : type(t), start(s), length(l), value(qMove(val)) {}
Attribute(AttributeType t, int s, int l) : type(t), start(s), length(l), value() {}
Attribute(AttributeType typ, int s, int l, QVariant val) : type(typ), start(s), length(l), value(qMove(val)) {}
Attribute(AttributeType typ, int s, int l) : type(typ), start(s), length(l), value() {}
AttributeType type;
int start;

View File

@ -581,6 +581,20 @@ void QPlatformWindow::invalidateSurface()
{
}
static QSize fixInitialSize(QSize size, const QWindow *w,
int defaultWidth, int defaultHeight)
{
if (size.width() == 0) {
const int minWidth = w->minimumWidth();
size.setWidth(minWidth > 0 ? minWidth : defaultWidth);
}
if (size.height() == 0) {
const int minHeight = w->minimumHeight();
size.setHeight(minHeight > 0 ? minHeight : defaultHeight);
}
return size;
}
/*!
Helper function to get initial geometry on windowing systems which do not
do smart positioning and also do not provide a means of centering a
@ -593,19 +607,18 @@ void QPlatformWindow::invalidateSurface()
QRect QPlatformWindow::initialGeometry(const QWindow *w,
const QRect &initialGeometry, int defaultWidth, int defaultHeight)
{
if (!w->isTopLevel()) {
const qreal factor = QHighDpiScaling::factor(w);
const QSize size = fixInitialSize(QHighDpi::fromNative(initialGeometry.size(), factor),
w, defaultWidth, defaultHeight);
return QRect(initialGeometry.topLeft(), QHighDpi::toNative(size, factor));
}
const QScreen *screen = effectiveScreen(w);
if (!screen)
return initialGeometry;
QRect rect(QHighDpi::fromNativePixels(initialGeometry, w));
if (rect.width() == 0) {
const int minWidth = w->minimumWidth();
rect.setWidth(minWidth > 0 ? minWidth : defaultWidth);
}
if (rect.height() == 0) {
const int minHeight = w->minimumHeight();
rect.setHeight(minHeight > 0 ? minHeight : defaultHeight);
}
if (w->isTopLevel() && qt_window_private(const_cast<QWindow*>(w))->positionAutomatic
rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight));
if (qt_window_private(const_cast<QWindow*>(w))->positionAutomatic
&& w->type() != Qt::Popup) {
const QRect availableGeometry = screen->availableGeometry();
// Center unless the geometry ( + unknown window frame) is too large for the screen).

View File

@ -402,7 +402,7 @@ void QWindowPrivate::create(bool recursive)
q->parent()->create();
platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q);
Q_ASSERT(platformWindow);
Q_ASSERT(platformWindow || q->type() == Qt::ForeignWindow);
if (!platformWindow) {
qWarning() << "Failed to create platform window for" << q << "with flags" << q->flags();
@ -2432,7 +2432,8 @@ QWindow *QWindowPrivate::topLevelWindow() const
This can be used, on platforms which support it, to embed a QWindow inside a
native window, or to embed a native window inside a QWindow.
If foreign windows are not supported, this function returns 0.
If foreign windows are not supported or embedding the native window
failed in the platform plugin, this function returns 0.
\note The resulting QWindow should not be used to manipulate the underlying
native window (besides re-parenting), or to observe state changes of the
@ -2453,6 +2454,10 @@ QWindow *QWindow::fromWinId(WId id)
window->setFlags(Qt::ForeignWindow);
window->setProperty("_q_foreignWinId", QVariant::fromValue(id));
window->create();
if (!window->handle()) {
delete window;
return nullptr;
}
return window;
}

View File

@ -42,6 +42,7 @@
#include <QtCore/qvarlengtharray.h>
#include <QtGui/qopengl.h>
#include <QtGui/qopenglfunctions.h>
#include <QtGui/qoffscreensurface.h>
#include "qopengldebug.h"
@ -1287,8 +1288,41 @@ void QOpenGLDebugLoggerPrivate::controlDebugMessages(QOpenGLDebugMessage::Source
*/
void QOpenGLDebugLoggerPrivate::_q_contextAboutToBeDestroyed()
{
Q_ASSERT(context);
// Re-make our context current somehow, otherwise stopLogging will fail.
// Save the current context and its surface in case we need to set them back
QOpenGLContext *currentContext = QOpenGLContext::currentContext();
QSurface *currentSurface = 0;
QScopedPointer<QOffscreenSurface> offscreenSurface;
if (context != currentContext) {
// Make our old context current on a temporary surface
if (currentContext)
currentSurface = currentContext->surface();
offscreenSurface.reset(new QOffscreenSurface);
offscreenSurface->setFormat(context->format());
offscreenSurface->create();
if (!context->makeCurrent(offscreenSurface.data()))
qWarning("QOpenGLDebugLoggerPrivate::_q_contextAboutToBeDestroyed(): could not make the owning GL context current for cleanup");
}
Q_Q(QOpenGLDebugLogger);
q->stopLogging();
if (offscreenSurface) {
// We did change the current context: set it back
if (currentContext)
currentContext->makeCurrent(currentSurface);
else
context->doneCurrent();
}
QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
context = 0;
initialized = false;
}
@ -1494,6 +1528,12 @@ void QOpenGLDebugLogger::stopLogging()
if (!d->isLogging)
return;
QOpenGLContext *currentContext = QOpenGLContext::currentContext();
if (!currentContext || currentContext != d->context) {
qWarning("QOpenGLDebugLogger::stopLogging(): attempting to stop logging with the wrong OpenGL context current");
return;
}
d->isLogging = false;
d->glDebugMessageCallback(d->oldDebugCallbackFunction, d->oldDebugCallbackParameter);

View File

@ -76,6 +76,14 @@ QT_BEGIN_NAMESPACE
#define GL_TEXTURE_COMPARE_FUNC 0x884D
#endif
// use GL_APICALL only on Android + __clang__
#if !defined(Q_OS_ANDROID) || !defined(__clang__)
# undef GL_APICALL
# define GL_APICALL
#elif !defined(GL_APICALL)
# define GL_APICALL
#endif
class QOpenGLContext;
class QOpenGLTextureHelper
@ -754,15 +762,15 @@ private:
// OpenGL 1.3
void (QOPENGLF_APIENTRYP GetCompressedTexImage)(GLenum target, GLint level, GLvoid *img);
void (QOPENGLF_APIENTRYP CompressedTexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
void (QOPENGLF_APIENTRYP CompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
GL_APICALL void (QOPENGLF_APIENTRYP CompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
void (QOPENGLF_APIENTRYP CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
void (QOPENGLF_APIENTRYP CompressedTexImage1D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
void (QOPENGLF_APIENTRYP CompressedTexImage2D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
GL_APICALL void (QOPENGLF_APIENTRYP CompressedTexImage2D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
void (QOPENGLF_APIENTRYP CompressedTexImage3D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
void (QOPENGLF_APIENTRYP ActiveTexture)(GLenum texture);
GL_APICALL void (QOPENGLF_APIENTRYP ActiveTexture)(GLenum texture);
// OpenGL 3.0
void (QOPENGLF_APIENTRYP GenerateMipmap)(GLenum target);
GL_APICALL void (QOPENGLF_APIENTRYP GenerateMipmap)(GLenum target);
// OpenGL 3.2
void (QOPENGLF_APIENTRYP TexImage3DMultisample)(GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);

View File

@ -358,9 +358,11 @@ QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject()
Q_D(QOpenGLVertexArrayObject);
QOpenGLContext *oldContext = 0;
QSurface *oldContextSurface = 0;
QScopedPointer<QOffscreenSurface> offscreenSurface;
if (d->context && ctx && d->context != ctx) {
oldContext = ctx;
oldContextSurface = ctx->surface();
// Cannot just make the current surface current again with another context.
// The format may be incompatible and some platforms (iOS) may impose
// restrictions on using a window with different contexts. Create an
@ -380,7 +382,7 @@ QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject()
destroy();
if (oldContext) {
if (!oldContext->makeCurrent(oldContext->surface()))
if (!oldContext->makeCurrent(oldContextSurface))
qWarning("QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject() failed to restore current context");
}
}

View File

@ -236,11 +236,16 @@ QSize QBackingStore::size() const
*/
bool QBackingStore::scroll(const QRegion &area, int dx, int dy)
{
Q_UNUSED(area);
Q_UNUSED(dx);
Q_UNUSED(dy);
// Disable scrolling for non-integer scroll deltas. For this case
// the the existing rendered pixels can't be re-used, and we return
// false to signal that a repaint is needed.
const qreal nativeDx = QHighDpi::toNativePixels(qreal(dx), d_ptr->window);
const qreal nativeDy = QHighDpi::toNativePixels(qreal(dy), d_ptr->window);
if (qFloor(nativeDx) != nativeDx || qFloor(nativeDy) != nativeDy)
return false;
return d_ptr->platformBackingStore->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window), QHighDpi::toNativePixels(dx, d_ptr->window), QHighDpi::toNativePixels(dy, d_ptr->window));
return d_ptr->platformBackingStore->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window),
nativeDx, nativeDy);
}
/*!

View File

@ -76,7 +76,9 @@
QT_BEGIN_NAMESPACE
#ifndef QFONTCACHE_DECREASE_TRIGGER_LIMIT
# define QFONTCACHE_DECREASE_TRIGGER_LIMIT 256
#endif
bool QFontDef::exactMatch(const QFontDef &other) const
{
@ -2800,7 +2802,7 @@ void QFontCache::insertEngineData(const QFontDef &def, QFontEngineData *engineDa
engineData->ref.ref();
// Decrease now rather than waiting
if (total_cost > min_cost * 2)
if (total_cost > min_cost * 2 && engineDataCache.size() >= QFONTCACHE_DECREASE_TRIGGER_LIMIT)
decreaseCache();
engineDataCache.insert(def, engineData);
@ -2849,7 +2851,7 @@ void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMu
#endif
engine->ref.ref();
// Decrease now rather than waiting
if (total_cost > min_cost * 2)
if (total_cost > min_cost * 2 && engineCache.size() >= QFONTCACHE_DECREASE_TRIGGER_LIMIT)
decreaseCache();
Engine data(engine);

View File

@ -1849,7 +1849,10 @@ static inline QImage alphaMapFromGlyphData(QFontEngineFT::Glyph *glyph, QFontEng
Q_UNREACHABLE();
};
return QImage(static_cast<const uchar *>(glyph->data), glyph->width, glyph->height, bytesPerLine, format);
QImage img(static_cast<const uchar *>(glyph->data), glyph->width, glyph->height, bytesPerLine, format);
if (format == QImage::Format_Mono)
img.setColor(1, QColor(Qt::white).rgba()); // Expands color table to 2 items; item 0 set to transparent.
return img;
}
QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixelPosition,

View File

@ -2657,9 +2657,8 @@ void QAbstractSocket::setPeerName(const QString &name)
}
/*!
Closes the I/O device for the socket, disconnects the socket's connection with the
host, closes the socket, and resets the name, address, port number and underlying
socket descriptor.
Closes the I/O device for the socket and calls disconnectFromHost()
to close the socket's connection.
See QIODevice::close() for a description of the actions that occur when an I/O
device is closed.
@ -2675,13 +2674,6 @@ void QAbstractSocket::close()
QIODevice::close();
if (d->state != UnconnectedState)
disconnectFromHost();
d->localPort = 0;
d->peerPort = 0;
d->localAddress.clear();
d->peerAddress.clear();
d->peerName.clear();
d->cachedSocketDescriptor = -1;
}
/*!
@ -2784,6 +2776,7 @@ void QAbstractSocket::disconnectFromHost()
d->peerPort = 0;
d->localAddress.clear();
d->peerAddress.clear();
d->peerName.clear();
d->setWriteChannelCount(0);
#if defined(QABSTRACTSOCKET_DEBUG)

View File

@ -116,14 +116,16 @@ QFbVtHandler::QFbVtHandler(QObject *parent)
m_signalNotifier = new QSocketNotifier(m_sigFd[1], QSocketNotifier::Read, this);
connect(m_signalNotifier, &QSocketNotifier::activated, this, &QFbVtHandler::handleSignal);
struct sigaction sa;
sa.sa_flags = 0;
sa.sa_handler = signalHandler;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, 0); // Ctrl+C
sigaction(SIGTSTP, &sa, 0); // Ctrl+Z
sigaction(SIGCONT, &sa, 0);
sigaction(SIGTERM, &sa, 0); // default signal used by kill
if (!qEnvironmentVariableIntValue("QT_QPA_NO_SIGNAL_HANDLER")) {
struct sigaction sa;
sa.sa_flags = 0;
sa.sa_handler = signalHandler;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, 0); // Ctrl+C
sigaction(SIGTSTP, &sa, 0); // Ctrl+Z
sigaction(SIGCONT, &sa, 0);
sigaction(SIGTERM, &sa, 0); // default signal used by kill
}
#endif
}

View File

@ -91,7 +91,7 @@ void QConnmanEngine::initialize()
this, SLOT(updateServices(ConnmanMapList,QList<QDBusObjectPath>)));
connect(connmanManager,SIGNAL(servicesReady(QStringList)),this,SLOT(servicesReady(QStringList)));
connect(connmanManager,SIGNAL(scanFinished()),this,SLOT(finishedScan()));
connect(connmanManager,SIGNAL(scanFinished(bool)),this,SLOT(finishedScan(bool)));
foreach (const QString &servPath, connmanManager->getServices()) {
addServiceConfiguration(servPath);
@ -203,11 +203,15 @@ void QConnmanEngine::requestUpdate()
void QConnmanEngine::doRequestUpdate()
{
connmanManager->requestScan("wifi");
bool scanned = connmanManager->requestScan("wifi");
if (!scanned)
Q_EMIT updateCompleted();
}
void QConnmanEngine::finishedScan()
void QConnmanEngine::finishedScan(bool error)
{
if (error)
Q_EMIT updateCompleted();
}
void QConnmanEngine::updateServices(const ConnmanMapList &changed, const QList<QDBusObjectPath> &removed)

View File

@ -100,7 +100,7 @@ private Q_SLOTS:
void updateServices(const ConnmanMapList &changed, const QList<QDBusObjectPath> &removed);
void servicesReady(const QStringList &);
void finishedScan();
void finishedScan(bool error);
void changedModem();
void serviceStateChanged(const QString &state);
void configurationChange(QConnmanServiceInterface * service);

View File

@ -249,13 +249,16 @@ QStringList QConnmanManagerInterface::getServices()
return servicesList;
}
void QConnmanManagerInterface::requestScan(const QString &type)
bool QConnmanManagerInterface::requestScan(const QString &type)
{
bool scanned = false;
Q_FOREACH (QConnmanTechnologyInterface *tech, technologiesMap) {
if (tech->type() == type) {
tech->scan();
scanned = true;
}
}
return scanned;
}
void QConnmanManagerInterface::technologyAdded(const QDBusObjectPath &path, const QVariantMap &)
@ -265,7 +268,7 @@ void QConnmanManagerInterface::technologyAdded(const QDBusObjectPath &path, cons
QConnmanTechnologyInterface *tech;
tech = new QConnmanTechnologyInterface(path.path(),this);
technologiesMap.insert(path.path(),tech);
connect(tech,SIGNAL(scanFinished()),this,SIGNAL(scanFinished()));
connect(tech,SIGNAL(scanFinished(bool)),this,SIGNAL(scanFinished(bool)));
}
}
@ -501,7 +504,11 @@ void QConnmanTechnologyInterface::scan()
void QConnmanTechnologyInterface::scanReply(QDBusPendingCallWatcher *call)
{
Q_EMIT scanFinished();
QDBusPendingReply<QVariantMap> props_reply = *call;
if (props_reply.isError()) {
qDebug() << props_reply.error().message();
}
Q_EMIT scanFinished(props_reply.isError());
call->deleteLater();
}

View File

@ -115,7 +115,7 @@ public:
bool getOfflineMode();
QStringList getTechnologies();
QStringList getServices();
void requestScan(const QString &type);
bool requestScan(const QString &type);
QHash<QString, QConnmanTechnologyInterface *> technologiesMap;
@ -126,7 +126,7 @@ Q_SIGNALS:
void servicesChanged(const ConnmanMapList&, const QList<QDBusObjectPath> &);
void servicesReady(const QStringList &);
void scanFinished();
void scanFinished(bool error);
protected:
void connectNotify(const QMetaMethod &signal);
@ -211,7 +211,7 @@ public:
Q_SIGNALS:
void propertyChanged(const QString &, const QDBusVariant &value);
void propertyChangedContext(const QString &,const QString &,const QDBusVariant &);
void scanFinished();
void scanFinished(bool error);
protected:
void connectNotify(const QMetaMethod &signal);
QVariant getProperty(const QString &);

View File

@ -840,6 +840,11 @@ QT_END_NAMESPACE
Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
{
static bool initialized = false;
if (initialized)
return JNI_VERSION_1_6;
initialized = true;
QT_USE_NAMESPACE
typedef union {
JNIEnv *nativeEnvironment;

View File

@ -75,6 +75,7 @@ private:
uchar mime_type;
mutable QPointer<QMimeData> mime;
mutable bool mac_mime_source;
bool resolvingBeforeDestruction;
static OSStatus promiseKeeper(PasteboardRef, PasteboardItemID, CFStringRef, void *);
void clear_helper();
public:

View File

@ -87,6 +87,7 @@ QMacPasteboard::QMacPasteboard(PasteboardRef p, uchar mt)
mime_type = mt ? mt : uchar(QMacInternalPasteboardMime::MIME_ALL);
paste = p;
CFRetain(paste);
resolvingBeforeDestruction = false;
}
QMacPasteboard::QMacPasteboard(uchar mt)
@ -100,6 +101,7 @@ QMacPasteboard::QMacPasteboard(uchar mt)
} else {
qDebug("PasteBoard: Error creating pasteboard: [%d]", (int)err);
}
resolvingBeforeDestruction = false;
}
QMacPasteboard::QMacPasteboard(CFStringRef name, uchar mt)
@ -113,23 +115,14 @@ QMacPasteboard::QMacPasteboard(CFStringRef name, uchar mt)
} else {
qDebug("PasteBoard: Error creating pasteboard: %s [%d]", QCFString::toQString(name).toLatin1().constData(), (int)err);
}
resolvingBeforeDestruction = false;
}
QMacPasteboard::~QMacPasteboard()
{
// commit all promises for paste after exit close
for (int i = 0; i < promises.count(); ++i) {
const Promise &promise = promises.at(i);
// At this point app teardown has started and control is somewhere in the Q[Core]Application
// destructor. Skip "lazy" promises where the application has not provided data;
// the application will generally not be in a state to provide it.
if (promise.dataRequestType == LazyRequest)
continue;
QCFString flavor = QCFString(promise.convertor->flavorFor(promise.mime));
NSInteger pbItemId = promise.itemId;
promiseKeeper(paste, reinterpret_cast<PasteboardItemID>(pbItemId), flavor, this);
}
resolvingBeforeDestruction = true;
PasteboardResolvePromises(paste);
if (paste)
CFRelease(paste);
}
@ -181,7 +174,7 @@ OSStatus QMacPasteboard::promiseKeeper(PasteboardRef paste, PasteboardItemID id,
// to request the data from the application.
QVariant promiseData;
if (promise.dataRequestType == LazyRequest) {
if (!promise.mimeData.isNull())
if (!qpaste->resolvingBeforeDestruction && !promise.mimeData.isNull())
promiseData = promise.mimeData->variantData(promise.mime);
} else {
promiseData = promise.variantData;

View File

@ -1625,12 +1625,18 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
const bool accepted = [self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)];
// Track keyDown acceptance state for later acceptance of the keyUp.
if (accepted)
// When Qt is used to implement a plugin for a native application we
// want to propagate unhandled events to other native views. However,
// Qt does not always set the accepted state correctly (in particular
// for return key events), so do this for plugin applications only
// to prevent incorrect forwarding in the general case.
const bool shouldPropagate = QCoreApplication::testAttribute(Qt::AA_PluginApplication) && !accepted;
// Track keyDown acceptance/forward state for later acceptance of the keyUp.
if (!shouldPropagate)
m_acceptedKeyDowns.insert([nsevent keyCode]);
// Propagate the keyDown to the next responder if Qt did not accept it.
if (!accepted)
if (shouldPropagate)
[super keyDown:nsevent];
}

View File

@ -302,7 +302,12 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
}
if (window->type() == Qt::ForeignWindow) {
QWindowsForeignWindow *result = new QWindowsForeignWindow(window, reinterpret_cast<HWND>(window->winId()));
const HWND hwnd = reinterpret_cast<HWND>(window->winId());
if (!IsWindow(hwnd)) {
qWarning("Windows QPA: Invalid foreign window ID %p.");
return nullptr;
}
QWindowsForeignWindow *result = new QWindowsForeignWindow(window, hwnd);
const QRect obtainedGeometry = result->geometry();
QScreen *screen = Q_NULLPTR;
if (const QPlatformScreen *pScreen = result->screenForGeometry(obtainedGeometry))

View File

@ -389,8 +389,13 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const
return QVariant(booleanSystemParametersInfo(SPI_GETSNAPTODEFBUTTON, false));
case ContextMenuOnMouseRelease:
return QVariant(true);
case WheelScrollLines:
return QVariant(int(dWordSystemParametersInfo(SPI_GETWHEELSCROLLLINES, 3)));
case WheelScrollLines: {
int result = 3;
const DWORD scrollLines = dWordSystemParametersInfo(SPI_GETWHEELSCROLLLINES, DWORD(result));
if (scrollLines != DWORD(-1)) // Special value meaning "scroll one screen", unimplemented in Qt.
result = int(scrollLines);
return QVariant(result);
}
default:
break;
}

View File

@ -1504,7 +1504,7 @@ void QWindowsWindow::handleGeometryChange()
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
}
if (testFlag(SynchronousGeometryChangeEvent))
QWindowSystemInterface::flushWindowSystemEvents();
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
qCDebug(lcQpaEvents) << __FUNCTION__ << this << window() << m_data.geometry;
}
@ -1596,7 +1596,7 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message,
// Our tests depend on it.
fireExpose(QRegion(qrectFromRECT(ps.rcPaint)), true);
if (!QWindowsContext::instance()->asyncExpose())
QWindowSystemInterface::flushWindowSystemEvents();
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
EndPaint(hwnd, &ps);
return true;
@ -1656,7 +1656,7 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowState state)
switch (state) {
case Qt::WindowMinimized:
handleHidden();
QWindowSystemInterface::flushWindowSystemEvents(); // Tell QQuickWindow to stop rendering now.
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); // Tell QQuickWindow to stop rendering now.
break;
case Qt::WindowMaximized:
case Qt::WindowFullScreen:
@ -1679,7 +1679,7 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowState state)
}
}
if (exposeEventsSent && !QWindowsContext::instance()->asyncExpose())
QWindowSystemInterface::flushWindowSystemEvents();
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
}
break;
default:
@ -1769,7 +1769,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
if (!wasSync)
clearFlag(SynchronousGeometryChangeEvent);
QWindowSystemInterface::handleGeometryChange(window(), r);
QWindowSystemInterface::flushWindowSystemEvents();
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
} else if (newState != Qt::WindowMinimized) {
// Restore saved state.
unsigned newStyle = m_savedStyle ? m_savedStyle : style();

View File

@ -2195,8 +2195,11 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in
const bool isWheel = detail >= 4 && detail <= 7;
if (!isWheel && window() != QGuiApplication::focusWindow()) {
QWindow *w = static_cast<QWindowPrivate *>(QObjectPrivate::get(window()))->eventReceiver();
if (!(w->flags() & Qt::WindowDoesNotAcceptFocus))
if (!(w->flags() & (Qt::WindowDoesNotAcceptFocus | Qt::BypassWindowManagerHint))
&& w->type() != Qt::ToolTip
&& w->type() != Qt::Popup) {
w->requestActivate();
}
}
updateNetWmUserTime(timestamp);

View File

@ -254,7 +254,7 @@
\li \c -nocrashhandler \br
Disables the crash handler on Unix platforms.
On Windows, it re-enables the Windows Error Reporting dialog, which is
turned off by default.
turned off by default. This is useful for debugging crashes.
\li \c -platform \e name \br
This command line argument applies to all Qt applications, but might be

View File

@ -485,7 +485,7 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
" -mousedelay ms : Set default delay for mouse simulation to ms milliseconds\n"
" -maxwarnings n : Sets the maximum amount of messages to output.\n"
" 0 means unlimited, default: 2000\n"
" -nocrashhandler : Disables the crash handler\n"
" -nocrashhandler : Disables the crash handler. Useful for debugging crashes.\n"
"\n"
" Benchmarking options:\n"
#ifdef QTESTLIB_USE_VALGRIND

View File

@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
@ -179,6 +180,8 @@ Type Moc::parseType()
case Q_SLOT_TOKEN:
type.name += lexem();
return type;
case NOTOKEN:
return type;
default:
prev();
break;
@ -213,6 +216,8 @@ Type Moc::parseType()
type.name += lexem();
isVoid |= (lookup(0) == VOID);
break;
case NOTOKEN:
return type;
default:
prev();
;

View File

@ -849,8 +849,10 @@ void QDialog::adjustPosition(QWidget* w)
// QTBUG-52735: Manually set the correct target screen since scaling in a
// subsequent call to QWindow::resize() may otherwise use the wrong factor
// if the screen changed notification is still in an event queue.
if (QWindow *window = windowHandle())
window->setScreen(QGuiApplication::screens().at(scrn));
if (scrn >= 0) {
if (QWindow *window = windowHandle())
window->setScreen(QGuiApplication::screens().at(scrn));
}
move(p);
}

View File

@ -376,6 +376,7 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
const QStyleOptionViewItem &option,
const QModelIndex &index)
{
Q_D(QAbstractItemDelegate);
Q_UNUSED(option);
if (!event || !view)
@ -384,9 +385,10 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
#ifndef QT_NO_TOOLTIP
case QEvent::ToolTip: {
QHelpEvent *he = static_cast<QHelpEvent*>(event);
QVariant tooltip = index.data(Qt::ToolTipRole);
if (tooltip.canConvert<QString>()) {
QToolTip::showText(he->globalPos(), tooltip.toString(), view);
const int precision = inherits("QItemDelegate") ? 10 : 6; // keep in sync with DBL_DIG in qitemdelegate.cpp
const QString tooltip = d->textForRole(Qt::ToolTipRole, index.data(Qt::ToolTipRole), option.locale, precision);
if (!tooltip.isEmpty()) {
QToolTip::showText(he->globalPos(), tooltip, view);
return true;
}
break;}
@ -398,9 +400,10 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
break; }
case QEvent::WhatsThis: {
QHelpEvent *he = static_cast<QHelpEvent*>(event);
QVariant whatsthis = index.data(Qt::WhatsThisRole);
if (whatsthis.canConvert<QString>()) {
QWhatsThis::showText(he->globalPos(), whatsthis.toString(), view);
const int precision = inherits("QItemDelegate") ? 10 : 6; // keep in sync with DBL_DIG in qitemdelegate.cpp
const QString whatsthis = d->textForRole(Qt::WhatsThisRole, index.data(Qt::WhatsThisRole), option.locale, precision);
if (!whatsthis.isEmpty()) {
QWhatsThis::showText(he->globalPos(), whatsthis, view);
return true;
}
break ; }
@ -543,6 +546,46 @@ bool QAbstractItemDelegatePrivate::tryFixup(QWidget *editor)
return true;
}
QString QAbstractItemDelegatePrivate::textForRole(Qt::ItemDataRole role, const QVariant &value, const QLocale &locale, int precision) const
{
const QLocale::FormatType formatType = (role == Qt::DisplayRole) ? QLocale::ShortFormat : QLocale::LongFormat;
QString text;
switch (value.userType()) {
case QMetaType::Float:
text = locale.toString(value.toFloat());
break;
case QVariant::Double:
text = locale.toString(value.toDouble(), 'g', precision);
break;
case QVariant::Int:
case QVariant::LongLong:
text = locale.toString(value.toLongLong());
break;
case QVariant::UInt:
case QVariant::ULongLong:
text = locale.toString(value.toULongLong());
break;
case QVariant::Date:
text = locale.toString(value.toDate(), formatType);
break;
case QVariant::Time:
text = locale.toString(value.toTime(), formatType);
break;
case QVariant::DateTime: {
const QDateTime dateTime = value.toDateTime();
text = locale.toString(dateTime.date(), formatType)
+ QLatin1Char(' ')
+ locale.toString(dateTime.time(), formatType);
break; }
default:
text = value.toString();
if (role == Qt::DisplayRole)
text.replace(QLatin1Char('\n'), QChar::LineSeparator);
break;
}
return text;
}
void QAbstractItemDelegatePrivate::_q_commitDataAndCloseEditor(QWidget *editor)
{
Q_Q(QAbstractItemDelegate);

View File

@ -59,7 +59,7 @@
QT_BEGIN_NAMESPACE
class QAbstractItemDelegatePrivate : public QObjectPrivate
class Q_AUTOTEST_EXPORT QAbstractItemDelegatePrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QAbstractItemDelegate)
public:
@ -67,6 +67,7 @@ public:
bool editorEventFilter(QObject *object, QEvent *event);
bool tryFixup(QWidget *editor);
QString textForRole(Qt::ItemDataRole role, const QVariant &value, const QLocale &locale, int precision = 6) const;
void _q_commitDataAndCloseEditor(QWidget *editor);
};

View File

@ -4325,6 +4325,12 @@ const QEditorInfo & QAbstractItemViewPrivate::editorForIndex(const QModelIndex &
return it.value();
}
bool QAbstractItemViewPrivate::hasEditor(const QModelIndex &index) const
{
// Search's implicit cast (QModelIndex to QPersistentModelIndex) is slow; use cheap pre-test to avoid when we can.
return !indexEditorHash.isEmpty() && indexEditorHash.contains(index);
}
QModelIndex QAbstractItemViewPrivate::indexForEditor(QWidget *editor) const
{
// do not try to search to avoid slow implicit cast from QModelIndex to QPersistentModelIndex

View File

@ -277,10 +277,7 @@ public:
}
const QEditorInfo &editorForIndex(const QModelIndex &index) const;
inline bool hasEditor(const QModelIndex &index) const {
// Search's implicit cast (QModelIndex to QPersistentModelIndex) is slow; use cheap pre-test to avoid when we can.
return !indexEditorHash.isEmpty() && indexEditorHash.contains(index);
}
bool hasEditor(const QModelIndex &index) const;
QModelIndex indexForEditor(QWidget *editor) const;
void addEditor(const QModelIndex &index, QWidget *editor, bool isStatic);

View File

@ -67,6 +67,7 @@
#include <limits.h>
// keep in sync with QAbstractItemDelegate::helpEvent()
#ifndef DBL_DIG
# define DBL_DIG 10
#endif
@ -102,7 +103,7 @@ public:
return text;
}
static QString valueToText(const QVariant &value, const QStyleOptionViewItem &option);
QString valueToText(const QVariant &value, const QStyleOptionViewItem &option) const;
QItemEditorFactory *f;
bool clipPainting;
@ -332,40 +333,9 @@ void QItemDelegate::setClipping(bool clip)
d->clipPainting = clip;
}
QString QItemDelegatePrivate::valueToText(const QVariant &value, const QStyleOptionViewItem &option)
QString QItemDelegatePrivate::valueToText(const QVariant &value, const QStyleOptionViewItem &option) const
{
QString text;
switch (value.userType()) {
case QMetaType::Float:
text = option.locale.toString(value.toFloat(), 'g');
break;
case QVariant::Double:
text = option.locale.toString(value.toDouble(), 'g', DBL_DIG);
break;
case QVariant::Int:
case QVariant::LongLong:
text = option.locale.toString(value.toLongLong());
break;
case QVariant::UInt:
case QVariant::ULongLong:
text = option.locale.toString(value.toULongLong());
break;
case QVariant::Date:
text = option.locale.toString(value.toDate(), QLocale::ShortFormat);
break;
case QVariant::Time:
text = option.locale.toString(value.toTime(), QLocale::ShortFormat);
break;
case QVariant::DateTime:
text = option.locale.toString(value.toDateTime().date(), QLocale::ShortFormat);
text += QLatin1Char(' ');
text += option.locale.toString(value.toDateTime().time(), QLocale::ShortFormat);
break;
default:
text = replaceNewLine(value.toString());
break;
}
return text;
return textForRole(Qt::DisplayRole, value, option.locale, DBL_DIG);
}
/*!
@ -434,7 +404,7 @@ void QItemDelegate::paint(QPainter *painter,
QRect displayRect;
value = index.data(Qt::DisplayRole);
if (value.isValid() && !value.isNull()) {
text = QItemDelegatePrivate::valueToText(value, opt);
text = d->valueToText(value, opt);
displayRect = textRectangle(painter, d->textLayoutBounds(opt), opt.font, text);
}
@ -1061,7 +1031,7 @@ QRect QItemDelegate::rect(const QStyleOptionViewItem &option,
return QRect(QPoint(0, 0), option.decorationSize);
case QVariant::String:
default: {
QString text = QItemDelegatePrivate::valueToText(value, option);
const QString text = d->valueToText(value, option);
value = index.data(Qt::FontRole);
QFont fnt = qvariant_cast<QFont>(value).resolve(option.font);
return textRectangle(0, d->textLayoutBounds(option), fnt, text); }

View File

@ -261,41 +261,7 @@ QStyledItemDelegate::~QStyledItemDelegate()
*/
QString QStyledItemDelegate::displayText(const QVariant &value, const QLocale& locale) const
{
QString text;
switch (value.userType()) {
case QMetaType::Float:
case QVariant::Double:
text = locale.toString(value.toReal());
break;
case QVariant::Int:
case QVariant::LongLong:
text = locale.toString(value.toLongLong());
break;
case QVariant::UInt:
case QVariant::ULongLong:
text = locale.toString(value.toULongLong());
break;
case QVariant::Date:
text = locale.toString(value.toDate(), QLocale::ShortFormat);
break;
case QVariant::Time:
text = locale.toString(value.toTime(), QLocale::ShortFormat);
break;
case QVariant::DateTime:
text = locale.toString(value.toDateTime().date(), QLocale::ShortFormat);
text += QLatin1Char(' ');
text += locale.toString(value.toDateTime().time(), QLocale::ShortFormat);
break;
default:
// convert new lines into line separators
text = value.toString();
for (int i = 0; i < text.count(); ++i) {
if (text.at(i) == QLatin1Char('\n'))
text[i] = QChar::LineSeparator;
}
break;
}
return text;
return d_func()->textForRole(Qt::DisplayRole, value, locale);
}
/*!

View File

@ -1923,7 +1923,7 @@ NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget) const
}
case QCocoaPushButton: {
NSButton *bc = (NSButton *)bv;
bc.buttonType = NSMomentaryPushButton;
bc.buttonType = NSMomentaryLightButton;
bc.bezelStyle = NSRoundedBezelStyle;
break;
}

View File

@ -64,8 +64,12 @@
#include "qlistview.h"
#include <private/qmath_p.h>
#include <qmath.h>
#include <QtGui/qscreen.h>
#include <QtGui/qwindow.h>
#include <qpa/qplatformtheme.h>
#include <qpa/qplatformscreen.h>
#include <private/qguiapplication_p.h>
#include <private/qhighdpiscaling_p.h>
#include <private/qstylehelper_p.h>
#include <private/qstyleanimation_p.h>
@ -360,6 +364,47 @@ int QWindowsStylePrivate::fixedPixelMetric(QStyle::PixelMetric pm)
return QWindowsStylePrivate::InvalidMetric;
}
static QWindow *windowOf(const QWidget *w)
{
QWindow *result = Q_NULLPTR;
if (w) {
result = w->windowHandle();
if (!result) {
if (const QWidget *np = w->nativeParentWidget())
result = np->windowHandle();
}
}
return result;
}
static QScreen *screenOf(const QWidget *w)
{
if (const QWindow *window = windowOf(w))
return window->screen();
return QGuiApplication::primaryScreen();
}
// Calculate the overall scale factor to obtain Qt Device Independent
// Pixels from a native Windows size. Divide by devicePixelRatio
// and account for secondary screens with differing logical DPI.
qreal QWindowsStylePrivate::nativeMetricScaleFactor(const QWidget *widget)
{
if (!QHighDpiScaling::isActive())
return 1;
qreal result = qreal(1) / QWindowsStylePrivate::devicePixelRatio(widget);
if (QGuiApplicationPrivate::screen_list.size() > 1) {
const QScreen *primaryScreen = QGuiApplication::primaryScreen();
const QScreen *screen = screenOf(widget);
if (screen != primaryScreen) {
const qreal primaryLogicalDpi = primaryScreen->handle()->logicalDpi().first;
const qreal logicalDpi = screen->handle()->logicalDpi().first;
if (!qFuzzyCompare(primaryLogicalDpi, logicalDpi))
result *= logicalDpi / primaryLogicalDpi;
}
}
return result;
}
/*!
\reimp
*/
@ -367,7 +412,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW
{
int ret = QWindowsStylePrivate::pixelMetricFromSystemDp(pm, opt, widget);
if (ret != QWindowsStylePrivate::InvalidMetric)
return qRound(qreal(ret) / QWindowsStylePrivate::devicePixelRatio(widget));
return qRound(qreal(ret) * QWindowsStylePrivate::nativeMetricScaleFactor(widget));
ret = QWindowsStylePrivate::fixedPixelMetric(pm);
if (ret != QWindowsStylePrivate::InvalidMetric)

View File

@ -73,6 +73,7 @@ public:
static int fixedPixelMetric(QStyle::PixelMetric pm);
static qreal devicePixelRatio(const QWidget *widget = 0)
{ return widget ? widget->devicePixelRatioF() : QWindowsStylePrivate::appDevicePixelRatio(); }
static qreal nativeMetricScaleFactor(const QWidget *widget = Q_NULLPTR);
bool hasSeenAlt(const QWidget *widget) const;
bool altDown() const { return alt_down; }
@ -105,3 +106,4 @@ QT_END_NAMESPACE
#endif // QT_NO_STYLE_WINDOWS
#endif //QWINDOWSSTYLE_P_P_H
;

View File

@ -430,7 +430,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
XPThemeData themeSize = theme;
themeSize.partId = TVP_HOTGLYPH;
themeSize.stateId = GLPS_OPENED;
const QSizeF size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
decoration_size = qRound(qMax(size.width(), size.height()));
}
int mid_h = option->rect.x() + option->rect.width() / 2;
@ -988,7 +988,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ToolBarTheme,
TP_DROPDOWNBUTTON);
if (theme.isValid()) {
const QSizeF size = theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
const QSizeF size = theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
if (!size.isEmpty()) {
mbiw = qRound(size.width());
mbih = qRound(size.height());
@ -1184,8 +1184,8 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
XPThemeData themeSize = theme;
themeSize.partId = MENU_POPUPCHECK;
themeSize.stateId = 0;
const QSizeF size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
const QMarginsF margins = themeSize.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget);
const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
checkcol = qMax(menuitem->maxIconWidth, qRound(gutterWidth + size.width() + margins.left() + margins.right()));
}
QRect rect = option->rect;
@ -1210,7 +1210,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) {
int yoff = y-2 + h / 2;
const int separatorSize = 6 / QWindowsXPStylePrivate::devicePixelRatio(widget);
const int separatorSize = qRound(qreal(6) * QWindowsStylePrivate::nativeMetricScaleFactor(widget));
QPoint p1 = QPoint(x + checkcol, yoff);
QPoint p2 = QPoint(x + w + separatorSize, yoff);
stateId = MBI_HOT;
@ -1243,8 +1243,8 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
XPThemeData themeSize = theme;
themeSize.partId = MENU_POPUPCHECK;
themeSize.stateId = 0;
const QSizeF size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
const QMarginsF margins = themeSize.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget);
const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
QRect checkRect(0, 0, qRound(size.width() + margins.left() + margins.right()),
qRound(size.height() + margins.bottom() + margins.top()));
checkRect.moveCenter(vCheckRect.center());
@ -1856,8 +1856,8 @@ QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption
XPThemeData themeSize = theme;
themeSize.partId = MENU_POPUPCHECK;
themeSize.stateId = 0;
const QSizeF size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
const QMarginsF margins = themeSize.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget);
const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
minimumHeight = qMax(qRound(size.height() + margins.bottom() + margins.top()), sz.height());
sz.rwidth() += qRound(size.width() + margins.left() + margins.right());
}
@ -1959,7 +1959,7 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption
int arrowWidth = 13;
int arrowHeight = 5;
if (theme.isValid()) {
const QSizeF size = theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
const QSizeF size = theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
if (!size.isEmpty()) {
arrowWidth = qRound(size.width());
arrowHeight = qRound(size.height());
@ -2440,7 +2440,7 @@ QIcon QWindowsVistaStyle::standardIcon(StandardPixmap standardIcon,
QWindowsXPStylePrivate::ButtonTheme,
BP_COMMANDLINKGLYPH, CMDLGS_NORMAL);
if (theme.isValid()) {
const QSize size = (theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize();
const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize();
QIcon linkGlyph;
QPixmap pm(size);
pm.fill(Qt::transparent);

View File

@ -415,7 +415,7 @@ const QPixmap *QWindowsXPStylePrivate::tabBody(QWidget *widget)
{
if (!tabbody) {
XPThemeData theme(0, 0, QWindowsXPStylePrivate::TabTheme, TABP_BODY);
const QSize size = (theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize();
const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize();
tabbody = new QPixmap(size.width(), QApplication::desktop()->screenGeometry().height());
QPainter painter(tabbody);
@ -3274,7 +3274,7 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con
int res = QWindowsXPStylePrivate::pixelMetricFromSystemDp(pm, option, widget);
if (res != QWindowsStylePrivate::InvalidMetric)
return qRound(qreal(res) / QWindowsStylePrivate::devicePixelRatio(widget));
return qRound(qreal(res) * QWindowsStylePrivate::nativeMetricScaleFactor(widget));
res = 0;
switch (pm) {
@ -3420,9 +3420,10 @@ QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionCompl
const int height = tb->rect.height();
const int width = tb->rect.width();
const int buttonMargin = int(QStyleHelper::dpiScaled(4));
int buttonHeight = qRound(qreal(GetSystemMetrics(SM_CYSIZE)) / QWindowsStylePrivate::devicePixelRatio(widget))
const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(widget);
int buttonHeight = qRound(qreal(GetSystemMetrics(SM_CYSIZE)) * factor)
- buttonMargin;
int buttonWidth = qRound(qreal(GetSystemMetrics(SM_CXSIZE)) / QWindowsStylePrivate::devicePixelRatio(widget))
int buttonWidth = qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * factor)
- buttonMargin;
const int delta = buttonWidth + 2;
int controlTop = option->rect.bottom() - buttonHeight - 2;
@ -3792,7 +3793,7 @@ QPixmap QWindowsXPStyle::standardPixmap(StandardPixmap standardPixmap, const QSt
if (widget && widget->isWindow()) {
XPThemeData theme(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL);
if (theme.isValid()) {
const QSize size = (theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize();
const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize();
return QIcon(QWindowsStyle::standardPixmap(standardPixmap, option, widget)).pixmap(size);
}
}
@ -3826,7 +3827,7 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon,
XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme,
WP_MAXBUTTON, MAXBS_NORMAL);
if (theme.isValid()) {
const QSize size = (themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize();
const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize();
QPixmap pm(size);
pm.fill(Qt::transparent);
QPainter p(&pm);
@ -3860,7 +3861,7 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon,
XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme,
WP_SMALLCLOSEBUTTON, CBS_NORMAL);
if (theme.isValid()) {
const QSize size = (theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize();
const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize();
QPixmap pm(size);
pm.fill(Qt::transparent);
QPainter p(&pm);

View File

@ -2723,27 +2723,43 @@ void tst_QDataStream::status_QBitArray()
}
#define MAP_TEST(byteArray, initialStatus, expectedStatus, expectedHash) \
{ \
QByteArray ba = byteArray; \
QDataStream stream(&ba, QIODevice::ReadOnly); \
stream.setStatus(initialStatus); \
stream >> hash; \
QCOMPARE((int)stream.status(), (int)expectedStatus); \
QCOMPARE(hash.size(), expectedHash.size()); \
QCOMPARE(hash, expectedHash); \
} \
{ \
QByteArray ba = byteArray; \
StringMap expectedMap; \
StringHash::const_iterator it = expectedHash.constBegin(); \
for (; it != expectedHash.constEnd(); ++it) \
expectedMap.insert(it.key(), it.value()); \
QDataStream stream(&ba, QIODevice::ReadOnly); \
stream.setStatus(initialStatus); \
stream >> map; \
QCOMPARE((int)stream.status(), (int)expectedStatus); \
QCOMPARE(map.size(), expectedMap.size()); \
QCOMPARE(map, expectedMap); \
for (bool inTransaction = false;; inTransaction = true) { \
{ \
QByteArray ba = byteArray; \
QDataStream stream(&ba, QIODevice::ReadOnly); \
if (inTransaction) \
stream.startTransaction(); \
stream.setStatus(initialStatus); \
stream >> hash; \
QCOMPARE((int)stream.status(), (int)expectedStatus); \
if (!inTransaction || stream.commitTransaction()) { \
QCOMPARE(hash.size(), expectedHash.size()); \
QCOMPARE(hash, expectedHash); \
} else { \
QVERIFY(hash.isEmpty()); \
} \
} \
{ \
QByteArray ba = byteArray; \
StringMap expectedMap; \
StringHash::const_iterator it = expectedHash.constBegin(); \
for (; it != expectedHash.constEnd(); ++it) \
expectedMap.insert(it.key(), it.value()); \
QDataStream stream(&ba, QIODevice::ReadOnly); \
if (inTransaction) \
stream.startTransaction(); \
stream.setStatus(initialStatus); \
stream >> map; \
QCOMPARE((int)stream.status(), (int)expectedStatus); \
if (!inTransaction || stream.commitTransaction()) { \
QCOMPARE(map.size(), expectedMap.size()); \
QCOMPARE(map, expectedMap); \
} else { \
QVERIFY(map.isEmpty()); \
} \
} \
if (inTransaction) \
break; \
}
void tst_QDataStream::status_QHash_QMap()
@ -2788,38 +2804,60 @@ void tst_QDataStream::status_QHash_QMap()
}
#define LIST_TEST(byteArray, initialStatus, expectedStatus, expectedList) \
{ \
QByteArray ba = byteArray; \
QDataStream stream(&ba, QIODevice::ReadOnly); \
stream.setStatus(initialStatus); \
stream >> list; \
QCOMPARE((int)stream.status(), (int)expectedStatus); \
QCOMPARE(list.size(), expectedList.size()); \
QCOMPARE(list, expectedList); \
} \
{ \
LinkedList expectedLinkedList; \
for (int i = 0; i < expectedList.count(); ++i) \
expectedLinkedList << expectedList.at(i); \
QByteArray ba = byteArray; \
QDataStream stream(&ba, QIODevice::ReadOnly); \
stream.setStatus(initialStatus); \
stream >> linkedList; \
QCOMPARE((int)stream.status(), (int)expectedStatus); \
QCOMPARE(linkedList.size(), expectedLinkedList.size()); \
QCOMPARE(linkedList, expectedLinkedList); \
} \
{ \
Vector expectedVector; \
for (int i = 0; i < expectedList.count(); ++i) \
expectedVector << expectedList.at(i); \
QByteArray ba = byteArray; \
QDataStream stream(&ba, QIODevice::ReadOnly); \
stream.setStatus(initialStatus); \
stream >> vector; \
QCOMPARE((int)stream.status(), (int)expectedStatus); \
QCOMPARE(vector.size(), expectedVector.size()); \
QCOMPARE(vector, expectedVector); \
for (bool inTransaction = false;; inTransaction = true) { \
{ \
QByteArray ba = byteArray; \
QDataStream stream(&ba, QIODevice::ReadOnly); \
if (inTransaction) \
stream.startTransaction(); \
stream.setStatus(initialStatus); \
stream >> list; \
QCOMPARE((int)stream.status(), (int)expectedStatus); \
if (!inTransaction || stream.commitTransaction()) { \
QCOMPARE(list.size(), expectedList.size()); \
QCOMPARE(list, expectedList); \
} else { \
QVERIFY(list.isEmpty()); \
} \
} \
{ \
LinkedList expectedLinkedList; \
for (int i = 0; i < expectedList.count(); ++i) \
expectedLinkedList << expectedList.at(i); \
QByteArray ba = byteArray; \
QDataStream stream(&ba, QIODevice::ReadOnly); \
if (inTransaction) \
stream.startTransaction(); \
stream.setStatus(initialStatus); \
stream >> linkedList; \
QCOMPARE((int)stream.status(), (int)expectedStatus); \
if (!inTransaction || stream.commitTransaction()) { \
QCOMPARE(linkedList.size(), expectedLinkedList.size()); \
QCOMPARE(linkedList, expectedLinkedList); \
} else { \
QVERIFY(linkedList.isEmpty()); \
} \
} \
{ \
Vector expectedVector; \
for (int i = 0; i < expectedList.count(); ++i) \
expectedVector << expectedList.at(i); \
QByteArray ba = byteArray; \
QDataStream stream(&ba, QIODevice::ReadOnly); \
if (inTransaction) \
stream.startTransaction(); \
stream.setStatus(initialStatus); \
stream >> vector; \
QCOMPARE((int)stream.status(), (int)expectedStatus); \
if (!inTransaction || stream.commitTransaction()) { \
QCOMPARE(vector.size(), expectedVector.size()); \
QCOMPARE(vector, expectedVector); \
} else { \
QVERIFY(vector.isEmpty()); \
} \
} \
if (inTransaction) \
break; \
}
void tst_QDataStream::status_QLinkedList_QList_QVector()

View File

@ -34,6 +34,7 @@
#include <qfile.h>
#include <qdir.h>
#include <qset.h>
#include <qtextcodec.h>
#ifdef Q_OS_WIN
# include <windows.h>
#endif
@ -108,6 +109,38 @@ void tst_QTemporaryDir::getSetCheck()
QCOMPARE(true, obj1.autoRemove());
}
static inline bool canHandleUnicodeFileNames()
{
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
return true;
#else
// Check for UTF-8 by converting the Euro symbol (see tst_utf8)
return QFile::encodeName(QString(QChar(0x20AC))) == QByteArrayLiteral("\342\202\254");
#endif
}
static QString hanTestText()
{
QString text;
text += QChar(0x65B0);
text += QChar(0x5E10);
text += QChar(0x6237);
return text;
}
static QString umlautTestText()
{
QString text;
text += QChar(0xc4);
text += QChar(0xe4);
text += QChar(0xd6);
text += QChar(0xf6);
text += QChar(0xdc);
text += QChar(0xfc);
text += QChar(0xdf);
return text;
}
void tst_QTemporaryDir::fileTemplate_data()
{
QTest::addColumn<QString>("constructorTemplate");
@ -124,6 +157,14 @@ void tst_QTemporaryDir::fileTemplate_data()
QTest::newRow("constructor with XXXX suffix") << "qt_XXXXXX_XXXX" << "qt_";
QTest::newRow("constructor with XXXX prefix") << "qt_XXXX" << "qt_";
QTest::newRow("constructor with XXXXX prefix") << "qt_XXXXX" << "qt_";
if (canHandleUnicodeFileNames()) {
// Test Umlauts (contained in Latin1)
QString prefix = "qt_" + umlautTestText();
QTest::newRow("Umlauts") << (prefix + "XXXXXX") << prefix;
// Test Chinese
prefix = "qt_" + hanTestText();
QTest::newRow("Chinese characters") << (prefix + "XXXXXX") << prefix;
}
}
void tst_QTemporaryDir::fileTemplate()

View File

@ -34,6 +34,7 @@
#include <qfile.h>
#include <qdir.h>
#include <qset.h>
#include <qtextcodec.h>
#if defined(Q_OS_WIN)
# include <windows.h>
@ -140,6 +141,38 @@ void tst_QTemporaryFile::getSetCheck()
QCOMPARE(true, obj1.autoRemove());
}
static inline bool canHandleUnicodeFileNames()
{
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
return true;
#else
// Check for UTF-8 by converting the Euro symbol (see tst_utf8)
return QFile::encodeName(QString(QChar(0x20AC))) == QByteArrayLiteral("\342\202\254");
#endif
}
static QString hanTestText()
{
QString text;
text += QChar(0x65B0);
text += QChar(0x5E10);
text += QChar(0x6237);
return text;
}
static QString umlautTestText()
{
QString text;
text += QChar(0xc4);
text += QChar(0xe4);
text += QChar(0xd6);
text += QChar(0xf6);
text += QChar(0xdc);
text += QChar(0xfc);
text += QChar(0xdf);
return text;
}
void tst_QTemporaryFile::fileTemplate_data()
{
QTest::addColumn<QString>("constructorTemplate");
@ -166,6 +199,14 @@ void tst_QTemporaryFile::fileTemplate_data()
QTest::newRow("set template, with xxx") << "" << "qt_" << ".xxx" << "qt_XXXXXX.xxx";
QTest::newRow("set template, with >6 X's") << "" << "qt_" << ".xxx" << "qt_XXXXXXXXXXXXXX.xxx";
QTest::newRow("set template, with >6 X's, no suffix") << "" << "qt_" << "" << "qt_XXXXXXXXXXXXXX";
if (canHandleUnicodeFileNames()) {
// Test Umlauts (contained in Latin1)
QString prefix = "qt_" + umlautTestText();
QTest::newRow("Umlauts") << (prefix + "XXXXXX") << prefix << QString() << QString();
// Test Chinese
prefix = "qt_" + hanTestText();
QTest::newRow("Chinese characters") << (prefix + "XXXXXX") << prefix << QString() << QString();
}
}
void tst_QTemporaryFile::fileTemplate()

View File

@ -271,6 +271,7 @@ private slots:
void testOperators() const;
void reserve();
void reserveZero();
void reallocAfterCopy_data();
void reallocAfterCopy();
void initializeListInt();
@ -2365,13 +2366,34 @@ void tst_QVector::reserve()
{
QVector<Foo> a;
a.resize(2);
QCOMPARE(fooCtor, 2);
QVector<Foo> b(a);
b.reserve(1);
QCOMPARE(b.size(), a.size());
QCOMPARE(fooDtor, 0);
}
QCOMPARE(fooCtor, fooDtor);
}
// This is a regression test for QTBUG-51758
void tst_QVector::reserveZero()
{
QVector<int> vec;
vec.detach();
vec.reserve(0); // should not crash
QCOMPARE(vec.size(), 0);
QCOMPARE(vec.capacity(), 0);
vec.squeeze();
QCOMPARE(vec.size(), 0);
QCOMPARE(vec.capacity(), 0);
vec.reserve(-1);
QCOMPARE(vec.size(), 0);
QCOMPARE(vec.capacity(), 0);
vec.append(42);
QCOMPARE(vec.size(), 1);
QVERIFY(vec.capacity() >= 1);
}
// This is a regression test for QTBUG-11763, where memory would be reallocated
// soon after copying a QVector.
void tst_QVector::reallocAfterCopy_data()

View File

@ -557,6 +557,8 @@ private slots:
void checkCommentIndentation_data() const;
void crashInXmlStreamReader() const;
void write8bitCodec() const;
void invalidStringCharacters_data() const;
void invalidStringCharacters() const;
void hasError() const;
private:
@ -1614,6 +1616,63 @@ void tst_QXmlStream::write8bitCodec() const
QVERIFY(decodedText.startsWith(expected));
}
void tst_QXmlStream::invalidStringCharacters() const
{
// test scan in attributes
QFETCH(QString, testString);
QFETCH(bool, expectedResultNoError);
QByteArray values = testString.toUtf8();
QBuffer inBuffer;
inBuffer.setData(values);
QVERIFY(inBuffer.open(QIODevice::ReadOnly));
QXmlStreamReader reader(&inBuffer);
do {
reader.readNext();
} while (!reader.atEnd());
QCOMPARE((reader.error() == QXmlStreamReader::NoError), expectedResultNoError);
}
void tst_QXmlStream::invalidStringCharacters_data() const
{
// test scan in attributes
QTest::addColumn<bool>("expectedResultNoError");
QTest::addColumn<QString>("testString");
QChar ctrl(0x1A);
QTest::newRow("utf8, attributes, legal") << true << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'/>");
QTest::newRow("utf8, attributes, only char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='")+ctrl+QString("'/>");
QTest::newRow("utf8, attributes, 1st char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='")+ctrl+QString("abc'/>");
QTest::newRow("utf8, attributes, middle char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='abc")+ctrl+QString("efgx'/>");
QTest::newRow("utf8, attributes, last char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='abcde")+ctrl+QString("'/>");
//
QTest::newRow("utf8, text, legal") << true << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'>abcx1A</root>");
QTest::newRow("utf8, text, only, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'>")+ctrl+QString("</root>");
QTest::newRow("utf8, text, 1st char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'>abc")+ctrl+QString("def</root>");
QTest::newRow("utf8, text, middle char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'>abc")+ctrl+QString("efg</root>");
QTest::newRow("utf8, text, last char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'>abc")+ctrl+QString("</root>");
//
QTest::newRow("utf8, cdata text, legal") << true << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'><![CDATA[abcdefghi]]></root>");
QTest::newRow("utf8, cdata text, only, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'><![CDATA[")+ctrl+QString("]]></root>");
QTest::newRow("utf8, cdata text, 1st char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'><![CDATA[")+ctrl+QString("abcdefghi]]></root>");
QTest::newRow("utf8, cdata text, middle char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'><![CDATA[abcd")+ctrl+QString("efghi]]></root>");
QTest::newRow("utf8, cdata text, last char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'><![CDATA[abcdefghi")+ctrl+QString("]]></root>");
//
QTest::newRow("utf8, mixed, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='a")+ctrl+QString("a'><![CDATA[abcdefghi")+ctrl+QString("]]></root>");
QTest::newRow("utf8, tag") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><roo")+ctrl+QString("t attr='aa'><![CDATA[abcdefghi]]></roo")+ctrl+QString("t>");
//
QTest::newRow("utf8, attributes, 1st char, legal escaping hex") << true << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='a&#xA0;'/>");
QTest::newRow("utf8, attributes, 1st char, control escaping hex") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='&#x1A;aaa'/>");
QTest::newRow("utf8, attributes, middle char, legal escaping hex") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aaa&#x1A;aaa'/>");
QTest::newRow("utf8, attributes, last char, control escaping hex") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aaa&#x1A;'/>");
QTest::newRow("utf8, attributes, 1st char, legal escaping dec") << true << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='a&#160;'/>");
QTest::newRow("utf8, attributes, 1st char, control escaping dec") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='&#26;aaaa'/>");
QTest::newRow("utf8, attributes, middle char, legal escaping dec") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aaa&#26;aaaaa'/>");
QTest::newRow("utf8, attributes, last char, control escaping dec") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aaaaaa&#26;'/>");
QTest::newRow("utf8, tag escaping") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><roo&#x1A;t attr='aa'><![CDATA[abcdefghi]]></roo&#x1A;t>");
//
QTest::newRow("utf8, mix of illegal control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='a&#0;&#x4;&#x1c;a'><![CDATA[abcdefghi]]></root>");
//
}
#include "tst_qxmlstream.moc"
// vim: et:ts=4:sw=4:sts=4

View File

@ -94,6 +94,8 @@ private slots:
void setPixel_data();
void setPixel();
void defaultColorTable_data();
void defaultColorTable();
void setColorCount();
void setColor();
@ -1450,6 +1452,38 @@ void tst_QImage::convertToFormatPreserveText()
QCOMPARE(imgResult2.textKeys(), listResult);
}
void tst_QImage::defaultColorTable_data()
{
QTest::addColumn<QImage::Format>("format");
QTest::addColumn<int>("createdDataCount");
QTest::addColumn<int>("externalDataCount");
// For historical reasons, internally created mono images get a default colormap.
// Externally created and Indexed8 images do not.
QTest::newRow("Mono") << QImage::Format_Mono << 2 << 0;
QTest::newRow("MonoLSB") << QImage::Format_MonoLSB << 2 << 0;
QTest::newRow("Indexed8") << QImage::Format_Indexed8 << 0 << 0;
QTest::newRow("ARGB32_PM") << QImage::Format_A2BGR30_Premultiplied << 0 << 0;
}
void tst_QImage::defaultColorTable()
{
QFETCH(QImage::Format, format);
QFETCH(int, createdDataCount);
QFETCH(int, externalDataCount);
QImage img1(1, 1, format);
QCOMPARE(img1.colorCount(), createdDataCount);
QCOMPARE(img1.colorTable().size(), createdDataCount);
quint32 buf;
QImage img2(reinterpret_cast<uchar *>(&buf), 1, 1, format);
QCOMPARE(img2.colorCount(), externalDataCount);
QImage nullImg(0, 0, format);
QCOMPARE(nullImg.colorCount(), 0);
}
void tst_QImage::setColorCount()
{
QImage img(0, 0, QImage::Format_Indexed8);
@ -3194,8 +3228,8 @@ void tst_QImage::pixel()
QImage monolsb(&a, 1, 1, QImage::Format_MonoLSB);
QImage indexed(&a, 1, 1, QImage::Format_Indexed8);
QCOMPARE(QColor(mono.pixel(0, 0)), QColor(Qt::black));
QCOMPARE(QColor(monolsb.pixel(0, 0)), QColor(Qt::black));
mono.pixel(0, 0); // Don't crash
monolsb.pixel(0, 0); // Don't crash
indexed.pixel(0, 0); // Don't crash
}
}

View File

@ -673,6 +673,12 @@ void tst_QTcpSocket::bindThenResolveHost()
const quint16 port = 80;
socket->connectToHost(hostName, port);
// Additionally, initiate a delayed close before the socket connects
// to ensure that we don't lose the socket engine in HostLookupState.
// After a connection has been established, socket should send all
// the pending data and close the socket engine automatically.
QVERIFY(socket->putChar(0));
socket->close();
QVERIFY2(socket->waitForConnected(), (hostName.toLocal8Bit() + ": " + QByteArray::number(port) + ' '
+ QtNetworkSettings::msgSocketError(*socket)).constData());

View File

@ -46,6 +46,7 @@ class tst_QObjectRace: public QObject
private slots:
void moveToThreadRace();
void destroyRace();
void disconnectRace();
};
class RaceObject : public QObject
@ -293,6 +294,180 @@ void tst_QObjectRace::destroyRace()
delete threads[i];
}
static QAtomicInteger<unsigned> countedStructObjectsCount;
struct CountedFunctor
{
CountedFunctor() : destroyed(false) { countedStructObjectsCount.fetchAndAddRelaxed(1); }
CountedFunctor(const CountedFunctor &) : destroyed(false) { countedStructObjectsCount.fetchAndAddRelaxed(1); }
CountedFunctor &operator=(const CountedFunctor &) { return *this; }
~CountedFunctor() { destroyed = true; countedStructObjectsCount.fetchAndAddRelaxed(-1);}
void operator()() const {QCOMPARE(destroyed, false);}
private:
bool destroyed;
};
class DisconnectRaceSenderObject : public QObject
{
Q_OBJECT
signals:
void theSignal();
};
class DisconnectRaceThread : public QThread
{
Q_OBJECT
DisconnectRaceSenderObject *sender;
bool emitSignal;
public:
DisconnectRaceThread(DisconnectRaceSenderObject *s, bool emitIt)
: QThread(), sender(s), emitSignal(emitIt)
{
}
void run()
{
while (!isInterruptionRequested()) {
QMetaObject::Connection conn = connect(sender, &DisconnectRaceSenderObject::theSignal,
sender, CountedFunctor(), Qt::BlockingQueuedConnection);
if (emitSignal)
emit sender->theSignal();
disconnect(conn);
yieldCurrentThread();
}
}
};
class DeleteReceiverRaceSenderThread : public QThread
{
Q_OBJECT
DisconnectRaceSenderObject *sender;
public:
DeleteReceiverRaceSenderThread(DisconnectRaceSenderObject *s)
: QThread(), sender(s)
{
}
void run()
{
while (!isInterruptionRequested()) {
emit sender->theSignal();
yieldCurrentThread();
}
}
};
class DeleteReceiverRaceReceiver : public QObject
{
Q_OBJECT
DisconnectRaceSenderObject *sender;
QObject *receiver;
QTimer *timer;
public:
DeleteReceiverRaceReceiver(DisconnectRaceSenderObject *s)
: QObject(), sender(s), receiver(0)
{
timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &DeleteReceiverRaceReceiver::onTimeout);
timer->start(1);
}
void onTimeout()
{
if (receiver)
delete receiver;
receiver = new QObject;
connect(sender, &DisconnectRaceSenderObject::theSignal, receiver, CountedFunctor(), Qt::BlockingQueuedConnection);
}
};
class DeleteReceiverRaceReceiverThread : public QThread
{
Q_OBJECT
DisconnectRaceSenderObject *sender;
public:
DeleteReceiverRaceReceiverThread(DisconnectRaceSenderObject *s)
: QThread(), sender(s)
{
}
void run()
{
QScopedPointer<DeleteReceiverRaceReceiver> receiver(new DeleteReceiverRaceReceiver(sender));
exec();
}
};
void tst_QObjectRace::disconnectRace()
{
enum { ThreadCount = 20, TimeLimit = 3000 };
QCOMPARE(countedStructObjectsCount.load(), 0u);
{
QScopedPointer<DisconnectRaceSenderObject> sender(new DisconnectRaceSenderObject());
QScopedPointer<QThread> senderThread(new QThread());
senderThread->start();
sender->moveToThread(senderThread.data());
DisconnectRaceThread *threads[ThreadCount];
for (int i = 0; i < ThreadCount; ++i) {
threads[i] = new DisconnectRaceThread(sender.data(), !(i % 10));
threads[i]->start();
}
QTime timeLimiter;
timeLimiter.start();
while (timeLimiter.elapsed() < TimeLimit)
QTest::qWait(10);
for (int i = 0; i < ThreadCount; ++i) {
threads[i]->requestInterruption();
QVERIFY(threads[i]->wait(300));
delete threads[i];
}
senderThread->quit();
QVERIFY(senderThread->wait(300));
}
QCOMPARE(countedStructObjectsCount.load(), 0u);
{
QScopedPointer<DisconnectRaceSenderObject> sender(new DisconnectRaceSenderObject());
QScopedPointer<DeleteReceiverRaceSenderThread> senderThread(new DeleteReceiverRaceSenderThread(sender.data()));
senderThread->start();
sender->moveToThread(senderThread.data());
DeleteReceiverRaceReceiverThread *threads[ThreadCount];
for (int i = 0; i < ThreadCount; ++i) {
threads[i] = new DeleteReceiverRaceReceiverThread(sender.data());
threads[i]->start();
}
QTime timeLimiter;
timeLimiter.start();
while (timeLimiter.elapsed() < TimeLimit)
QTest::qWait(10);
senderThread->requestInterruption();
QVERIFY(senderThread->wait(300));
for (int i = 0; i < ThreadCount; ++i) {
threads[i]->quit();
QVERIFY(threads[i]->wait(300));
delete threads[i];
}
}
QCOMPARE(countedStructObjectsCount.load(), 0u);
}
QTEST_MAIN(tst_QObjectRace)
#include "tst_qobjectrace.moc"

View File

@ -2034,6 +2034,13 @@ void tst_Moc::warnings_data()
<< 0
<< QString("IGNORE_ALL_STDOUT")
<< QStringLiteral("Warning: Failed to resolve include \"doesnotexist.h\" for moc file <standard input>");
QTest::newRow("QTBUG-54815: Crash on invalid input")
<< QByteArray("class M{(})F<{}d000000000000000#0")
<< QStringList()
<< 0
<< QString()
<< QString("standard input:1: Note: No relevant classes found. No output generated.");
}
void tst_Moc::warnings()

View File

@ -1,6 +1,6 @@
CONFIG += testcase
TARGET = tst_qitemdelegate
QT += widgets testlib
QT += widgets widgets-private testlib
SOURCES += tst_qitemdelegate.cpp
win32:!winrt: LIBS += -luser32

View File

@ -51,6 +51,8 @@
#include <QPlainTextEdit>
#include <QDialog>
#include <QtWidgets/private/qabstractitemdelegate_p.h>
Q_DECLARE_METATYPE(QAbstractItemDelegate::EndEditHint)
#if defined (Q_OS_WIN) && !defined(Q_OS_WINRT)
@ -216,6 +218,8 @@ private slots:
void task257859_finalizeEdit();
void QTBUG4435_keepSelectionOnCheck();
void QTBUG16469_textForRole();
};
@ -1521,6 +1525,64 @@ void tst_QItemDelegate::testLineEditValidation()
QCOMPARE(item->data(Qt::DisplayRole).toString(), QStringLiteral("abc,def"));
}
void tst_QItemDelegate::QTBUG16469_textForRole()
{
#ifndef QT_BUILD_INTERNAL
QSKIP("This test requires a developer build");
#else
struct TestDelegate : public QItemDelegate
{
QString textForRole(Qt::ItemDataRole role, const QVariant &value, const QLocale &locale)
{
QAbstractItemDelegatePrivate *d = reinterpret_cast<QAbstractItemDelegatePrivate *>(qGetPtrHelper(d_ptr));
return d->textForRole(role, value, locale);
}
} delegate;
QLocale locale;
const float f = 123.456f;
QCOMPARE(delegate.textForRole(Qt::DisplayRole, f, locale), locale.toString(f));
QCOMPARE(delegate.textForRole(Qt::ToolTipRole, f, locale), locale.toString(f));
const double d = 123.456;
QCOMPARE(delegate.textForRole(Qt::DisplayRole, d, locale), locale.toString(d, 'g', 6));
QCOMPARE(delegate.textForRole(Qt::ToolTipRole, d, locale), locale.toString(d, 'g', 6));
const int i = 1234567;
QCOMPARE(delegate.textForRole(Qt::DisplayRole, i, locale), locale.toString(i));
QCOMPARE(delegate.textForRole(Qt::ToolTipRole, i, locale), locale.toString(i));
const qlonglong ll = 1234567;
QCOMPARE(delegate.textForRole(Qt::DisplayRole, ll, locale), locale.toString(ll));
QCOMPARE(delegate.textForRole(Qt::ToolTipRole, ll, locale), locale.toString(ll));
const uint ui = 1234567;
QCOMPARE(delegate.textForRole(Qt::DisplayRole, ui, locale), locale.toString(ui));
QCOMPARE(delegate.textForRole(Qt::ToolTipRole, ui, locale), locale.toString(ui));
const qulonglong ull = 1234567;
QCOMPARE(delegate.textForRole(Qt::DisplayRole, ull, locale), locale.toString(ull));
QCOMPARE(delegate.textForRole(Qt::ToolTipRole, ull, locale), locale.toString(ull));
const QDateTime dateTime = QDateTime::currentDateTime();
const QDate date = dateTime.date();
const QTime time = dateTime.time();
const QString shortDate = locale.toString(date, QLocale::ShortFormat);
const QString longDate = locale.toString(date, QLocale::LongFormat);
const QString shortTime = locale.toString(time, QLocale::ShortFormat);
const QString longTime = locale.toString(time, QLocale::LongFormat);
QCOMPARE(delegate.textForRole(Qt::DisplayRole, date, locale), shortDate);
QCOMPARE(delegate.textForRole(Qt::ToolTipRole, date, locale), longDate);
QCOMPARE(delegate.textForRole(Qt::DisplayRole, time, locale), shortTime);
QCOMPARE(delegate.textForRole(Qt::ToolTipRole, time, locale), longTime);
QCOMPARE(delegate.textForRole(Qt::DisplayRole, dateTime, locale), shortDate + QLatin1Char(' ') + shortTime);
QCOMPARE(delegate.textForRole(Qt::ToolTipRole, dateTime, locale), longDate + QLatin1Char(' ') + longTime);
const QString text("text");
QCOMPARE(delegate.textForRole(Qt::DisplayRole, text, locale), text);
QCOMPARE(delegate.textForRole(Qt::ToolTipRole, text, locale), text);
const QString multipleLines("multiple\nlines");
QString multipleLines2 = multipleLines;
multipleLines2.replace(QLatin1Char('\n'), QChar::LineSeparator);
QCOMPARE(delegate.textForRole(Qt::DisplayRole, multipleLines, locale), multipleLines2);
QCOMPARE(delegate.textForRole(Qt::ToolTipRole, multipleLines, locale), multipleLines);
#endif
}
// ### _not_ covered:

View File

@ -0,0 +1,7 @@
TEMPLATE = app
QT += gui-private
CONFIG += console c++11
CONFIG -= app_bundle
SOURCES += main.cpp itemwindow.cpp
HEADERS += itemwindow.h
include(../diaglib/diaglib.pri)

View File

@ -0,0 +1,72 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "itemwindow.h"
#include <QtGui/QPainter>
#include <QtGui/QPaintEvent>
void TextItem::paint(QPainter &painter)
{
painter.fillRect(m_rect, m_col);
painter.drawRect(m_rect);
QTextOption textOption;
textOption.setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
painter.drawText(m_rect, m_text, textOption);
}
void ButtonItem::mouseEvent(QMouseEvent *mouseEvent)
{
if (mouseEvent->type() == QEvent::MouseButtonPress && rect().contains(mouseEvent->pos())) {
mouseEvent->accept();
emit clicked();
}
}
void ButtonItem::keyEvent(QKeyEvent *keyEvent)
{
if (m_shortcut && keyEvent->type() == QEvent::KeyPress
&& (keyEvent->key() + int(keyEvent->modifiers())) == m_shortcut) {
keyEvent->accept();
emit clicked();
}
}
void ItemWindow::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QRect rect(QPoint(0, 0), size());
painter.fillRect(rect, m_background);
foreach (Item *i, m_items)
i->paint(painter);
}

View File

@ -0,0 +1,126 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef ITEMWINDOW_H
#define ITEMWINDOW_H
#include <QtGui/QKeySequence>
#include <QtGui/QRasterWindow>
QT_USE_NAMESPACE
// ItemWindow: Primitive UI item classes for use with a ItemWindow based
// on QRasterWindow without widgets allowing a simple UI without widgets.
// Basic item to be used in a ItemWindow
class Item : public QObject {
Q_OBJECT
public:
explicit Item(QObject *parent = nullptr) : QObject(parent) {}
virtual void paint(QPainter &painter) = 0;
virtual void mouseEvent(QMouseEvent *) {}
virtual void keyEvent(QKeyEvent *) {}
};
// Positionable text item
class TextItem : public Item {
Q_OBJECT
public:
explicit TextItem(const QString &text, const QRect &rect, const QColor &col,
QObject *parent = nullptr)
: Item(parent), m_text(text), m_rect(rect), m_col(col) {}
void paint(QPainter &painter) override;
QRect rect() const { return m_rect; }
private:
const QString m_text;
const QRect m_rect;
const QColor m_col;
};
// "button" item
class ButtonItem : public TextItem {
Q_OBJECT
public:
explicit ButtonItem(const QString &text, const QRect &rect, const QColor &col,
QObject *parent = nullptr)
: TextItem(text, rect, col, parent), m_shortcut(0) {}
void mouseEvent(QMouseEvent *mouseEvent) override;
void keyEvent(QKeyEvent *keyEvent) override;
int shortcut() const { return m_shortcut; }
void setShortcut(int shortcut) { m_shortcut = shortcut; }
signals:
void clicked();
private:
int m_shortcut;
};
#define PROPAGATE_EVENT(windowHandler, eventClass, itemHandler) \
void windowHandler(eventClass *e) override \
{ \
foreach (Item *i, m_items) \
i->itemHandler(e); \
}
class ItemWindow : public QRasterWindow {
Q_OBJECT
public:
explicit ItemWindow(QWindow *parent = nullptr) : QRasterWindow(parent), m_background(Qt::white) {}
void addItem(Item *item) { m_items.append(item); }
QColor background() const { return m_background; }
void setBackground(const QColor &background) { m_background = background; }
protected:
void paintEvent(QPaintEvent *) override;
PROPAGATE_EVENT(mousePressEvent, QMouseEvent, mouseEvent)
PROPAGATE_EVENT(mouseReleaseEvent, QMouseEvent, mouseEvent)
PROPAGATE_EVENT(mouseDoubleClickEvent, QMouseEvent, mouseEvent)
PROPAGATE_EVENT(mouseMoveEvent, QMouseEvent, mouseEvent)
PROPAGATE_EVENT(keyPressEvent, QKeyEvent, keyEvent)
PROPAGATE_EVENT(keyReleaseEvent, QKeyEvent, keyEvent)
private:
QList<Item *> m_items;
QColor m_background;
};
#endif // ITEMWINDOW_H

View File

@ -0,0 +1,287 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "itemwindow.h"
#include <QtGui/QGuiApplication>
#include <QtCore/QCommandLineOption>
#include <QtCore/QCommandLineParser>
#include <QtCore/QDebug>
#include <QtCore/QStringList>
#ifdef Q_OS_WIN
# include <qpa/qplatformnativeinterface.h>
# include <QtCore/QMetaObject>
# include <QtCore/qt_windows.h>
#endif
#include <eventfilter.h> // diaglib
#include <qwindowdump.h>
#include <iostream>
QT_USE_NAMESPACE
static const char usage[] =
"\nEmbeds a QWindow into a native foreign window passed on the command line.\n"
"When no window ID is passed, a test window is created (Windows only).";
static QString windowTitle()
{
return QLatin1String(QT_VERSION_STR) + QLatin1Char(' ') + QGuiApplication::platformName();
}
#ifdef Q_OS_WIN
// Helper to create a native test window (Windows)
static QString registerWindowClass(const QString &name)
{
QString result;
void *proc = DefWindowProc;
QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface();
if (!QMetaObject::invokeMethod(ni, "registerWindowClass", Qt::DirectConnection,
Q_RETURN_ARG(QString, result),
Q_ARG(QString, name),
Q_ARG(void *, proc))) {
qWarning("registerWindowClass failed");
}
return result;
}
static HWND createNativeWindow(const QString &name)
{
const HWND hwnd =
CreateWindowEx(0, reinterpret_cast<const wchar_t *>(name.utf16()),
L"NativeWindow", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
0, 0, GetModuleHandle(NULL), NULL);
if (!hwnd) {
qErrnoWarning("Cannot create window \"%s\"", qPrintable(name));
return 0;
}
const QString text = windowTitle() + QLatin1String(" 0x") + QString::number(quint64(hwnd), 16);
SetWindowText(hwnd, reinterpret_cast<const wchar_t *>(text.utf16()));
return hwnd;
}
#endif // Q_OS_WIN
// Helper functions for simple management of native windows.
static WId createNativeTestWindow()
{
WId result = 0;
#ifdef Q_OS_WIN
const QString className = registerWindowClass(QLatin1String("TestClass") + windowTitle());
const HWND nativeWin = createNativeWindow(className);
result = WId(nativeWin);
#else // Q_OS_WIN
Q_UNIMPLEMENTED();
#endif
return result;
}
static void showNativeWindow(WId wid)
{
#ifdef Q_OS_WIN
ShowWindow(HWND(wid), SW_SHOW);
#else // Q_OS_WIN
Q_UNUSED(wid)
Q_UNIMPLEMENTED();
#endif
}
static void setFocusToNativeWindow(WId wid)
{
#ifdef Q_OS_WIN
SetFocus(HWND(wid));
#else // Q_OS_WIN
Q_UNUSED(wid)
Q_UNIMPLEMENTED();
#endif
}
static void destroyNativeWindow(WId wid)
{
#ifdef Q_OS_WIN
DestroyWindow(HWND(wid));
#else // Q_OS_WIN
Q_UNUSED(wid)
Q_UNIMPLEMENTED();
#endif
}
// Main test window to be embedded into foreign window with some buttons.
class EmbeddedTestWindow : public ItemWindow {
Q_OBJECT
public:
explicit EmbeddedTestWindow(QWindow *parent = nullptr) : ItemWindow(parent)
{
const int spacing = 10;
const QSize buttonSize(100, 30);
const int width = 3 * buttonSize.width() + 4 * spacing;
QPoint pos(spacing, spacing);
addItem(new TextItem(::windowTitle(), QRect(pos, QSize(width - 2 * spacing, buttonSize.height())),
Qt::white));
pos.ry() += 2 * spacing + buttonSize.height();
ButtonItem *mgi = new ButtonItem("Map to global", QRect(pos, buttonSize),
QColor(Qt::yellow).lighter(), this);
connect(mgi, &ButtonItem::clicked, this, &EmbeddedTestWindow::testMapToGlobal);
addItem(mgi);
pos.rx() += buttonSize.width() + spacing;
ButtonItem *di = new ButtonItem("Dump Wins", QRect(pos, buttonSize),
QColor(Qt::cyan).lighter(), this);
connect(di, &ButtonItem::clicked, this, [] () { QtDiag::dumpAllWindows(); });
addItem(di);
pos.rx() += buttonSize.width() + spacing;
ButtonItem *qi = new ButtonItem("Quit", QRect(pos, buttonSize),
QColor(Qt::red).lighter(), this);
qi->setShortcut(Qt::CTRL + Qt::Key_Q);
connect(qi, &ButtonItem::clicked, qApp, &QCoreApplication::quit);
addItem(qi);
setBackground(Qt::lightGray);
resize(width, pos.y() + buttonSize.height() + spacing);
}
public slots:
void testMapToGlobal();
};
void EmbeddedTestWindow::testMapToGlobal()
{
const QPoint globalPos = mapToGlobal(QPoint(0,0));
qDebug() << "mapToGlobal(QPoint(0,0)" << globalPos
<< "cursor at:" << QCursor::pos();
}
struct EventFilterOption
{
const char *name;
const char *description;
QtDiag::EventFilter::EventCategories categories;
};
EventFilterOption eventFilterOptions[] = {
{"mouse-events", "Dump mouse events.", QtDiag::EventFilter::MouseEvents},
{"keyboard-events", "Dump keyboard events.", QtDiag::EventFilter::KeyEvents},
{"state-events", "Dump state/focus change events.", QtDiag::EventFilter::StateChangeEvents | QtDiag::EventFilter::FocusEvents}
};
static inline bool isOptionSet(int argc, char *argv[], const char *option)
{
return (argv + argc) !=
std::find_if(argv + 1, argv + argc,
[option] (const char *arg) { return !qstrcmp(arg, option); });
}
int main(int argc, char *argv[])
{
// Check for no scaling before QApplication is instantiated.
if (isOptionSet(argc, argv, "-s"))
QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
QGuiApplication::setApplicationDisplayName("Foreign Window Embedding Tester");
QGuiApplication app(argc, argv);
// Process command line
QCommandLineParser parser;
parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
parser.setApplicationDescription(QLatin1String(usage));
parser.addHelpOption();
parser.addVersionOption();
QCommandLineOption noScalingDummy(QStringLiteral("s"),
QStringLiteral("Disable High DPI scaling."));
parser.addOption(noScalingDummy);
const int eventFilterOptionCount = int(sizeof(eventFilterOptions) / sizeof(eventFilterOptions[0]));
for (int i = 0; i < eventFilterOptionCount; ++i) {
parser.addOption(QCommandLineOption(QLatin1String(eventFilterOptions[i].name),
QLatin1String(eventFilterOptions[i].description)));
}
parser.addPositionalArgument(QStringLiteral("[windows]"), QStringLiteral("Window ID."));
parser.process(QCoreApplication::arguments());
QtDiag::EventFilter::EventCategories eventCategories = 0;
for (int i = 0; i < eventFilterOptionCount; ++i) {
if (parser.isSet(QLatin1String(eventFilterOptions[i].name)))
eventCategories |= eventFilterOptions[i].categories;
}
if (eventCategories)
app.installEventFilter(new QtDiag::EventFilter(eventCategories, &app));
// Obtain foreign window to test with.
WId testForeignWinId = 0;
bool createdTestWindow = false;
if (parser.positionalArguments().isEmpty()) {
testForeignWinId = createNativeTestWindow();
if (!testForeignWinId)
parser.showHelp(-1);
showNativeWindow(testForeignWinId);
createdTestWindow = true;
} else {
bool ok;
const QString &winIdArgument = parser.positionalArguments().constFirst();
testForeignWinId = winIdArgument.toULongLong(&ok, 0);
if (!ok) {
std::cerr << "Invalid window id: \"" << qPrintable(winIdArgument) << "\"\n";
return -1;
}
}
if (!testForeignWinId)
parser.showHelp(1);
QWindow *foreignWindow = QWindow::fromWinId(testForeignWinId);
if (!foreignWindow)
return -2;
foreignWindow->setObjectName("ForeignWindow");
EmbeddedTestWindow *embeddedTestWindow = new EmbeddedTestWindow(foreignWindow);
embeddedTestWindow->setObjectName("EmbeddedTestWindow");
embeddedTestWindow->show();
setFocusToNativeWindow(embeddedTestWindow->winId()); // Windows: Set keyboard focus.
const int exitCode = app.exec();
delete embeddedTestWindow;
delete foreignWindow;
if (createdTestWindow)
destroyNativeWindow(testForeignWinId);
return exitCode;
}
#include "main.moc"

View File

@ -2,8 +2,10 @@ TEMPLATE=subdirs
SUBDIRS = bearerex \
filetest \
embeddedintoforeignwindow \
foreignwindows \
gestures \
highdpi \
inputmethodhints \
keypadnavigation \
lance \
@ -62,4 +64,4 @@ win32: SUBDIRS -= network_remote_stresstest network_stresstest
lessThan(QT_MAJOR_VERSION, 5): SUBDIRS -= bearerex lance qnetworkaccessmanager/qget qmimedatabase qnetworkreply \
qpainfo qscreen socketengine xembed-raster xembed-widgets windowtransparency \
foreignwindows
embeddedintoforeignwindow foreignwindows

View File

@ -2135,12 +2135,7 @@ void Configure::autoDetection()
detectArch();
if (dictionary["C++STD"] == "auto" && !dictionary["QMAKESPEC"].contains("msvc")) {
if (!tryCompileProject("common/c++11")) {
dictionary["DONE"] = "error";
cout << "ERROR: Qt requires a C++11 compiler and yours does not seem to be that." << endl
<< "Please upgrade." << endl;
return;
} else if (!tryCompileProject("common/c++14")) {
if (!tryCompileProject("common/c++14")) {
dictionary["C++STD"] = "c++11";
} else if (!tryCompileProject("common/c++1z")) {
dictionary["C++STD"] = "c++14";