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

Conflicts:
	configure
	src/plugins/platforms/eglfs/qeglfsintegration.cpp
	src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp

Change-Id: Id2da7c775439adb62646d5b741ee7c638042b34b
This commit is contained in:
Liang Qi 2016-11-15 09:51:41 +01:00
commit 9808b53fde
96 changed files with 831 additions and 332 deletions

View File

@ -40,6 +40,7 @@
#ifdef __APPLE__ #ifdef __APPLE__
#include <OpenGL/gl.h> #include <OpenGL/gl.h>
#else #else
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h> #include <GL/gl.h>
#endif #endif

View File

@ -40,6 +40,7 @@
#ifdef BUILD_ON_MAC #ifdef BUILD_ON_MAC
#include <OpenGLES/ES2/gl.h> #include <OpenGLES/ES2/gl.h>
#else #else
#define GL_GLEXT_PROTOTYPES
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#endif #endif

View File

@ -40,6 +40,7 @@
#ifdef BUILD_ON_MAC #ifdef BUILD_ON_MAC
#include <OpenGLES/ES3/gl.h> #include <OpenGLES/ES3/gl.h>
#else #else
#define GL_GLEXT_PROTOTYPES
#include <GLES3/gl3.h> #include <GLES3/gl3.h>
#endif #endif

6
configure vendored
View File

@ -3125,14 +3125,14 @@ if [ "$Edition" = "OpenSource" ]; then
while true; do while true; do
if [ "$CFG_ANDROID_STYLE_ASSETS" = "no" ] || [ "$XPLATFORM_ANDROID" = "no" ]; then if [ "$CFG_ANDROID_STYLE_ASSETS" = "no" ] || [ "$XPLATFORM_ANDROID" = "no" ]; then
echo "You are licensed to use this software under the terms of" echo "You are licensed to use this software under the terms of"
echo "the GNU Lesser General Public License (LGPL) versions 3." echo "the GNU Lesser General Public License (LGPL) version 3."
echo "You are also licensed to use this software under the terms of" echo "You are also licensed to use this software under the terms of"
echo "the GNU General Public License (GPL) versions 2." echo "the GNU General Public License (GPL) version 2."
affix="either" affix="either"
showGPL2="yes" showGPL2="yes"
else else
echo "You are licensed to use this software under the terms of" echo "You are licensed to use this software under the terms of"
echo "the GNU Lesser General Public License (LGPL) versions 3." echo "the GNU Lesser General Public License (LGPL) version 3."
showGPL2="no" showGPL2="no"
affix="the" affix="the"
fi fi

View File

@ -1,114 +0,0 @@
MAKEFILE_GENERATOR = UNIX
QMAKE_INCREMENTAL_STYLE = sublib
QMAKE_PLATFORM += android
include(linux.conf)
include(gcc-base-unix.conf)
DEFINES += QT_NO_PRINTER QT_NO_PRINTDIALOG
QT_QPA_DEFAULT_PLATFORM = minimal
NDK_ROOT = $$(ANDROID_NDK_ROOT)
isEmpty(NDK_ROOT): error("$ANDROID_NDK_ROOT is empty, please set it to something like ~/android/ndk-r7c")
NDK_HOST = $$(ANDROID_NDK_HOST)
isEmpty(NDK_HOST): error("$ANDROID_NDK_HOST is empty, please set it to something like linux-x86 or darwin-x86")
ANDROID_PLATFORM = $$(ANDROID_NDK_PLATFORM)
isEmpty(ANDROID_PLATFORM): ANDROID_PLATFORM = android-5
NDK_TOOLCHAIN_VERSION = $$(ANDROID_NDK_TOOLCHAIN_VERSION)
isEmpty(NDK_TOOLCHAIN_VERSION): NDK_TOOLCHAIN_VERSION = 4.4.3
!contains(NDK_TOOLCHAIN_VERSION, 4.4.3): ANDROID_CXXSTL_SUFFIX = -$$NDK_TOOLCHAIN_VERSION
NDK_TOOLCHAIN = $$ANDROID_NDK_TOOLCHAIN_PREFIX-$$NDK_TOOLCHAIN_VERSION
NDK_TOOLCHAIN_PATH = $$NDK_ROOT/toolchains/$$NDK_TOOLCHAIN/prebuilt/$$NDK_HOST
CONFIG += $$ANDROID_PLATFORM $$ANDROID_TARGET_ARCH
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 = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/usr/include
QMAKE_ANDROID_PLATFORM_LIBDIR = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/usr/lib
ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl$$ANDROID_CXXSTL_SUFFIX/gnu-libstdc++/libs/$$ANDROID_TARGET_ARCH
ANDROID_SOURCES_CXX_STL_INCDIR = $$NDK_ROOT/sources/cxx-stl$$ANDROID_CXXSTL_SUFFIX/gnu-libstdc++/include $$ANDROID_SOURCES_CXX_STL_LIBDIR/include
# modifications to g++.conf
QMAKE_CC = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-gcc
QMAKE_CFLAGS_WARN_ON = -Wall -Wextra
QMAKE_CFLAGS_WARN_OFF = -Wno-psabi
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/$$ANDROID_NDK_TOOLS_PREFIX-g++
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_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_LINK = $$QMAKE_CXX
QMAKE_LINK_SHLIB = $$QMAKE_LINK
# modifications to linux.conf
QMAKE_AR = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-ar cqs
QMAKE_OBJCOPY = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-objcopy
QMAKE_NM = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-nm -P
QMAKE_STRIP = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-strip
QMAKE_RANLIB = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-ranlib
QMAKE_INCDIR = $$ANDROID_PLATFORM_PATH/include $$ANDROID_SOURCES_CXX_STL_INCDIR
QMAKE_LIBDIR = $$ANDROID_SOURCES_CXX_STL_LIBDIR $$ANDROID_PLATFORM_PATH/lib
QMAKE_INCDIR_X11 =
QMAKE_LIBDIR_X11 =
QMAKE_INCDIR_OPENGL =
QMAKE_INCDIR_OPENGL_ES2 =
QMAKE_LIBDIR_OPENGL_ES2 =
contains(ANDROID_TARGET_ARCH, x86): LIBGCC_PATH_FULL = $$system($$QMAKE_CC -print-libgcc-file-name)
else: LIBGCC_PATH_FULL = $$system($$QMAKE_CC -mthumb-interwork -print-libgcc-file-name)
QMAKE_LINK = $$QMAKE_CXX
QMAKE_LINK_SHLIB = $$QMAKE_CXX
QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH -L$$dirname(LIBGCC_PATH_FULL) -Wl,-rpath-link=$$ANDROID_PLATFORM_PATH/lib
QMAKE_LFLAGS_APP =
QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared
contains(NDK_ROOT, ".*r[56].*") {
!contains(ANDROID_PLATFORM, ".*android-[458].*") {
message("Your NDK-version is out-dated. A work-around is enabled. Consider updating your NDK (workarounds are required until r6(a))")
QMAKE_LFLAGS_SHLIB += $$ANDROID_PLATFORM_PATH/lib/crtbegin_so.o $$ANDROID_PLATFORM_PATH/lib/crtend_so.o
}
}
QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
QMAKE_LFLAGS_SONAME =
QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined
QMAKE_LFLAGS_RPATH = -Wl,-rpath=
# TODO: -lgnustl_static was -lstdc++, but that leads to undefined reference to
# std::__throw_bad_alloc during configure.
QMAKE_LIBS = -lsupc++ -llog -lz -lm -ldl -lc -lgcc -lgnustl_static
QMAKE_LIBS_X11 =
QMAKE_LIBS_X11SM =
QMAKE_LIBS_QT_THREAD =
QMAKE_LIBS_QT_OPENGL =
QMAKE_LIBS_QTOPIA =
QMAKE_LIBS_THREAD =
QMAKE_LIBS_OPENGL =
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 $$QMAKE_LIBS
load(qt_config)

View File

@ -65,7 +65,7 @@
actool_output_files = $$system(\ actool_output_files = $$system(\
mkdir -p $$system_quote($$QMAKE_ASSET_CATALOGS_BUILD_PATH) && \ mkdir -p $$system_quote($$QMAKE_ASSET_CATALOGS_BUILD_PATH) && \
/usr/libexec/PlistBuddy -c \'Print :com.apple.actool.compilation-results:output-files\' \ /usr/libexec/PlistBuddy -c \'Print :com.apple.actool.compilation-results:output-files\' \
/dev/stdin <<< $($${asset_catalog_compiler.commands} 2>/dev/null) | grep \'^ .*$\', lines) /dev/stdin <<< $($${asset_catalog_compiler.commands} 2>/dev/null) | sed -Ene \'s/^ +//p\', lines)
for (output_file, actool_output_files) { for (output_file, actool_output_files) {
!equals(output_file, $$asset_catalog_compiler.target): \ !equals(output_file, $$asset_catalog_compiler.target): \

View File

@ -1158,6 +1158,21 @@ static inline QString toString(subSystemOption option)
return QString(); return QString();
} }
static inline QString toString(triState genDebugInfo, linkerDebugOption option)
{
switch (genDebugInfo) {
case unset:
break;
case _False:
return "false";
case _True:
if (option == linkerDebugOptionFastLink)
return "DebugFastLink";
return "true";
}
return QString();
}
static inline QString toString(machineTypeOption option) static inline QString toString(machineTypeOption option)
{ {
switch (option) { switch (option) {
@ -1536,7 +1551,7 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCLinkerTool &tool)
<< attrTagS(_EntryPointSymbol, tool.EntryPointSymbol) << attrTagS(_EntryPointSymbol, tool.EntryPointSymbol)
<< attrTagX(_ForceSymbolReferences, tool.ForceSymbolReferences, ";") << attrTagX(_ForceSymbolReferences, tool.ForceSymbolReferences, ";")
<< attrTagS(_FunctionOrder, tool.FunctionOrder) << attrTagS(_FunctionOrder, tool.FunctionOrder)
<< attrTagT(_GenerateDebugInformation, tool.GenerateDebugInformation) << attrTagS(_GenerateDebugInformation, toString(tool.GenerateDebugInformation, tool.DebugInfoOption))
<< attrTagT(_GenerateManifest, tool.GenerateManifest) << attrTagT(_GenerateManifest, tool.GenerateManifest)
<< attrTagT(_GenerateWindowsMetadata, tool.GenerateWindowsMetadata) << attrTagT(_GenerateWindowsMetadata, tool.GenerateWindowsMetadata)
<< attrTagS(_WindowsMetadataFile, tool.GenerateWindowsMetadata == _True ? tool.WindowsMetadataFile : QString()) << attrTagS(_WindowsMetadataFile, tool.GenerateWindowsMetadata == _True ? tool.WindowsMetadataFile : QString())

View File

@ -1425,8 +1425,10 @@ bool VCLinkerTool::parseOption(const char* option)
}else }else
EnableUAC = _True; EnableUAC = _True;
break; break;
case 0x3389797: // /DEBUG case 0x3389797: // /DEBUG[:FASTLINK]
GenerateDebugInformation = _True; GenerateDebugInformation = _True;
if (config->CompilerVersion >= NET2015 && strcmp(option + 7, "FASTLINK") == 0)
DebugInfoOption = linkerDebugOptionFastLink;
break; break;
case 0x0033896: // /DEF:filename case 0x0033896: // /DEF:filename
ModuleDefinitionFile = option+5; ModuleDefinitionFile = option+5;

View File

@ -277,6 +277,10 @@ enum inlineExpansionOption {
expandAnySuitable, expandAnySuitable,
expandDefault // Not useful number, but stops the output expandDefault // Not useful number, but stops the output
}; };
enum linkerDebugOption {
linkerDebugOptionNone,
linkerDebugOptionFastLink
};
enum linkIncrementalType { enum linkIncrementalType {
linkIncrementalDefault, linkIncrementalDefault,
linkIncrementalNo, linkIncrementalNo,
@ -590,6 +594,7 @@ public:
QStringList ForceSymbolReferences; QStringList ForceSymbolReferences;
QString FunctionOrder; QString FunctionOrder;
triState GenerateDebugInformation; triState GenerateDebugInformation;
linkerDebugOption DebugInfoOption;
triState GenerateMapFile; triState GenerateMapFile;
qlonglong HeapCommitSize; qlonglong HeapCommitSize;
qlonglong HeapReserveSize; qlonglong HeapReserveSize;

View File

@ -481,8 +481,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
int end = -1; int end = -1;
if (func_t == E_SECTION) { if (func_t == E_SECTION) {
if (args.count() != 3 && args.count() != 4) { if (args.count() != 3 && args.count() != 4) {
evalError(fL1S("%1(var) section(var, sep, begin, end) requires" evalError(fL1S("section(var, sep, begin, end) requires three or four arguments."));
" three or four arguments.").arg(func.toQString(m_tmp1)));
} else { } else {
var = args[0]; var = args[0];
sep = args.at(1).toQString(); sep = args.at(1).toQString();

View File

@ -41,38 +41,41 @@ static const struct {
const char *name; const char *name;
QLibraryInfo::LibraryLocation loc; QLibraryInfo::LibraryLocation loc;
bool raw; bool raw;
bool singular;
} propList[] = { } propList[] = {
{ "QT_SYSROOT", QLibraryInfo::SysrootPath, true }, { "QT_SYSROOT", QLibraryInfo::SysrootPath, true, true },
{ "QT_INSTALL_PREFIX", QLibraryInfo::PrefixPath, false }, { "QT_INSTALL_PREFIX", QLibraryInfo::PrefixPath, false, false },
{ "QT_INSTALL_ARCHDATA", QLibraryInfo::ArchDataPath, false }, { "QT_INSTALL_ARCHDATA", QLibraryInfo::ArchDataPath, false, false },
{ "QT_INSTALL_DATA", QLibraryInfo::DataPath, false }, { "QT_INSTALL_DATA", QLibraryInfo::DataPath, false, false },
{ "QT_INSTALL_DOCS", QLibraryInfo::DocumentationPath, false }, { "QT_INSTALL_DOCS", QLibraryInfo::DocumentationPath, false, false },
{ "QT_INSTALL_HEADERS", QLibraryInfo::HeadersPath, false }, { "QT_INSTALL_HEADERS", QLibraryInfo::HeadersPath, false, false },
{ "QT_INSTALL_LIBS", QLibraryInfo::LibrariesPath, false }, { "QT_INSTALL_LIBS", QLibraryInfo::LibrariesPath, false, false },
{ "QT_INSTALL_LIBEXECS", QLibraryInfo::LibraryExecutablesPath, false }, { "QT_INSTALL_LIBEXECS", QLibraryInfo::LibraryExecutablesPath, false, false },
{ "QT_INSTALL_BINS", QLibraryInfo::BinariesPath, false }, { "QT_INSTALL_BINS", QLibraryInfo::BinariesPath, false, false },
{ "QT_INSTALL_TESTS", QLibraryInfo::TestsPath, false }, { "QT_INSTALL_TESTS", QLibraryInfo::TestsPath, false, false },
{ "QT_INSTALL_PLUGINS", QLibraryInfo::PluginsPath, false }, { "QT_INSTALL_PLUGINS", QLibraryInfo::PluginsPath, false, false },
{ "QT_INSTALL_IMPORTS", QLibraryInfo::ImportsPath, false }, { "QT_INSTALL_IMPORTS", QLibraryInfo::ImportsPath, false, false },
{ "QT_INSTALL_QML", QLibraryInfo::Qml2ImportsPath, false }, { "QT_INSTALL_QML", QLibraryInfo::Qml2ImportsPath, false, false },
{ "QT_INSTALL_TRANSLATIONS", QLibraryInfo::TranslationsPath, false }, { "QT_INSTALL_TRANSLATIONS", QLibraryInfo::TranslationsPath, false, false },
{ "QT_INSTALL_CONFIGURATION", QLibraryInfo::SettingsPath, false }, { "QT_INSTALL_CONFIGURATION", QLibraryInfo::SettingsPath, false, false },
{ "QT_INSTALL_EXAMPLES", QLibraryInfo::ExamplesPath, false }, { "QT_INSTALL_EXAMPLES", QLibraryInfo::ExamplesPath, false, false },
{ "QT_INSTALL_DEMOS", QLibraryInfo::ExamplesPath, false }, // Just backwards compat { "QT_INSTALL_DEMOS", QLibraryInfo::ExamplesPath, false, false }, // Just backwards compat
{ "QT_HOST_PREFIX", QLibraryInfo::HostPrefixPath, true }, { "QT_HOST_PREFIX", QLibraryInfo::HostPrefixPath, true, false },
{ "QT_HOST_DATA", QLibraryInfo::HostDataPath, true }, { "QT_HOST_DATA", QLibraryInfo::HostDataPath, true, false },
{ "QT_HOST_BINS", QLibraryInfo::HostBinariesPath, true }, { "QT_HOST_BINS", QLibraryInfo::HostBinariesPath, true, false },
{ "QT_HOST_LIBS", QLibraryInfo::HostLibrariesPath, true }, { "QT_HOST_LIBS", QLibraryInfo::HostLibrariesPath, true, false },
{ "QMAKE_SPEC", QLibraryInfo::HostSpecPath, true }, { "QMAKE_SPEC", QLibraryInfo::HostSpecPath, true, true },
{ "QMAKE_XSPEC", QLibraryInfo::TargetSpecPath, true }, { "QMAKE_XSPEC", QLibraryInfo::TargetSpecPath, true, true },
}; };
QMakeProperty::QMakeProperty() : settings(0) QMakeProperty::QMakeProperty() : settings(0)
{ {
for (unsigned i = 0; i < sizeof(propList)/sizeof(propList[0]); i++) { for (unsigned i = 0; i < sizeof(propList)/sizeof(propList[0]); i++) {
QString name = QString::fromLatin1(propList[i].name); QString name = QString::fromLatin1(propList[i].name);
m_values[ProKey(name + "/src")] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::EffectiveSourcePaths); if (!propList[i].singular) {
m_values[ProKey(name + "/get")] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::EffectivePaths); m_values[ProKey(name + "/src")] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::EffectiveSourcePaths);
m_values[ProKey(name + "/get")] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::EffectivePaths);
}
QString val = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::FinalPaths); QString val = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::FinalPaths);
if (!propList[i].raw) { if (!propList[i].raw) {
m_values[ProKey(name + "/dev")] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::DevicePaths); m_values[ProKey(name + "/dev")] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::DevicePaths);

View File

@ -135,10 +135,12 @@ bool Data::valid() const
return false; return false;
bool res = false; bool res = false;
if (header->root()->is_object) Base *root = header->root();
res = static_cast<Object *>(header->root())->isValid(); int maxSize = alloc - sizeof(Header);
if (root->is_object)
res = static_cast<Object *>(root)->isValid(maxSize);
else else
res = static_cast<Array *>(header->root())->isValid(); res = static_cast<Array *>(root)->isValid(maxSize);
return res; return res;
} }
@ -223,9 +225,9 @@ int Object::indexOf(QLatin1String key, bool *exists) const
return min; return min;
} }
bool Object::isValid() const bool Object::isValid(int maxSize) const
{ {
if (tableOffset + length*sizeof(offset) > size) if (size > (uint)maxSize || tableOffset + length*sizeof(offset) > size)
return false; return false;
QString lastKey; QString lastKey;
@ -234,8 +236,7 @@ bool Object::isValid() const
if (entryOffset + sizeof(Entry) >= tableOffset) if (entryOffset + sizeof(Entry) >= tableOffset)
return false; return false;
Entry *e = entryAt(i); Entry *e = entryAt(i);
int s = e->size(); if (!e->isValid(tableOffset - table()[i]))
if (table()[i] + s > tableOffset)
return false; return false;
QString key = e->key(); QString key = e->key();
if (key < lastKey) if (key < lastKey)
@ -249,9 +250,9 @@ bool Object::isValid() const
bool Array::isValid() const bool Array::isValid(int maxSize) const
{ {
if (tableOffset + length*sizeof(offset) > size) if (size > (uint)maxSize || tableOffset + length*sizeof(offset) > size)
return false; return false;
for (uint i = 0; i < length; ++i) { for (uint i = 0; i < length; ++i) {
@ -359,12 +360,12 @@ bool Value::isValid(const Base *b) const
int s = usedStorage(b); int s = usedStorage(b);
if (!s) if (!s)
return true; return true;
if (s < 0 || offset + s > (int)b->tableOffset) if (s < 0 || s > (int)b->tableOffset - offset)
return false; return false;
if (type == QJsonValue::Array) if (type == QJsonValue::Array)
return static_cast<Array *>(base(b))->isValid(); return static_cast<Array *>(base(b))->isValid(s);
if (type == QJsonValue::Object) if (type == QJsonValue::Object)
return static_cast<Object *>(base(b))->isValid(); return static_cast<Object *>(base(b))->isValid(s);
return true; return true;
} }

View File

@ -310,12 +310,19 @@ public:
explicit String(const char *data) { d = (Data *)data; } explicit String(const char *data) { d = (Data *)data; }
struct Data { struct Data {
qle_int length; qle_uint length;
qle_ushort utf16[1]; qle_ushort utf16[1];
}; };
Data *d; Data *d;
int byteSize() const { return sizeof(uint) + sizeof(ushort) * d->length; }
bool isValid(int maxSize) const {
// Check byteSize() <= maxSize, avoiding integer overflow
maxSize -= sizeof(uint);
return maxSize >= 0 && uint(d->length) <= maxSize / sizeof(ushort);
}
inline String &operator=(const QString &str) inline String &operator=(const QString &str)
{ {
d->length = str.length(); d->length = str.length();
@ -384,11 +391,16 @@ public:
explicit Latin1String(const char *data) { d = (Data *)data; } explicit Latin1String(const char *data) { d = (Data *)data; }
struct Data { struct Data {
qle_short length; qle_ushort length;
char latin1[1]; char latin1[1];
}; };
Data *d; Data *d;
int byteSize() const { return sizeof(ushort) + sizeof(char)*(d->length); }
bool isValid(int maxSize) const {
return byteSize() <= maxSize;
}
inline Latin1String &operator=(const QString &str) inline Latin1String &operator=(const QString &str)
{ {
int len = d->length = str.length(); int len = d->length = str.length();
@ -590,7 +602,7 @@ public:
int indexOf(const QString &key, bool *exists) const; int indexOf(const QString &key, bool *exists) const;
int indexOf(QLatin1String key, bool *exists) const; int indexOf(QLatin1String key, bool *exists) const;
bool isValid() const; bool isValid(int maxSize) const;
}; };
@ -600,7 +612,7 @@ public:
inline Value at(int i) const; inline Value at(int i) const;
inline Value &operator [](int i); inline Value &operator [](int i);
bool isValid() const; bool isValid(int maxSize) const;
}; };
@ -655,12 +667,12 @@ public:
// key // key
// value data follows key // value data follows key
int size() const { uint size() const {
int s = sizeof(Entry); int s = sizeof(Entry);
if (value.latinKey) if (value.latinKey)
s += sizeof(ushort) + qFromLittleEndian(*(ushort *) ((const char *)this + sizeof(Entry))); s += shallowLatin1Key().byteSize();
else else
s += sizeof(uint) + sizeof(ushort)*qFromLittleEndian(*(int *) ((const char *)this + sizeof(Entry))); s += shallowKey().byteSize();
return alignedSize(s); return alignedSize(s);
} }
@ -686,6 +698,15 @@ public:
return shallowKey().toString(); return shallowKey().toString();
} }
bool isValid(int maxSize) const {
if (maxSize < (int)sizeof(Entry))
return false;
maxSize -= sizeof(Entry);
if (value.latinKey)
return shallowLatin1Key().isValid(maxSize);
return shallowKey().isValid(maxSize);
}
bool operator ==(const QString &key) const; bool operator ==(const QString &key) const;
inline bool operator !=(const QString &key) const { return !operator ==(key); } inline bool operator !=(const QString &key) const { return !operator ==(key); }
inline bool operator >=(const QString &key) const; inline bool operator >=(const QString &key) const;
@ -698,8 +719,6 @@ public:
bool operator >=(const Entry &other) const; bool operator >=(const Entry &other) const;
}; };
inline bool operator!=(const Entry &lhs, const Entry &rhs) { return !(lhs == rhs); }
inline bool Entry::operator >=(const QString &key) const inline bool Entry::operator >=(const QString &key) const
{ {
if (value.latinKey) if (value.latinKey)

View File

@ -599,8 +599,8 @@ bool QJsonObject::operator==(const QJsonObject &other) const
for (uint i = 0; i < o->length; ++i) { for (uint i = 0; i < o->length; ++i) {
QJsonPrivate::Entry *e = o->entryAt(i); QJsonPrivate::Entry *e = o->entryAt(i);
QJsonPrivate::Entry *oe = other.o->entryAt(i); QJsonValue v(d, o, e->value);
if (*e != *oe || QJsonValue(d, o, e->value) != QJsonValue(other.d, other.o, oe->value)) if (other.value(e->key()) != v)
return false; return false;
} }

View File

@ -42,6 +42,7 @@
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>
#include <QtCore/QThread> #include <QtCore/QThread>
#include <QtCore/QHash> #include <QtCore/QHash>
#include <QtCore/QMutex>
#include <QtCore/qfunctions_winrt.h> #include <QtCore/qfunctions_winrt.h>
#include <private/qabstracteventdispatcher_p.h> #include <private/qabstracteventdispatcher_p.h>
#include <private/qcoreapplication_p.h> #include <private/qcoreapplication_p.h>
@ -106,6 +107,7 @@ public:
private: private:
QHash<int, QObject *> timerIdToObject; QHash<int, QObject *> timerIdToObject;
QVector<WinRTTimerInfo> timerInfos; QVector<WinRTTimerInfo> timerInfos;
mutable QMutex timerInfoLock;
QHash<HANDLE, int> timerHandleToId; QHash<HANDLE, int> timerHandleToId;
QHash<int, HANDLE> timerIdToHandle; QHash<int, HANDLE> timerIdToHandle;
QHash<int, HANDLE> timerIdToCancelHandle; QHash<int, HANDLE> timerIdToCancelHandle;
@ -122,6 +124,7 @@ private:
timerIdToObject.insert(id, obj); timerIdToObject.insert(id, obj);
const quint64 targetTime = qt_msectime() + interval; const quint64 targetTime = qt_msectime() + interval;
const WinRTTimerInfo info(id, interval, type, obj, targetTime); const WinRTTimerInfo info(id, interval, type, obj, targetTime);
QMutexLocker locker(&timerInfoLock);
if (id >= timerInfos.size()) if (id >= timerInfos.size())
timerInfos.resize(id + 1); timerInfos.resize(id + 1);
timerInfos[id] = info; timerInfos[id] = info;
@ -130,6 +133,7 @@ private:
bool removeTimer(int id) bool removeTimer(int id)
{ {
QMutexLocker locker(&timerInfoLock);
if (id >= timerInfos.size()) if (id >= timerInfos.size())
return false; return false;
@ -253,14 +257,18 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
if (timerId == INTERRUPT_HANDLE) if (timerId == INTERRUPT_HANDLE)
break; break;
WinRTTimerInfo &info = d->timerInfos[timerId]; {
Q_ASSERT(info.timerId != INVALID_TIMER_ID); QMutexLocker locker(&d->timerInfoLock);
QCoreApplication::postEvent(this, new QTimerEvent(timerId)); WinRTTimerInfo &info = d->timerInfos[timerId];
Q_ASSERT(info.timerId != INVALID_TIMER_ID);
// Update timer's targetTime QCoreApplication::postEvent(this, new QTimerEvent(timerId));
const quint64 targetTime = qt_msectime() + info.interval;
info.targetTime = targetTime; // Update timer's targetTime
const quint64 targetTime = qt_msectime() + info.interval;
info.targetTime = targetTime;
}
waitResult = WaitForMultipleObjectsEx(timerHandles.count(), timerHandles.constData(), FALSE, 0, TRUE); waitResult = WaitForMultipleObjectsEx(timerHandles.count(), timerHandles.constData(), FALSE, 0, TRUE);
} }
emit awake(); emit awake();
@ -428,6 +436,7 @@ QList<QAbstractEventDispatcher::TimerInfo> QEventDispatcherWinRT::registeredTime
} }
Q_D(const QEventDispatcherWinRT); Q_D(const QEventDispatcherWinRT);
QMutexLocker locker(&d->timerInfoLock);
QList<TimerInfo> timerInfos; QList<TimerInfo> timerInfos;
for (const WinRTTimerInfo &info : d->timerInfos) { for (const WinRTTimerInfo &info : d->timerInfos) {
if (info.object == object && info.timerId != INVALID_TIMER_ID) if (info.object == object && info.timerId != INVALID_TIMER_ID)
@ -459,6 +468,7 @@ int QEventDispatcherWinRT::remainingTime(int timerId)
} }
Q_D(QEventDispatcherWinRT); Q_D(QEventDispatcherWinRT);
QMutexLocker locker(&d->timerInfoLock);
const WinRTTimerInfo timerInfo = d->timerInfos.at(timerId); const WinRTTimerInfo timerInfo = d->timerInfos.at(timerId);
if (timerInfo.timerId == INVALID_TIMER_ID) { if (timerInfo.timerId == INVALID_TIMER_ID) {
#ifndef QT_NO_DEBUG #ifndef QT_NO_DEBUG
@ -507,6 +517,9 @@ bool QEventDispatcherWinRT::event(QEvent *e)
case QEvent::Timer: { case QEvent::Timer: {
QTimerEvent *timerEvent = static_cast<QTimerEvent *>(e); QTimerEvent *timerEvent = static_cast<QTimerEvent *>(e);
const int id = timerEvent->timerId(); const int id = timerEvent->timerId();
QMutexLocker locker(&d->timerInfoLock);
Q_ASSERT(id < d->timerInfos.size()); Q_ASSERT(id < d->timerInfos.size());
WinRTTimerInfo &info = d->timerInfos[id]; WinRTTimerInfo &info = d->timerInfos[id];
Q_ASSERT(info.timerId != INVALID_TIMER_ID); Q_ASSERT(info.timerId != INVALID_TIMER_ID);
@ -515,17 +528,17 @@ bool QEventDispatcherWinRT::event(QEvent *e)
break; break;
info.inEvent = true; info.inEvent = true;
locker.unlock();
QTimerEvent te(id); QTimerEvent te(id);
QCoreApplication::sendEvent(d->timerIdToObject.value(id), &te); QCoreApplication::sendEvent(d->timerIdToObject.value(id), &te);
locker.relock();
// The timer might have been removed in the meanwhile // The timer might have been removed in the meanwhile
if (id >= d->timerInfos.size()) if (id >= d->timerInfos.size())
break; break;
info = d->timerInfos[id];
if (info.timerId == INVALID_TIMER_ID)
break;
if (info.interval == 0 && info.inEvent) { if (info.interval == 0 && info.inEvent) {
// post the next zero timer event as long as the timer was not restarted // post the next zero timer event as long as the timer was not restarted
QCoreApplication::postEvent(this, new QTimerEvent(id)); QCoreApplication::postEvent(this, new QTimerEvent(id));

View File

@ -886,7 +886,7 @@ inline void QXmlStreamReaderPrivate::reallocateStack()
sym_stack = reinterpret_cast<Value*> (realloc(sym_stack, stack_size * sizeof(Value))); sym_stack = reinterpret_cast<Value*> (realloc(sym_stack, stack_size * sizeof(Value)));
Q_CHECK_PTR(sym_stack); Q_CHECK_PTR(sym_stack);
state_stack = reinterpret_cast<int*> (realloc(state_stack, stack_size * sizeof(int))); state_stack = reinterpret_cast<int*> (realloc(state_stack, stack_size * sizeof(int)));
Q_CHECK_PTR(sym_stack); Q_CHECK_PTR(state_stack);
} }

View File

@ -380,8 +380,6 @@ QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName,
QThemeIconInfo info; QThemeIconInfo info;
Q_ASSERT(!themeName.isEmpty()); Q_ASSERT(!themeName.isEmpty());
QPixmap pixmap;
// Used to protect against potential recursions // Used to protect against potential recursions
visited << themeName; visited << themeName;

View File

@ -342,8 +342,10 @@ static const char scaleFactorProperty[] = "_q_scaleFactor";
*/ */
void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor) void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor)
{ {
m_screenFactorSet = true; if (!qFuzzyCompare(factor, qreal(1))) {
m_active = true; m_screenFactorSet = true;
m_active = true;
}
screen->setProperty(scaleFactorProperty, QVariant(factor)); screen->setProperty(scaleFactorProperty, QVariant(factor));
// hack to force re-evaluation of screen geometry // hack to force re-evaluation of screen geometry

View File

@ -264,7 +264,7 @@ public:
static QOpenGLContextPrivate *get(QOpenGLContext *context) static QOpenGLContextPrivate *get(QOpenGLContext *context)
{ {
return context->d_func(); return context ? context->d_func() : Q_NULLPTR;
} }
#if !defined(QT_NO_DEBUG) #if !defined(QT_NO_DEBUG)

View File

@ -2502,6 +2502,9 @@ void QWindowPrivate::_q_clearAlert()
See the \l{Qt::CursorShape}{list of predefined cursor objects} for a See the \l{Qt::CursorShape}{list of predefined cursor objects} for a
range of useful shapes. range of useful shapes.
If no cursor has been set, or after a call to unsetCursor(), the
parent window's cursor is used.
By default, the cursor has the Qt::ArrowCursor shape. By default, the cursor has the Qt::ArrowCursor shape.
Some underlying window implementations will reset the cursor if it Some underlying window implementations will reset the cursor if it

View File

@ -95,6 +95,13 @@ typedef void* GLeglImageOES;
// applications cannot target ES 3. Therefore QOpenGLFunctions and // applications cannot target ES 3. Therefore QOpenGLFunctions and
// friends do everything dynamically and never rely on these macros. // friends do everything dynamically and never rely on these macros.
// Some Khronos headers use the ext proto guard in the standard headers as well,
// which is bad. Work it around, but avoid spilling over to the ext header.
# ifndef GL_GLEXT_PROTOTYPES
# define GL_GLEXT_PROTOTYPES
# define QGL_TEMP_GLEXT_PROTO
# endif
# if defined(QT_OPENGL_ES_3_1) # if defined(QT_OPENGL_ES_3_1)
# include <GLES3/gl31.h> # include <GLES3/gl31.h>
# elif defined(QT_OPENGL_ES_3) # elif defined(QT_OPENGL_ES_3)
@ -106,6 +113,11 @@ typedef void* GLeglImageOES;
# include <GLES2/gl2.h> # include <GLES2/gl2.h>
#endif #endif
# ifdef QGL_TEMP_GLEXT_PROTO
# undef GL_GLEXT_PROTOTYPES
# undef QGL_TEMP_GLEXT_PROTO
# endif
/* /*
Some GLES2 implementations (like the one on Harmattan) are missing the Some GLES2 implementations (like the one on Harmattan) are missing the
typedef for GLchar. Work around it here by adding it. The Kkronos headers typedef for GLchar. Work around it here by adding it. The Kkronos headers
@ -126,7 +138,15 @@ typedef char GLchar;
# include <OpenGL/glext.h> # include <OpenGL/glext.h>
# else # else
# define GL_GLEXT_LEGACY // Prevents GL/gl.h from #including system glext.h # define GL_GLEXT_LEGACY // Prevents GL/gl.h from #including system glext.h
# include <GL/gl.h> // Some Khronos headers use the ext proto guard in the standard headers as well,
// which is bad. Work it around, but avoid spilling over to the ext header.
# ifndef GL_GLEXT_PROTOTYPES
# define GL_GLEXT_PROTOTYPES
# include <GL/gl.h>
# undef GL_GLEXT_PROTOTYPES
# else
# include <GL/gl.h>
# endif
# include <QtGui/qopenglext.h> # include <QtGui/qopenglext.h>
# endif // Q_OS_MAC # endif // Q_OS_MAC
#endif // QT_OPENGL_ES_2 #endif // QT_OPENGL_ES_2

View File

@ -955,6 +955,12 @@ QOpenGLFramebufferObject::~QOpenGLFramebufferObject()
d->stencil_buffer_guard->free(); d->stencil_buffer_guard->free();
if (d->fbo_guard) if (d->fbo_guard)
d->fbo_guard->free(); d->fbo_guard->free();
QOpenGLContextPrivate *contextPrv = QOpenGLContextPrivate::get(QOpenGLContext::currentContext());
if (contextPrv && contextPrv->qgl_current_fbo == this) {
contextPrv->qgl_current_fbo_invalid = true;
contextPrv->qgl_current_fbo = Q_NULLPTR;
}
} }
/*! /*!

View File

@ -1766,6 +1766,10 @@ QTextBlock QTextDocument::lastBlock() const
\property QTextDocument::pageSize \property QTextDocument::pageSize
\brief the page size that should be used for laying out the document \brief the page size that should be used for laying out the document
The units are determined by the underlying paint device. The size is
measured in logical pixels when painting to the screen, and in points
(1/72 inch) when painting to a printer.
By default, for a newly-created, empty document, this property contains By default, for a newly-created, empty document, this property contains
an undefined size. an undefined size.

View File

@ -1902,11 +1902,15 @@ void QTextLine::layout_helper(int maxGlyphs)
++lbh.glyphCount; ++lbh.glyphCount;
if (lbh.checkFullOtherwiseExtend(line)) if (lbh.checkFullOtherwiseExtend(line))
goto found; goto found;
} else if (attributes[lbh.currentPosition].whiteSpace) { } else if (attributes[lbh.currentPosition].whiteSpace
&& eng->layoutData->string.at(lbh.currentPosition).decompositionTag() != QChar::NoBreak) {
lbh.whiteSpaceOrObject = true; lbh.whiteSpaceOrObject = true;
while (lbh.currentPosition < end && attributes[lbh.currentPosition].whiteSpace) while (lbh.currentPosition < end
&& attributes[lbh.currentPosition].whiteSpace
&& eng->layoutData->string.at(lbh.currentPosition).decompositionTag() != QChar::NoBreak) {
addNextCluster(lbh.currentPosition, end, lbh.spaceData, lbh.glyphCount, addNextCluster(lbh.currentPosition, end, lbh.spaceData, lbh.glyphCount,
current, lbh.logClusters, lbh.glyphs); current, lbh.logClusters, lbh.glyphs);
}
if (!lbh.manualWrap && lbh.spaceData.textWidth > line.width) { if (!lbh.manualWrap && lbh.spaceData.textWidth > line.width) {
lbh.spaceData.textWidth = line.width; // ignore spaces that fall out of the line. lbh.spaceData.textWidth = line.width; // ignore spaces that fall out of the line.

View File

@ -587,6 +587,7 @@ qint64 QNativeSocketEngine::bytesAvailable() const
if (d->socketType != QAbstractSocket::TcpSocket) if (d->socketType != QAbstractSocket::TcpSocket)
return -1; return -1;
QMutexLocker locker(&d->readMutex);
return d->readBytes.size() - d->readBytes.pos(); return d->readBytes.size() - d->readBytes.pos();
} }
@ -599,12 +600,12 @@ qint64 QNativeSocketEngine::read(char *data, qint64 maxlen)
// There will be a read notification when the socket was closed by the remote host. If that // There will be a read notification when the socket was closed by the remote host. If that
// happens and there isn't anything left in the buffer, we have to return -1 in order to signal // happens and there isn't anything left in the buffer, we have to return -1 in order to signal
// the closing of the socket. // the closing of the socket.
QMutexLocker mutexLocker(&d->readMutex);
if (d->readBytes.pos() == d->readBytes.size() && d->socketState != QAbstractSocket::ConnectedState) { if (d->readBytes.pos() == d->readBytes.size() && d->socketState != QAbstractSocket::ConnectedState) {
close(); close();
return -1; return -1;
} }
QMutexLocker mutexLocker(&d->readMutex);
return d->readBytes.read(data, maxlen); return d->readBytes.read(data, maxlen);
} }
@ -635,6 +636,7 @@ qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QIpPacketHea
PacketHeaderOptions) PacketHeaderOptions)
{ {
Q_D(QNativeSocketEngine); Q_D(QNativeSocketEngine);
QMutexLocker locker(&d->readMutex);
if (d->socketType != QAbstractSocket::UdpSocket || d->pendingDatagrams.isEmpty()) { if (d->socketType != QAbstractSocket::UdpSocket || d->pendingDatagrams.isEmpty()) {
if (header) if (header)
header->clear(); header->clear();
@ -654,6 +656,7 @@ qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QIpPacketHea
} else { } else {
readOrigin = datagram.data; readOrigin = datagram.data;
} }
locker.unlock();
memcpy(data, readOrigin, qMin(maxlen, qint64(datagram.data.length()))); memcpy(data, readOrigin, qMin(maxlen, qint64(datagram.data.length())));
return readOrigin.length(); return readOrigin.length();
} }
@ -691,12 +694,14 @@ qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 len, const QI
bool QNativeSocketEngine::hasPendingDatagrams() const bool QNativeSocketEngine::hasPendingDatagrams() const
{ {
Q_D(const QNativeSocketEngine); Q_D(const QNativeSocketEngine);
QMutexLocker locker(&d->readMutex);
return d->pendingDatagrams.length() > 0; return d->pendingDatagrams.length() > 0;
} }
qint64 QNativeSocketEngine::pendingDatagramSize() const qint64 QNativeSocketEngine::pendingDatagramSize() const
{ {
Q_D(const QNativeSocketEngine); Q_D(const QNativeSocketEngine);
QMutexLocker locker(&d->readMutex);
if (d->pendingDatagrams.isEmpty()) if (d->pendingDatagrams.isEmpty())
return -1; return -1;
@ -1346,7 +1351,7 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async
hr = byteArrayAccess->Buffer(&data); hr = byteArrayAccess->Buffer(&data);
Q_ASSERT_SUCCEEDED(hr); Q_ASSERT_SUCCEEDED(hr);
readMutex.lock(); QMutexLocker locker(&readMutex);
if (readBytes.atEnd()) // Everything has been read; the buffer is safe to reset if (readBytes.atEnd()) // Everything has been read; the buffer is safe to reset
readBytes.close(); readBytes.close();
if (!readBytes.isOpen()) if (!readBytes.isOpen())
@ -1356,7 +1361,7 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async
Q_ASSERT(readBytes.atEnd()); Q_ASSERT(readBytes.atEnd());
readBytes.write(reinterpret_cast<const char*>(data), qint64(bufferLength)); readBytes.write(reinterpret_cast<const char*>(data), qint64(bufferLength));
readBytes.seek(readPos); readBytes.seek(readPos);
readMutex.unlock(); locker.unlock();
if (notifyOnRead) if (notifyOnRead)
emit q->readReady(); emit q->readReady();
@ -1420,7 +1425,9 @@ HRESULT QNativeSocketEnginePrivate::handleNewDatagram(IDatagramSocket *socket, I
datagram.data.resize(length); datagram.data.resize(length);
hr = reader->ReadBytes(length, reinterpret_cast<BYTE *>(datagram.data.data())); hr = reader->ReadBytes(length, reinterpret_cast<BYTE *>(datagram.data.data()));
RETURN_OK_IF_FAILED("Could not read datagram"); RETURN_OK_IF_FAILED("Could not read datagram");
QMutexLocker locker(&readMutex);
pendingDatagrams.append(datagram); pendingDatagrams.append(datagram);
locker.unlock();
if (notifyOnRead) if (notifyOnRead)
emit q->readReady(); emit q->readReady();

View File

@ -206,10 +206,18 @@ private:
Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocketListener> tcpListener; Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocketListener> tcpListener;
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncAction> connectOp; Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncAction> connectOp;
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperationWithProgress<ABI::Windows::Storage::Streams::IBuffer *, UINT32>> readOp; Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperationWithProgress<ABI::Windows::Storage::Streams::IBuffer *, UINT32>> readOp;
QBuffer readBytes;
QMutex readMutex;
// Protected by readMutex. Written in handleReadyRead (native callback)
QBuffer readBytes;
// In case of TCP readMutex protects readBytes and bytesAvailable. In case of UDP it is
// pendingDatagrams. They are written inside native callbacks (handleReadyRead and
// handleNewDatagrams/putIntoPendingDatagramsList)
mutable QMutex readMutex;
// Protected by readMutex. Written in handleNewDatagrams/putIntoPendingDatagramsList
QList<WinRtDatagram> pendingDatagrams; QList<WinRtDatagram> pendingDatagrams;
QList<ABI::Windows::Networking::Sockets::IStreamSocket *> pendingConnections; QList<ABI::Windows::Networking::Sockets::IStreamSocket *> pendingConnections;
QList<ABI::Windows::Networking::Sockets::IStreamSocket *> currentConnections; QList<ABI::Windows::Networking::Sockets::IStreamSocket *> currentConnections;
QEventLoop eventLoop; QEventLoop eventLoop;

View File

@ -85,6 +85,35 @@
relayed to the function retrieved by QGuiApplication. relayed to the function retrieved by QGuiApplication.
*/ */
/*!
\typedef QXcbWindowFunctions::SetWmWindowRole
\since 5.6.2
This is the typedef for the function returned by
QGuiApplication::platformFunction when passed the
value returned by setWmWindowRoleIdentifier().
*/
/*!
\fn QByteArray QXcbWindowFunctions::setWmWindowRoleIdentifier()
\since 5.6.2
This function returns the byte array that can be used to query
QGuiApplication::platformFunction to retrieve the SetWmWindowRole function.
*/
/*!
\fn void QXcbWindowFunctions::setWmWindowRole(QWindow *window, const QByteArray &role)
\since 5.6.2
Sets the WM_WINDOW_ROLE property from \role on the corresponding
X11 window.
This is a convenience function that can be used directly instead
of resolving the function pointer. \a window and \a role will be
relayed to the function retrieved by QGuiApplication.
*/
/*! /*!
\typedef QXcbWindowFunctions::SetWmWindowIconText \typedef QXcbWindowFunctions::SetWmWindowIconText

View File

@ -117,7 +117,7 @@ static inline int stretchFromFcWidth(int fcwidth)
return qtstretch; return qtstretch;
} }
static const char *specialLanguages[] = { static const char specialLanguages[][6] = {
"", // Unknown "", // Unknown
"", // Inherited "", // Inherited
"", // Common "", // Common
@ -251,12 +251,12 @@ static const char *specialLanguages[] = {
"", // OldHungarian "", // OldHungarian
"" // SignWriting "" // SignWriting
}; };
Q_STATIC_ASSERT(sizeof(specialLanguages) / sizeof(const char *) == QChar::ScriptCount); Q_STATIC_ASSERT(sizeof specialLanguages / sizeof *specialLanguages == QChar::ScriptCount);
// this could become a list of all languages used for each writing // this could become a list of all languages used for each writing
// system, instead of using the single most common language. // system, instead of using the single most common language.
static const char *languageForWritingSystem[] = { static const char languageForWritingSystem[][6] = {
0, // Any "", // Any
"en", // Latin "en", // Latin
"el", // Greek "el", // Greek
"ru", // Cyrillic "ru", // Cyrillic
@ -286,25 +286,25 @@ static const char *languageForWritingSystem[] = {
"ja", // Japanese "ja", // Japanese
"ko", // Korean "ko", // Korean
"vi", // Vietnamese "vi", // Vietnamese
0, // Symbol "", // Symbol
"sga", // Ogham "sga", // Ogham
"non", // Runic "non", // Runic
"man" // N'Ko "man" // N'Ko
}; };
Q_STATIC_ASSERT(sizeof(languageForWritingSystem) / sizeof(const char *) == QFontDatabase::WritingSystemsCount); Q_STATIC_ASSERT(sizeof languageForWritingSystem / sizeof *languageForWritingSystem == QFontDatabase::WritingSystemsCount);
#if FC_VERSION >= 20297 #if FC_VERSION >= 20297
// Newer FontConfig let's us sort out fonts that report certain scripts support, // Newer FontConfig let's us sort out fonts that report certain scripts support,
// but no open type tables for handling them correctly. // but no open type tables for handling them correctly.
// Check the reported script presence in the FC_CAPABILITY's "otlayout:" section. // Check the reported script presence in the FC_CAPABILITY's "otlayout:" section.
static const char *capabilityForWritingSystem[] = { static const char capabilityForWritingSystem[][5] = {
0, // Any "", // Any
0, // Latin "", // Latin
0, // Greek "", // Greek
0, // Cyrillic "", // Cyrillic
0, // Armenian "", // Armenian
0, // Hebrew "", // Hebrew
0, // Arabic "", // Arabic
"syrc", // Syriac "syrc", // Syriac
"thaa", // Thaana "thaa", // Thaana
"deva", // Devanagari "deva", // Devanagari
@ -317,20 +317,20 @@ static const char *capabilityForWritingSystem[] = {
"knda", // Kannada "knda", // Kannada
"mlym", // Malayalam "mlym", // Malayalam
"sinh", // Sinhala "sinh", // Sinhala
0, // Thai "", // Thai
0, // Lao "", // Lao
"tibt", // Tibetan "tibt", // Tibetan
"mymr", // Myanmar "mymr", // Myanmar
0, // Georgian "", // Georgian
"khmr", // Khmer "khmr", // Khmer
0, // SimplifiedChinese "", // SimplifiedChinese
0, // TraditionalChinese "", // TraditionalChinese
0, // Japanese "", // Japanese
0, // Korean "", // Korean
0, // Vietnamese "", // Vietnamese
0, // Symbol "", // Symbol
0, // Ogham "", // Ogham
0, // Runic "", // Runic
"nko " // N'Ko "nko " // N'Ko
}; };
Q_STATIC_ASSERT(sizeof(capabilityForWritingSystem) / sizeof(*capabilityForWritingSystem) == QFontDatabase::WritingSystemsCount); Q_STATIC_ASSERT(sizeof(capabilityForWritingSystem) / sizeof(*capabilityForWritingSystem) == QFontDatabase::WritingSystemsCount);
@ -436,7 +436,7 @@ static void populateFromPattern(FcPattern *pattern)
FcLangResult langRes = FcLangSetHasLang(langset, lang); FcLangResult langRes = FcLangSetHasLang(langset, lang);
if (langRes != FcLangDifferentLang) { if (langRes != FcLangDifferentLang) {
#if FC_VERSION >= 20297 #if FC_VERSION >= 20297
if (capabilityForWritingSystem[j] != Q_NULLPTR && requiresOpenType(j)) { if (*capabilityForWritingSystem[j] && requiresOpenType(j)) {
if (cap == Q_NULLPTR) if (cap == Q_NULLPTR)
capRes = FcPatternGetString(pattern, FC_CAPABILITY, 0, &cap); capRes = FcPatternGetString(pattern, FC_CAPABILITY, 0, &cap);
if (capRes == FcResultMatch && strstr(reinterpret_cast<const char *>(cap), capabilityForWritingSystem[j]) == 0) if (capRes == FcResultMatch && strstr(reinterpret_cast<const char *>(cap), capabilityForWritingSystem[j]) == 0)

View File

@ -45,6 +45,7 @@
#include "qcocoacolordialoghelper.h" #include "qcocoacolordialoghelper.h"
#include "qcocoahelpers.h" #include "qcocoahelpers.h"
#include "qcocoaeventdispatcher.h"
#import <AppKit/AppKit.h> #import <AppKit/AppKit.h>
@ -322,6 +323,10 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
// cleanup of modal sessions. Do this before showing the native dialog, otherwise it will // cleanup of modal sessions. Do this before showing the native dialog, otherwise it will
// close down during the cleanup. // close down during the cleanup.
qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
// Make sure we don't interrupt the runModalForWindow call.
QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag();
[NSApp runModalForWindow:mColorPanel]; [NSApp runModalForWindow:mColorPanel];
mDialogIsExecuting = false; mDialogIsExecuting = false;
return (mResultCode == NSOKButton); return (mResultCode == NSOKButton);

View File

@ -61,7 +61,7 @@ QCocoaCursor::~QCocoaCursor()
void QCocoaCursor::changeCursor(QCursor *cursor, QWindow *window) void QCocoaCursor::changeCursor(QCursor *cursor, QWindow *window)
{ {
NSCursor * cocoaCursor = convertCursor(cursor); NSCursor *cocoaCursor = convertCursor(cursor);
if (QPlatformWindow * platformWindow = window->handle()) if (QPlatformWindow * platformWindow = window->handle())
static_cast<QCocoaWindow *>(platformWindow)->setWindowCursor(cocoaCursor); static_cast<QCocoaWindow *>(platformWindow)->setWindowCursor(cocoaCursor);
@ -83,9 +83,12 @@ void QCocoaCursor::setPos(const QPoint &position)
CFRelease(e); CFRelease(e);
} }
NSCursor *QCocoaCursor::convertCursor(QCursor * cursor) NSCursor *QCocoaCursor::convertCursor(QCursor *cursor)
{ {
const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; if (cursor == Q_NULLPTR)
return 0;
const Qt::CursorShape newShape = cursor->shape();
NSCursor *cocoaCursor; NSCursor *cocoaCursor;
// Check for a suitable built-in NSCursor first: // Check for a suitable built-in NSCursor first:

View File

@ -131,6 +131,8 @@ public:
void interrupt(); void interrupt();
void flush(); void flush();
static void clearCurrentThreadCocoaEventDispatcherInterruptFlag();
friend void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher); friend void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher);
}; };

View File

@ -966,6 +966,19 @@ void QCocoaEventDispatcher::interrupt()
void QCocoaEventDispatcher::flush() void QCocoaEventDispatcher::flush()
{ } { }
// QTBUG-56746: The behavior of processEvents() has been changed to not clear
// the interrupt flag. Use this function to clear it.
void QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag()
{
QCocoaEventDispatcher *cocoaEventDispatcher =
qobject_cast<QCocoaEventDispatcher *>(QThread::currentThread()->eventDispatcher());
if (!cocoaEventDispatcher)
return;
QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate =
static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher));
cocoaEventDispatcherPrivate->interrupt = false;
}
QCocoaEventDispatcher::~QCocoaEventDispatcher() QCocoaEventDispatcher::~QCocoaEventDispatcher()
{ {
Q_D(QCocoaEventDispatcher); Q_D(QCocoaEventDispatcher);

View File

@ -53,6 +53,7 @@
#include "qt_mac_p.h" #include "qt_mac_p.h"
#include "qcocoahelpers.h" #include "qcocoahelpers.h"
#include "qcocoamenubar.h" #include "qcocoamenubar.h"
#include "qcocoaeventdispatcher.h"
#include <qregexp.h> #include <qregexp.h>
#include <qbuffer.h> #include <qbuffer.h>
#include <qdebug.h> #include <qdebug.h>
@ -243,6 +244,10 @@ static QString strippedText(QString s)
// cleanup of modal sessions. Do this before showing the native dialog, otherwise it will // cleanup of modal sessions. Do this before showing the native dialog, otherwise it will
// close down during the cleanup. // close down during the cleanup.
qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
// Make sure we don't interrupt the runModal call below.
QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag();
QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder(); QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder();
mReturnCode = [mSavePanel runModal]; mReturnCode = [mSavePanel runModal];
QCocoaMenuBar::resetKnownMenuItemsToQt(); QCocoaMenuBar::resetKnownMenuItemsToQt();

View File

@ -49,6 +49,7 @@
#include "qcocoafontdialoghelper.h" #include "qcocoafontdialoghelper.h"
#include "qcocoahelpers.h" #include "qcocoahelpers.h"
#include "qcocoaeventdispatcher.h"
#import <AppKit/AppKit.h> #import <AppKit/AppKit.h>
@ -319,6 +320,10 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
// cleanup of modal sessions. Do this before showing the native dialog, otherwise it will // cleanup of modal sessions. Do this before showing the native dialog, otherwise it will
// close down during the cleanup. // close down during the cleanup.
qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
// Make sure we don't interrupt the runModalForWindow call.
QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag();
[NSApp runModalForWindow:mFontPanel]; [NSApp runModalForWindow:mFontPanel];
mDialogIsExecuting = false; mDialogIsExecuting = false;
return (mResultCode == NSOKButton); return (mResultCode == NSOKButton);

View File

@ -100,6 +100,8 @@ private:
*/ */
Q_INVOKABLE QPixmap defaultBackgroundPixmapForQWizard(); Q_INVOKABLE QPixmap defaultBackgroundPixmapForQWizard();
Q_INVOKABLE void clearCurrentThreadCocoaEventDispatcherInterruptFlag();
// QMacPastebardMime support. The mac pasteboard void pointers are // QMacPastebardMime support. The mac pasteboard void pointers are
// QMacPastebardMime instances from the cocoa plugin or qtmacextras // QMacPastebardMime instances from the cocoa plugin or qtmacextras
// These two classes are kept in sync and can be casted between. // These two classes are kept in sync and can be casted between.

View File

@ -44,6 +44,7 @@
#include "qcocoahelpers.h" #include "qcocoahelpers.h"
#include "qcocoaapplication.h" #include "qcocoaapplication.h"
#include "qcocoaintegration.h" #include "qcocoaintegration.h"
#include "qcocoaeventdispatcher.h"
#include <qbytearray.h> #include <qbytearray.h>
#include <qwindow.h> #include <qwindow.h>
@ -194,6 +195,11 @@ QPixmap QCocoaNativeInterface::defaultBackgroundPixmapForQWizard()
return QPixmap(); return QPixmap();
} }
void QCocoaNativeInterface::clearCurrentThreadCocoaEventDispatcherInterruptFlag()
{
QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag();
}
void QCocoaNativeInterface::onAppFocusWindowChanged(QWindow *window) void QCocoaNativeInterface::onAppFocusWindowChanged(QWindow *window)
{ {
Q_UNUSED(window); Q_UNUSED(window);

View File

@ -242,6 +242,8 @@ public:
void setMenubar(QCocoaMenuBar *mb); void setMenubar(QCocoaMenuBar *mb);
QCocoaMenuBar *menubar() const; QCocoaMenuBar *menubar() const;
NSCursor *effectiveWindowCursor() const;
void applyEffectiveWindowCursor();
void setWindowCursor(NSCursor *cursor); void setWindowCursor(NSCursor *cursor);
void registerTouch(bool enable); void registerTouch(bool enable);

View File

@ -1663,29 +1663,51 @@ QCocoaMenuBar *QCocoaWindow::menubar() const
return m_menubar; return m_menubar;
} }
// Finds the effective cursor for this window by walking up the
// ancestor chain (including this window) until a set cursor is
// found. Returns nil if there is not set cursor.
NSCursor *QCocoaWindow::effectiveWindowCursor() const
{
if (m_windowCursor)
return m_windowCursor;
if (!parent())
return nil;
return static_cast<QCocoaWindow *>(parent())->effectiveWindowCursor();
}
// Applies the cursor as returned by effectiveWindowCursor(), handles
// the special no-cursor-set case by setting the arrow cursor.
void QCocoaWindow::applyEffectiveWindowCursor()
{
NSCursor *effectiveCursor = effectiveWindowCursor();
if (effectiveCursor) {
[effectiveCursor set];
} else {
// We wold like to _unset_ the cursor here; but there is no such
// API. Fall back to setting the default arrow cursor.
[[NSCursor arrowCursor] set];
}
}
void QCocoaWindow::setWindowCursor(NSCursor *cursor) void QCocoaWindow::setWindowCursor(NSCursor *cursor)
{ {
// This function is called (via QCocoaCursor) by Qt to set if (m_windowCursor == cursor)
// the cursor for this window. It can be called for a window return;
// that is not currenly under the mouse pointer (for example
// for a popup window.) Qt expects the set cursor to "stick":
// it should be accociated with the window until a different
// cursor is set.
if (m_windowCursor != cursor) {
[m_windowCursor release];
m_windowCursor = [cursor retain];
}
// Use the built in cursor rect API if the QCocoaWindow has a NSWindow. // Setting a cursor in a foregin view is not supported.
// Othervise, set the cursor if this window is under the mouse. In if (!m_qtView)
// this case QNSView::cursorUpdate will set the cursor as the pointer return;
// moves.
if (m_nsWindow && m_qtView) { [m_windowCursor release];
[m_nsWindow invalidateCursorRectsForView : m_qtView]; m_windowCursor = cursor;
} else { [m_windowCursor retain];
if (m_windowUnderMouse)
[cursor set]; // The installed view tracking area (see QNSView updateTrackingAreas) will
} // handle cursor updates on mouse enter/leave. Handle the case where the
// mouse is on the this window by changing the cursor immediately.
if (m_windowUnderMouse)
applyEffectiveWindowCursor();
} }
void QCocoaWindow::registerTouch(bool enable) void QCocoaWindow::registerTouch(bool enable)

View File

@ -131,7 +131,6 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
- (void)mouseMovedImpl:(NSEvent *)theEvent; - (void)mouseMovedImpl:(NSEvent *)theEvent;
- (void)mouseEnteredImpl:(NSEvent *)theEvent; - (void)mouseEnteredImpl:(NSEvent *)theEvent;
- (void)mouseExitedImpl:(NSEvent *)theEvent; - (void)mouseExitedImpl:(NSEvent *)theEvent;
- (void)cursorUpdateImpl:(NSEvent *)theEvent;
- (void)rightMouseDown:(NSEvent *)theEvent; - (void)rightMouseDown:(NSEvent *)theEvent;
- (void)rightMouseDragged:(NSEvent *)theEvent; - (void)rightMouseDragged:(NSEvent *)theEvent;
- (void)rightMouseUp:(NSEvent *)theEvent; - (void)rightMouseUp:(NSEvent *)theEvent;

View File

@ -125,7 +125,7 @@ static bool _q_dontOverrideCtrlLMB = false;
- (void)cursorUpdate:(NSEvent *)theEvent - (void)cursorUpdate:(NSEvent *)theEvent
{ {
[view cursorUpdateImpl:theEvent]; [self cursorUpdate:theEvent];
} }
@end @end
@ -1071,21 +1071,10 @@ QT_WARNING_POP
[self addTrackingArea:m_trackingArea]; [self addTrackingArea:m_trackingArea];
} }
-(void)cursorUpdateImpl:(NSEvent *)theEvent - (void)cursorUpdate:(NSEvent *)theEvent
{ {
Q_UNUSED(theEvent) Q_UNUSED(theEvent);
// Set the cursor manually if there is no NSWindow. m_platformWindow->applyEffectiveWindowCursor();
if (!m_platformWindow->m_nsWindow && m_platformWindow->m_windowCursor)
[m_platformWindow->m_windowCursor set];
else
[super cursorUpdate:theEvent];
}
-(void)resetCursorRects
{
// Use the cursor rect API if there is a NSWindow
if (m_platformWindow->m_nsWindow && m_platformWindow->m_windowCursor)
[self addCursorRect:[self visibleRect] cursor:m_platformWindow->m_windowCursor];
} }
- (void)mouseMovedImpl:(NSEvent *)theEvent - (void)mouseMovedImpl:(NSEvent *)theEvent
@ -1915,9 +1904,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
- (NSRange) selectedRange - (NSRange) selectedRange
{ {
NSRange selectedRange = {NSNotFound, 0}; NSRange selectedRange = {0, 0};
selectedRange.location = NSNotFound;
selectedRange.length = 0;
QObject *fo = QGuiApplication::focusObject(); QObject *fo = QGuiApplication::focusObject();
if (!fo) if (!fo)

View File

@ -418,15 +418,17 @@ void QEglFSIntegration::createInputHandlers()
} }
#endif #endif
bool useTslib = false;
#ifndef QT_NO_TSLIB
useTslib = qEnvironmentVariableIntValue("QT_QPA_EGLFS_TSLIB");
if (useTslib)
new QTsLibMouseHandler(QLatin1String("TsLib"), QString() /* spec */);
#endif
#if !defined(QT_NO_EVDEV) && !defined(Q_OS_ANDROID) #if !defined(QT_NO_EVDEV) && !defined(Q_OS_ANDROID)
m_kbdMgr = new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this); m_kbdMgr = new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this); new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
#ifndef QT_NO_TSLIB if (!useTslib)
const bool useTslib = qEnvironmentVariableIntValue("QT_QPA_EGLFS_TSLIB");
if (useTslib)
new QTsLibMouseHandler(QLatin1String("TsLib"), QString() /* spec */);
else
#endif // QT_NO_TSLIB
new QEvdevTouchManager(QLatin1String("EvdevTouch"), QString() /* spec */, this); new QEvdevTouchManager(QLatin1String("EvdevTouch"), QString() /* spec */, this);
#endif #endif
} }

View File

@ -625,7 +625,7 @@
- (id<UITextInputTokenizer>)tokenizer - (id<UITextInputTokenizer>)tokenizer
{ {
return [[[UITextInputStringTokenizer alloc] initWithTextInput:id<UITextInput>(self)] autorelease]; return [[[UITextInputStringTokenizer alloc] initWithTextInput:self] autorelease];
} }
- (UITextPosition *)beginningOfDocument - (UITextPosition *)beginningOfDocument

View File

@ -147,15 +147,17 @@ void QLinuxFbIntegration::createInputHandlers()
} }
#endif #endif
bool useTslib = false;
#ifndef QT_NO_TSLIB
useTslib = qEnvironmentVariableIntValue("QT_QPA_FB_TSLIB");
if (useTslib)
new QTsLibMouseHandler(QLatin1String("TsLib"), QString());
#endif
#if !defined(QT_NO_EVDEV) && !defined(Q_OS_ANDROID) #if !defined(QT_NO_EVDEV) && !defined(Q_OS_ANDROID)
new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString(), this); new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString(), this);
new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString(), this); new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString(), this);
#ifndef QT_NO_TSLIB if (!useTslib)
const bool useTslib = qEnvironmentVariableIntValue("QT_QPA_FB_TSLIB");
if (useTslib)
new QTsLibMouseHandler(QLatin1String("TsLib"), QString());
else
#endif // QT_NO_TSLIB
new QEvdevTouchManager(QLatin1String("EvdevTouch"), QString() /* spec */, this); new QEvdevTouchManager(QLatin1String("EvdevTouch"), QString() /* spec */, this);
#endif #endif
} }

View File

@ -678,8 +678,11 @@ void QGLXContext::queryDummyContext()
} }
QOpenGLContext context; QOpenGLContext context;
context.create(); if (!context.create() || !context.makeCurrent(surface.data())) {
context.makeCurrent(surface.data()); qWarning("QGLXContext: Failed to create dummy context");
m_supportsThreading = false;
return;
}
m_supportsThreading = true; m_supportsThreading = true;

View File

@ -729,8 +729,10 @@ void QXcbClipboard::handleXFixesSelectionRequest(xcb_xfixes_selection_notify_eve
if (mode > QClipboard::Selection) if (mode > QClipboard::Selection)
return; return;
// here we care only about the xfixes events that come from non Qt processes // Note1: Here we care only about the xfixes events that come from other processes.
if (event->owner != XCB_NONE && event->owner != owner()) { // Note2: If the QClipboard::clear() is issued, event->owner is XCB_NONE,
// so we check selection_timestamp to not handle our own QClipboard::clear().
if (event->owner != owner() && event->selection_timestamp > m_timestamp[mode]) {
if (!m_xClipboard[mode]) { if (!m_xClipboard[mode]) {
m_xClipboard[mode].reset(new QXcbClipboardMime(mode, this)); m_xClipboard[mode].reset(new QXcbClipboardMime(mode, this));
} else { } else {

View File

@ -133,6 +133,11 @@ void QMacPageSetupDialogPrivate::openCocoaPageLayout(Qt::WindowModality modality
QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) alloc] initWithNSPrintInfo:printInfo]; QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) alloc] initWithNSPrintInfo:printInfo];
if (modality == Qt::ApplicationModal) { if (modality == Qt::ApplicationModal) {
// Make sure we don't interrupt the runModalWithPrintInfo call.
(void) QMetaObject::invokeMethod(qApp->platformNativeInterface(),
"clearCurrentThreadCocoaEventDispatcherInterruptFlag");
int rval = [pageLayout runModalWithPrintInfo:printInfo]; int rval = [pageLayout runModalWithPrintInfo:printInfo];
[delegate pageLayoutDidEnd:pageLayout returnCode:rval contextInfo:q]; [delegate pageLayoutDidEnd:pageLayout returnCode:rval contextInfo:q];
} else { } else {

View File

@ -245,6 +245,11 @@ void QPrintDialogPrivate::openCocoaPrintPanel(Qt::WindowModality modality)
if (modality == Qt::ApplicationModal || !q->parentWidget()) { if (modality == Qt::ApplicationModal || !q->parentWidget()) {
if (modality == Qt::NonModal) if (modality == Qt::NonModal)
qWarning("QPrintDialog is required to be modal on OS X"); qWarning("QPrintDialog is required to be modal on OS X");
// Make sure we don't interrupt the runModalWithPrintInfo call.
(void) QMetaObject::invokeMethod(qApp->platformNativeInterface(),
"clearCurrentThreadCocoaEventDispatcherInterruptFlag");
int rval = [printPanel runModalWithPrintInfo:printInfo]; int rval = [printPanel runModalWithPrintInfo:printInfo];
[delegate printPanelDidEnd:printPanel returnCode:rval contextInfo:q]; [delegate printPanelDidEnd:printPanel returnCode:rval contextInfo:q];
} else { } else {

View File

@ -137,11 +137,3 @@ setUpdatesEnabled(false);
bigVisualChanges(); bigVisualChanges();
setUpdatesEnabled(true); setUpdatesEnabled(true);
//! [13] //! [13]
//! [14]
...
extern void qt_x11_set_global_double_buffer(bool);
qt_x11_set_global_double_buffer(false);
...
//! [14]

View File

@ -694,8 +694,7 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics
bool QGraphicsSceneBspTreeIndex::event(QEvent *event) bool QGraphicsSceneBspTreeIndex::event(QEvent *event)
{ {
Q_D(QGraphicsSceneBspTreeIndex); Q_D(QGraphicsSceneBspTreeIndex);
switch (event->type()) { if (event->type() == QEvent::Timer) {
case QEvent::Timer:
if (d->indexTimerId && static_cast<QTimerEvent *>(event)->timerId() == d->indexTimerId) { if (d->indexTimerId && static_cast<QTimerEvent *>(event)->timerId() == d->indexTimerId) {
if (d->restartIndexTimer) { if (d->restartIndexTimer) {
d->restartIndexTimer = false; d->restartIndexTimer = false;
@ -704,11 +703,8 @@ bool QGraphicsSceneBspTreeIndex::event(QEvent *event)
d->_q_updateIndex(); d->_q_updateIndex();
} }
} }
// Fallthrough intended - support timers in subclasses.
default:
return QObject::event(event);
} }
return true; return QObject::event(event);
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -1456,6 +1456,7 @@ bool QGraphicsWidget::event(QEvent *event)
case QEvent::GraphicsSceneMousePress: case QEvent::GraphicsSceneMousePress:
if (d->hasDecoration() && windowFrameEvent(event)) if (d->hasDecoration() && windowFrameEvent(event))
return true; return true;
break;
case QEvent::GraphicsSceneMouseMove: case QEvent::GraphicsSceneMouseMove:
case QEvent::GraphicsSceneMouseRelease: case QEvent::GraphicsSceneMouseRelease:
case QEvent::GraphicsSceneMouseDoubleClick: case QEvent::GraphicsSceneMouseDoubleClick:

View File

@ -9631,11 +9631,6 @@ void QWidget::leaveEvent(QEvent *)
Since Qt 4.0, QWidget automatically double-buffers its painting, so there Since Qt 4.0, QWidget automatically double-buffers its painting, so there
is no need to write double-buffering code in paintEvent() to avoid flicker. is no need to write double-buffering code in paintEvent() to avoid flicker.
\b{Note for the X11 platform}: It is possible to toggle global double
buffering by calling \c qt_x11_set_global_double_buffer(). For example,
\snippet code/src_gui_kernel_qwidget.cpp 14
\note Generally, you should refrain from calling update() or repaint() \note Generally, you should refrain from calling update() or repaint()
\b{inside} a paintEvent(). For example, calling update() or repaint() on \b{inside} a paintEvent(). For example, calling update() or repaint() on
children inside a paintevent() results in undefined behavior; the child may children inside a paintevent() results in undefined behavior; the child may

View File

@ -49,6 +49,8 @@
#include "qstylehelper_p.h" #include "qstylehelper_p.h"
#include <qstringbuilder.h> #include <qstringbuilder.h>
#include <qdatastream.h>
#include <qcryptographichash.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -62,7 +64,6 @@ QString uniqueName(const QString &key, const QStyleOption *option, const QSize &
QString tmp = key % HexString<uint>(option->state) QString tmp = key % HexString<uint>(option->state)
% HexString<uint>(option->direction) % HexString<uint>(option->direction)
% HexString<uint>(complexOption ? uint(complexOption->activeSubControls) : 0u) % HexString<uint>(complexOption ? uint(complexOption->activeSubControls) : 0u)
% HexString<quint64>(option->palette.cacheKey())
% HexString<uint>(size.width()) % HexString<uint>(size.width())
% HexString<uint>(size.height()); % HexString<uint>(size.height());
@ -73,6 +74,25 @@ QString uniqueName(const QString &key, const QStyleOption *option, const QSize &
% QLatin1Char(spinBox->frame ? '1' : '0'); ; % QLatin1Char(spinBox->frame ? '1' : '0'); ;
} }
#endif // QT_NO_SPINBOX #endif // QT_NO_SPINBOX
// QTBUG-56743, try to create a palette cache key reflecting the value,
// as leaks may occur in conjunction with QStyleSheetStyle/QRenderRule modifying
// palettes when using QPalette::cacheKey()
if (option->palette != QGuiApplication::palette()) {
tmp.append(QLatin1Char('P'));
#ifndef QT_NO_DATASTREAM
QByteArray key;
key.reserve(5120); // Observed 5040B for a serialized palette on 64bit
{
QDataStream str(&key, QIODevice::WriteOnly);
str << option->palette;
}
const QByteArray sha1 = QCryptographicHash::hash(key, QCryptographicHash::Sha1).toHex();
tmp.append(QString::fromLatin1(sha1));
#else // QT_NO_DATASTREAM
tmp.append(QString::number(option->palette.cacheKey(), 16));
#endif // !QT_NO_DATASTREAM
}
return tmp; return tmp;
} }

View File

@ -585,6 +585,7 @@ QSize QLabelPrivate::sizeForWidth(int w) const
#ifndef QT_NO_MOVIE #ifndef QT_NO_MOVIE
} else if (movie && !movie->currentPixmap().isNull()) { } else if (movie && !movie->currentPixmap().isNull()) {
br = movie->currentPixmap().rect(); br = movie->currentPixmap().rect();
br.setSize(br.size() / movie->currentPixmap().devicePixelRatio());
#endif #endif
} else if (isTextLabel) { } else if (isTextLabel) {
int align = QStyle::visualAlignment(textDirection(), QFlag(this->align)); int align = QStyle::visualAlignment(textDirection(), QFlag(this->align));

View File

@ -58,11 +58,3 @@ my @zlib_headers = ( "zconf.h", "zlib.h" );
@ignore_for_include_check = ( "qsystemdetection.h", "qcompilerdetection.h", "qprocessordetection.h", @zlib_headers, @angle_headers); @ignore_for_include_check = ( "qsystemdetection.h", "qcompilerdetection.h", "qprocessordetection.h", @zlib_headers, @angle_headers);
@ignore_for_qt_begin_namespace_check = ( "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qatomic_arch.h", "qatomic_windowsce.h", "qt_windows.h", "qatomic_macosx.h", @zlib_headers, @angle_headers); @ignore_for_qt_begin_namespace_check = ( "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qatomic_arch.h", "qatomic_windowsce.h", "qt_windows.h", "qatomic_macosx.h", @zlib_headers, @angle_headers);
%inject_headers = ( "$basedir/src/corelib/global" => [ "qconfig.h", "qfeatures.h" ] ); %inject_headers = ( "$basedir/src/corelib/global" => [ "qconfig.h", "qfeatures.h" ] );
# Module dependencies.
# Every module that is required to build this module should have one entry.
# Each of the module version specifiers can take one of the following values:
# - A specific Git revision.
# - any git symbolic ref resolvable from the module's repository (e.g. "refs/heads/master" to track master branch)
#
%dependencies = (
);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -93,6 +93,7 @@ private Q_SLOTS:
void fromBinary(); void fromBinary();
void toAndFromBinary_data(); void toAndFromBinary_data();
void toAndFromBinary(); void toAndFromBinary();
void invalidBinaryData();
void parseNumbers(); void parseNumbers();
void parseStrings(); void parseStrings();
void parseDuplicateKeys(); void parseDuplicateKeys();
@ -1764,6 +1765,21 @@ void tst_QtJson::toAndFromBinary()
QCOMPARE(doc, outdoc); QCOMPARE(doc, outdoc);
} }
void tst_QtJson::invalidBinaryData()
{
QDir dir(testDataDir + "/invalidBinaryData");
QFileInfoList files = dir.entryInfoList();
for (int i = 0; i < files.size(); ++i) {
if (!files.at(i).isFile())
continue;
QFile file(files.at(i).filePath());
file.open(QIODevice::ReadOnly);
QByteArray bytes = file.readAll();
QJsonDocument document = QJsonDocument::fromRawData(bytes.constData(), bytes.size());
QVERIFY(document.isNull());
}
}
void tst_QtJson::parseNumbers() void tst_QtJson::parseNumbers()
{ {
{ {

View File

@ -162,6 +162,7 @@ private:
const QString m_prefix; const QString m_prefix;
const QString m_convertFromImage; const QString m_convertFromImage;
const QString m_loadFromData; const QString m_loadFromData;
const QTemporaryDir m_tempDir;
}; };
static bool lenientCompare(const QPixmap &actual, const QPixmap &expected) static bool lenientCompare(const QPixmap &actual, const QPixmap &expected)
@ -209,11 +210,11 @@ void tst_QPixmap::initTestCase()
QVERIFY(!m_prefix.isEmpty()); QVERIFY(!m_prefix.isEmpty());
QVERIFY(!m_convertFromImage.isEmpty()); QVERIFY(!m_convertFromImage.isEmpty());
QVERIFY(!m_loadFromData.isEmpty()); QVERIFY(!m_loadFromData.isEmpty());
QVERIFY2(m_tempDir.isValid(), qPrintable(m_tempDir.errorString()));
} }
void tst_QPixmap::cleanupTestCase() void tst_QPixmap::cleanupTestCase()
{ {
QFile::remove(QLatin1String("temp_image.png"));
} }
void tst_QPixmap::swap() void tst_QPixmap::swap()
@ -1455,18 +1456,18 @@ void tst_QPixmap::preserveDepth()
void tst_QPixmap::loadAsBitmapOrPixmap() void tst_QPixmap::loadAsBitmapOrPixmap()
{ {
QImage tmp(10, 10, QImage::Format_RGB32); QImage tmp(10, 10, QImage::Format_RGB32);
tmp.save("temp_image.png"); tmp.save(m_tempDir.path() + "/temp_image.png");
bool ok; bool ok;
// Check that we can load the pixmap as a pixmap and that it then turns into a pixmap // Check that we can load the pixmap as a pixmap and that it then turns into a pixmap
QPixmap pixmap("temp_image.png"); QPixmap pixmap(m_tempDir.path() + "/temp_image.png");
QVERIFY(!pixmap.isNull()); QVERIFY(!pixmap.isNull());
QVERIFY(pixmap.depth() > 1); QVERIFY(pixmap.depth() > 1);
QVERIFY(!pixmap.isQBitmap()); QVERIFY(!pixmap.isQBitmap());
pixmap = QPixmap(); pixmap = QPixmap();
ok = pixmap.load("temp_image.png"); ok = pixmap.load(m_tempDir.path() + "/temp_image.png");
QVERIFY(ok); QVERIFY(ok);
QVERIFY(!pixmap.isNull()); QVERIFY(!pixmap.isNull());
QVERIFY(pixmap.depth() > 1); QVERIFY(pixmap.depth() > 1);
@ -1474,20 +1475,20 @@ void tst_QPixmap::loadAsBitmapOrPixmap()
//now we can try to load it without an extension //now we can try to load it without an extension
pixmap = QPixmap(); pixmap = QPixmap();
ok = pixmap.load("temp_image"); ok = pixmap.load(m_tempDir.path() + "/temp_image");
QVERIFY(ok); QVERIFY(ok);
QVERIFY(!pixmap.isNull()); QVERIFY(!pixmap.isNull());
QVERIFY(pixmap.depth() > 1); QVERIFY(pixmap.depth() > 1);
QVERIFY(!pixmap.isQBitmap()); QVERIFY(!pixmap.isQBitmap());
// The do the same check for bitmaps.. // The do the same check for bitmaps..
QBitmap bitmap("temp_image.png"); QBitmap bitmap(m_tempDir.path() + "/temp_image.png");
QVERIFY(!bitmap.isNull()); QVERIFY(!bitmap.isNull());
QCOMPARE(bitmap.depth(), 1); QCOMPARE(bitmap.depth(), 1);
QVERIFY(bitmap.isQBitmap()); QVERIFY(bitmap.isQBitmap());
bitmap = QBitmap(); bitmap = QBitmap();
ok = bitmap.load("temp_image.png"); ok = bitmap.load(m_tempDir.path() + "/temp_image.png");
QVERIFY(ok); QVERIFY(ok);
QVERIFY(!bitmap.isNull()); QVERIFY(!bitmap.isNull());
QCOMPARE(bitmap.depth(), 1); QCOMPARE(bitmap.depth(), 1);

View File

@ -134,6 +134,7 @@ private slots:
void xToCursorForLigatures(); void xToCursorForLigatures();
void cursorInNonStopChars(); void cursorInNonStopChars();
void nbsp(); void nbsp();
void nbspWithFormat();
void noModificationOfInputString(); void noModificationOfInputString();
void superscriptCrash_qtbug53911(); void superscriptCrash_qtbug53911();
@ -2254,5 +2255,41 @@ void tst_QTextLayout::superscriptCrash_qtbug53911()
qDeleteAll(textLayouts); qDeleteAll(textLayouts);
} }
void tst_QTextLayout::nbspWithFormat()
{
QString s1 = QLatin1String("ABCDEF ");
QString s2 = QLatin1String("GHI");
QChar nbsp(QChar::Nbsp);
QString s3 = QLatin1String("JKLMNOPQRSTUVWXYZ");
QTextLayout layout;
layout.setText(s1 + s2 + nbsp + s3);
QTextLayout::FormatRange formatRange;
formatRange.start = s1.length() + s2.length();
formatRange.length = 1;
formatRange.format.setFontUnderline(true);
QList<QTextLayout::FormatRange> overrides;
overrides.append(formatRange);
layout.setAdditionalFormats(overrides);
layout.beginLayout();
forever {
QTextLine line = layout.createLine();
if (!line.isValid())
break;
line.setLineWidth(1);
}
layout.endLayout();
QCOMPARE(layout.lineCount(), 2);
QCOMPARE(layout.lineAt(0).textStart(), 0);
QCOMPARE(layout.lineAt(0).textLength(), s1.length());
QCOMPARE(layout.lineAt(1).textStart(), s1.length());
QCOMPARE(layout.lineAt(1).textLength(), s2.length() + 1 + s3.length());
}
QTEST_MAIN(tst_QTextLayout) QTEST_MAIN(tst_QTextLayout)
#include "tst_qtextlayout.moc" #include "tst_qtextlayout.moc"

View File

@ -1120,8 +1120,8 @@ void tst_qmakelib::addReplaceFunctions(const QString &qindir)
QTest::newRow("$$section(): bad number of arguments") QTest::newRow("$$section(): bad number of arguments")
<< "VAR = $$section(1, 2) \\\n$$section(1, 2, 3, 4, 5)" << "VAR = $$section(1, 2) \\\n$$section(1, 2, 3, 4, 5)"
<< "VAR =" << "VAR ="
<< "##:1: section(var) section(var, sep, begin, end) requires three or four arguments.\n" << "##:1: section(var, sep, begin, end) requires three or four arguments.\n"
"##:2: section(var) section(var, sep, begin, end) requires three or four arguments." "##:2: section(var, sep, begin, end) requires three or four arguments."
<< true; << true;
QTest::newRow("$$find()") QTest::newRow("$$find()")

View File

@ -1093,6 +1093,10 @@ static QSet<QString> fileListUnderIndex(const QFileSystemModel *model, const QMo
void tst_QFileSystemModel::specialFiles() void tst_QFileSystemModel::specialFiles()
{ {
#ifndef Q_OS_UNIX
QSKIP("Not implemented");
#endif
QFileSystemModel model; QFileSystemModel model;
model.setFilter(QDir::AllEntries | QDir::System | QDir::Hidden); model.setFilter(QDir::AllEntries | QDir::System | QDir::Hidden);
@ -1101,23 +1105,8 @@ void tst_QFileSystemModel::specialFiles()
// as it will always return a valid index for existing files, // as it will always return a valid index for existing files,
// even if the file is not visible with the given filter. // even if the file is not visible with the given filter.
#if defined(Q_OS_UNIX)
const QModelIndex rootIndex = model.setRootPath(QStringLiteral("/dev/")); const QModelIndex rootIndex = model.setRootPath(QStringLiteral("/dev/"));
const QString testFileName = QStringLiteral("null"); const QString testFileName = QStringLiteral("null");
#elif defined(Q_OS_WIN)
const QModelIndex rootIndex = model.setRootPath(flatDirTestPath);
const QString testFileName = QStringLiteral("linkSource.lnk");
QFile file(flatDirTestPath + QLatin1String("/linkTarget.txt"));
QVERIFY(file.open(QIODevice::WriteOnly));
file.close();
QVERIFY(file.link(flatDirTestPath + '/' + testFileName));
#else
QSKIP("Not implemented");
QModelIndex rootIndex;
QString testFileName;
#endif
QTRY_VERIFY(fileListUnderIndex(&model, rootIndex).contains(testFileName)); QTRY_VERIFY(fileListUnderIndex(&model, rootIndex).contains(testFileName));

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 B

View File

@ -96,6 +96,9 @@ private Q_SLOTS:
void taskQTBUG_7902_contextMenuCrash(); void taskQTBUG_7902_contextMenuCrash();
#endif #endif
void taskQTBUG_48157_dprPixmap();
void taskQTBUG_48157_dprMovie();
private: private:
QLabel *testWidget; QLabel *testWidget;
QPointer<Widget> test_box; QPointer<Widget> test_box;
@ -541,5 +544,26 @@ void tst_QLabel::taskQTBUG_7902_contextMenuCrash()
} }
#endif #endif
void tst_QLabel::taskQTBUG_48157_dprPixmap()
{
QLabel label;
QPixmap pixmap;
pixmap.load(QFINDTESTDATA(QStringLiteral("red@2x.png")));
QCOMPARE(pixmap.devicePixelRatio(), 2.0);
label.setPixmap(pixmap);
QCOMPARE(label.sizeHint(), pixmap.rect().size() / pixmap.devicePixelRatio());
}
void tst_QLabel::taskQTBUG_48157_dprMovie()
{
QLabel label;
QMovie movie;
movie.setFileName(QFINDTESTDATA(QStringLiteral("red@2x.png")));
movie.start();
QCOMPARE(movie.currentPixmap().devicePixelRatio(), 2.0);
label.setMovie(&movie);
QCOMPARE(label.sizeHint(), movie.currentPixmap().size() / movie.currentPixmap().devicePixelRatio());
}
QTEST_MAIN(tst_QLabel) QTEST_MAIN(tst_QLabel)
#include "tst_qlabel.moc" #include "tst_qlabel.moc"

View File

@ -0,0 +1,6 @@
TEMPLATE = app
TARGET = childwidget
INCLUDEPATH += .
QT += widgets
SOURCES += main.cpp

View File

@ -0,0 +1,92 @@
/****************************************************************************
**
** 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 <QtWidgets>
class CursorWidget : public QWidget
{
public:
CursorWidget(QCursor cursor, QColor color)
:m_cursor(cursor)
,m_color(color)
{
if (cursor.shape() == Qt::ArrowCursor)
unsetCursor();
else
setCursor(cursor);
}
void paintEvent(QPaintEvent *e)
{
QPainter p(this);
p.fillRect(e->rect(), m_color);
}
void mousePressEvent(QMouseEvent *)
{
// Toggle cursor
QCursor newCursor = (cursor().shape() == m_cursor.shape()) ? QCursor() : m_cursor;
if (newCursor.shape() == Qt::ArrowCursor)
unsetCursor();
else
setCursor(newCursor);
}
private:
QCursor m_cursor;
QColor m_color;
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
// Test child widgets (one of which is native) with set cursors.
// Click window to toggle cursor.
CursorWidget w1((QCursor(Qt::SizeVerCursor)), QColor(Qt::blue).darker());
w1.resize(200, 200);
w1.show();
CursorWidget w2((QCursor(Qt::OpenHandCursor)), QColor(Qt::red).darker());
w2.setParent(&w1);
w2.setGeometry(0, 0, 100, 100);
w2.show();
CursorWidget w3((QCursor(Qt::IBeamCursor)), QColor(Qt::green).darker());
w3.winId();
w3.setParent(&w1);
w3.setGeometry(100, 100, 100, 100);
w3.show();
return app.exec();
}

View File

@ -0,0 +1,5 @@
TEMPLATE = app
TARGET = childwindow
INCLUDEPATH += .
SOURCES += main.cpp

View File

@ -0,0 +1,91 @@
/****************************************************************************
**
** 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 <QtGui>
class CursorWindow : public QRasterWindow
{
public:
CursorWindow(QCursor cursor, QColor color)
:m_cursor(cursor)
,m_color(color)
{
if (cursor.shape() == Qt::ArrowCursor)
unsetCursor();
else
setCursor(cursor);
}
void paintEvent(QPaintEvent *e)
{
QPainter p(this);
p.fillRect(e->rect(), m_color);
}
void mousePressEvent(QMouseEvent *)
{
// Toggle cursor
QCursor newCursor = (cursor().shape() == m_cursor.shape()) ? QCursor() : m_cursor;
if (newCursor.shape() == Qt::ArrowCursor)
unsetCursor();
else
setCursor(newCursor);
}
private:
QCursor m_cursor;
QColor m_color;
};
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
// Test child windows with set cursors. Create parent window and
// two child windows. Click window to toggle cursor.
CursorWindow w1((QCursor(Qt::SizeVerCursor)), QColor(Qt::blue).darker());
w1.resize(200, 200);
w1.show();
CursorWindow w2((QCursor(Qt::OpenHandCursor)), QColor(Qt::red).darker());
w2.setParent(&w1);
w2.setGeometry(0, 0, 100, 100);
w2.show();
CursorWindow w3((QCursor(Qt::IBeamCursor)), QColor(Qt::green).darker());
w3.setParent(&w1);
w3.setGeometry(100, 100, 100, 100);
w3.show();
return app.exec();
}

View File

@ -0,0 +1,6 @@
TEMPLATE = app
TARGET = childwindowcontainer
INCLUDEPATH += .
QT += widgets
SOURCES += main.cpp

View File

@ -0,0 +1,138 @@
/****************************************************************************
**
** 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 <QtWidgets>
class CursorWindow : public QRasterWindow
{
public:
CursorWindow(QCursor cursor, QColor color)
:m_cursor(cursor)
,m_color(color)
{
if (cursor.shape() == Qt::ArrowCursor)
unsetCursor();
else
setCursor(cursor);
}
void paintEvent(QPaintEvent *e)
{
QPainter p(this);
p.fillRect(e->rect(), m_color);
}
void mousePressEvent(QMouseEvent *)
{
// Toggle cursor
QCursor newCursor = (cursor().shape() == m_cursor.shape()) ? QCursor() : m_cursor;
if (newCursor.shape() == Qt::ArrowCursor)
unsetCursor();
else
setCursor(newCursor);
}
private:
QCursor m_cursor;
QColor m_color;
};
class CursorWidget : public QWidget
{
public:
CursorWidget(QCursor cursor, QColor color)
:m_cursor(cursor)
,m_color(color)
{
if (cursor.shape() == Qt::ArrowCursor)
unsetCursor();
else
setCursor(cursor);
}
void paintEvent(QPaintEvent *e)
{
QPainter p(this);
p.fillRect(e->rect(), m_color);
}
void mousePressEvent(QMouseEvent *)
{
// Toggle cursor
QCursor newCursor = (cursor().shape() == m_cursor.shape()) ? QCursor() : m_cursor;
if (newCursor.shape() == Qt::ArrowCursor)
unsetCursor();
else
setCursor(newCursor);
}
private:
QCursor m_cursor;
QColor m_color;
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
{
// Create top-level windowContainer with window. Setting the cursor
// for the container should set the cursor for the window as well.
// Setting the cursor for the window overrides the cursor for the
// container. The example starts out with a window cursor; click
// to fall back to the container cursor.
CursorWindow *w1 = new CursorWindow(QCursor(Qt::OpenHandCursor), QColor(Qt::red).darker());
QWidget* container = QWidget::createWindowContainer(w1);
container->resize(200, 200);
container->setCursor(Qt::PointingHandCursor);
container->show();
}
{
// Similar to above, but with a top-level QWiget
CursorWidget *w1 = new CursorWidget(QCursor(Qt::IBeamCursor), QColor(Qt::green).darker());
w1->resize(200, 200);
CursorWindow *w2 = new CursorWindow(QCursor(Qt::OpenHandCursor), QColor(Qt::red).darker());
QWidget* container = QWidget::createWindowContainer(w2);
container->winId(); // must make the container native, otherwise setCursor
// sets the cursor on a QWindowContainerClassWindow which
// is outside the QWindow hierarchy (macOS).
container->setParent(w1);
container->setCursor(Qt::PointingHandCursor);
container->setGeometry(0, 0, 100, 100);
w1->show();
}
return app.exec();
}

View File

@ -1,3 +1,3 @@
TEMPLATE = subdirs TEMPLATE = subdirs
SUBDIRS = allcursors grab_override qcursorhighdpi SUBDIRS = allcursors childwidget childwindow childwindowcontainer grab_override qcursorhighdpi