Merge remote-tracking branch 'origin/5.12' into 5.13
Conflicts: src/network/access/http2/hpacktable_p.h Change-Id: Ie0c296667dfdebba84f4858056a1ac80c24ee7df
This commit is contained in:
commit
2add2dbdaa
@ -84,6 +84,7 @@ Win32MakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
|
|||||||
if (impexts.isEmpty())
|
if (impexts.isEmpty())
|
||||||
impexts = project->values("QMAKE_EXTENSION_STATICLIB");
|
impexts = project->values("QMAKE_EXTENSION_STATICLIB");
|
||||||
QList<QMakeLocalFileName> dirs;
|
QList<QMakeLocalFileName> dirs;
|
||||||
|
int libidx = 0;
|
||||||
for (const ProString &dlib : project->values("QMAKE_DEFAULT_LIBDIRS"))
|
for (const ProString &dlib : project->values("QMAKE_DEFAULT_LIBDIRS"))
|
||||||
dirs.append(QMakeLocalFileName(dlib.toQString()));
|
dirs.append(QMakeLocalFileName(dlib.toQString()));
|
||||||
static const char * const lflags[] = { "LIBS", "LIBS_PRIVATE",
|
static const char * const lflags[] = { "LIBS", "LIBS_PRIVATE",
|
||||||
@ -96,11 +97,12 @@ Win32MakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
|
|||||||
LibFlagType type = parseLibFlag(opt, &arg);
|
LibFlagType type = parseLibFlag(opt, &arg);
|
||||||
if (type == LibFlagPath) {
|
if (type == LibFlagPath) {
|
||||||
QMakeLocalFileName lp(arg.toQString());
|
QMakeLocalFileName lp(arg.toQString());
|
||||||
if (dirs.contains(lp)) {
|
int idx = dirs.indexOf(lp);
|
||||||
|
if (idx >= 0 && idx < libidx) {
|
||||||
it = l.erase(it);
|
it = l.erase(it);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dirs.append(lp);
|
dirs.insert(libidx++, lp);
|
||||||
(*it) = "-L" + lp.real();
|
(*it) = "-L" + lp.real();
|
||||||
} else if (type == LibFlagLib) {
|
} else if (type == LibFlagLib) {
|
||||||
QString lib = arg.toQString();
|
QString lib = arg.toQString();
|
||||||
|
@ -912,16 +912,20 @@ QTemporaryFile *QTemporaryFile::createNativeFile(QFile &file)
|
|||||||
file.open(QIODevice::ReadOnly);
|
file.open(QIODevice::ReadOnly);
|
||||||
//dump data
|
//dump data
|
||||||
QTemporaryFile *ret = new QTemporaryFile;
|
QTemporaryFile *ret = new QTemporaryFile;
|
||||||
ret->open();
|
if (ret->open()) {
|
||||||
file.seek(0);
|
file.seek(0);
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
while(true) {
|
while (true) {
|
||||||
qint64 len = file.read(buffer, 1024);
|
qint64 len = file.read(buffer, 1024);
|
||||||
if(len < 1)
|
if (len < 1)
|
||||||
break;
|
break;
|
||||||
ret->write(buffer, len);
|
ret->write(buffer, len);
|
||||||
|
}
|
||||||
|
ret->seek(0);
|
||||||
|
} else {
|
||||||
|
delete ret;
|
||||||
|
ret = nullptr;
|
||||||
}
|
}
|
||||||
ret->seek(0);
|
|
||||||
//restore
|
//restore
|
||||||
if(wasOpen)
|
if(wasOpen)
|
||||||
file.seek(old_off);
|
file.seek(old_off);
|
||||||
|
@ -65,6 +65,19 @@ QCFString::operator CFStringRef() const
|
|||||||
|
|
||||||
#if defined(QT_USE_APPLE_UNIFIED_LOGGING)
|
#if defined(QT_USE_APPLE_UNIFIED_LOGGING)
|
||||||
|
|
||||||
|
bool AppleUnifiedLogger::willMirrorToStderr()
|
||||||
|
{
|
||||||
|
// When running under Xcode or LLDB, one or more of these variables will
|
||||||
|
// be set, which triggers libsystem_trace.dyld to log messages to stderr
|
||||||
|
// as well, via_os_log_impl_mirror_to_stderr. Un-setting these variables
|
||||||
|
// is not an option, as that would silence normal NSLog or os_log calls,
|
||||||
|
// so instead we skip our own stderr output. See rdar://36919139.
|
||||||
|
static bool willMirror = qEnvironmentVariableIsSet("OS_ACTIVITY_DT_MODE")
|
||||||
|
|| qEnvironmentVariableIsSet("ACTIVITY_LOG_STDERR")
|
||||||
|
|| qEnvironmentVariableIsSet("CFLOG_FORCE_STDERR");
|
||||||
|
return willMirror;
|
||||||
|
}
|
||||||
|
|
||||||
QT_MAC_WEAK_IMPORT(_os_log_default);
|
QT_MAC_WEAK_IMPORT(_os_log_default);
|
||||||
bool AppleUnifiedLogger::messageHandler(QtMsgType msgType, const QMessageLogContext &context,
|
bool AppleUnifiedLogger::messageHandler(QtMsgType msgType, const QMessageLogContext &context,
|
||||||
const QString &message, const QString &optionalSubsystem)
|
const QString &message, const QString &optionalSubsystem)
|
||||||
@ -103,15 +116,7 @@ bool AppleUnifiedLogger::messageHandler(QtMsgType msgType, const QMessageLogCont
|
|||||||
// system from redacting our log message.
|
// system from redacting our log message.
|
||||||
os_log_with_type(log, logType, "%{public}s", qPrintable(message));
|
os_log_with_type(log, logType, "%{public}s", qPrintable(message));
|
||||||
|
|
||||||
// When running under Xcode or LLDB, one or more of these variables will
|
return willMirrorToStderr();
|
||||||
// be set, which triggers libsystem_trace.dyld to log messages to stderr
|
|
||||||
// as well, via_os_log_impl_mirror_to_stderr. Un-setting these variables
|
|
||||||
// is not an option, as that would silence normal NSLog or os_log calls,
|
|
||||||
// so instead we skip our own stderr output. See rdar://36919139.
|
|
||||||
static bool mirroredToStderr = qEnvironmentVariableIsSet("OS_ACTIVITY_DT_MODE")
|
|
||||||
|| qEnvironmentVariableIsSet("ACTIVITY_LOG_STDERR")
|
|
||||||
|| qEnvironmentVariableIsSet("CFLOG_FORCE_STDERR");
|
|
||||||
return mirroredToStderr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
os_log_type_t AppleUnifiedLogger::logTypeForMessageType(QtMsgType msgType)
|
os_log_type_t AppleUnifiedLogger::logTypeForMessageType(QtMsgType msgType)
|
||||||
|
@ -202,6 +202,7 @@ class Q_CORE_EXPORT AppleUnifiedLogger
|
|||||||
public:
|
public:
|
||||||
static bool messageHandler(QtMsgType msgType, const QMessageLogContext &context, const QString &message,
|
static bool messageHandler(QtMsgType msgType, const QMessageLogContext &context, const QString &message,
|
||||||
const QString &subsystem = QString());
|
const QString &subsystem = QString());
|
||||||
|
static bool willMirrorToStderr();
|
||||||
private:
|
private:
|
||||||
static os_log_type_t logTypeForMessageType(QtMsgType msgType);
|
static os_log_type_t logTypeForMessageType(QtMsgType msgType);
|
||||||
static os_log_t cachedLog(const QString &subsystem, const QString &category);
|
static os_log_t cachedLog(const QString &subsystem, const QString &category);
|
||||||
|
@ -818,6 +818,16 @@ void QThread::quit()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QThread::exit(int returnCode)
|
||||||
|
{
|
||||||
|
Q_D(QThread);
|
||||||
|
d->data->quitNow = true;
|
||||||
|
for (int i = 0; i < d->data->eventLoops.size(); ++i) {
|
||||||
|
QEventLoop *eventLoop = d->data->eventLoops.at(i);
|
||||||
|
eventLoop->exit(returnCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool QThread::wait(unsigned long time)
|
bool QThread::wait(unsigned long time)
|
||||||
{
|
{
|
||||||
Q_UNUSED(time);
|
Q_UNUSED(time);
|
||||||
|
@ -91,16 +91,29 @@ macro(_qt5gui_find_extra_libs Name Libs LibDir IncDirs)
|
|||||||
endforeach()
|
endforeach()
|
||||||
!!ENDIF
|
!!ENDIF
|
||||||
foreach(_lib ${Libs})
|
foreach(_lib ${Libs})
|
||||||
string(REGEX REPLACE "[^_A-Za-z0-9]" "_" _cmake_lib_name ${_lib})
|
if (IS_ABSOLUTE ${_lib})
|
||||||
|
get_filename_component(_libFile ${_lib} NAME_WE)
|
||||||
|
if (_libFile MATCHES \"^${CMAKE_SHARED_LIBRARY_PREFIX}(.*)\")
|
||||||
|
set(_libFile ${CMAKE_MATCH_1})
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(_libFile ${_lib})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
string(REGEX REPLACE "[^_A-Za-z0-9]" "_" _cmake_lib_name ${_libFile})
|
||||||
if (NOT TARGET Qt5::Gui_${_cmake_lib_name} AND NOT _Qt5Gui_${_cmake_lib_name}_LIBRARY_DONE)
|
if (NOT TARGET Qt5::Gui_${_cmake_lib_name} AND NOT _Qt5Gui_${_cmake_lib_name}_LIBRARY_DONE)
|
||||||
find_library(Qt5Gui_${_cmake_lib_name}_LIBRARY ${_lib}
|
if (IS_ABSOLUTE ${_lib})
|
||||||
|
set(Qt5Gui_${_cmake_lib_name}_LIBRARY ${_lib})
|
||||||
|
else()
|
||||||
|
find_library(Qt5Gui_${_cmake_lib_name}_LIBRARY ${_lib}
|
||||||
!!IF !isEmpty(CROSS_COMPILE)
|
!!IF !isEmpty(CROSS_COMPILE)
|
||||||
PATHS \"${LibDir}\"
|
PATHS \"${LibDir}\"
|
||||||
!!IF !mac
|
!!IF !mac
|
||||||
NO_DEFAULT_PATH
|
NO_DEFAULT_PATH
|
||||||
!!ENDIF
|
!!ENDIF
|
||||||
!!ENDIF
|
!!ENDIF
|
||||||
)
|
)
|
||||||
|
endif()
|
||||||
!!IF mac
|
!!IF mac
|
||||||
set(Qt5Gui_${_cmake_lib_name}_LIBRARY "${Qt5Gui_${_cmake_lib_name}_LIBRARY}/${_lib}")
|
set(Qt5Gui_${_cmake_lib_name}_LIBRARY "${Qt5Gui_${_cmake_lib_name}_LIBRARY}/${_lib}")
|
||||||
if (NOT EXISTS "${Qt5Gui_${_cmake_lib_name}_LIBRARY}")
|
if (NOT EXISTS "${Qt5Gui_${_cmake_lib_name}_LIBRARY}")
|
||||||
|
@ -114,6 +114,18 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
|
|||||||
externalFormat = GL_BGRA;
|
externalFormat = GL_BGRA;
|
||||||
internalFormat = GL_RGBA;
|
internalFormat = GL_RGBA;
|
||||||
pixelType = GL_UNSIGNED_INT_8_8_8_8_REV;
|
pixelType = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||||
|
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||||
|
// Without GL_UNSIGNED_INT_8_8_8_8_REV, BGRA only matches ARGB on little endian:
|
||||||
|
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::BGRATextureFormat) && !sRgbBinding) {
|
||||||
|
// The GL_EXT_texture_format_BGRA8888 extension requires the internal format to match the external.
|
||||||
|
externalFormat = internalFormat = GL_BGRA;
|
||||||
|
pixelType = GL_UNSIGNED_BYTE;
|
||||||
|
} else if (context->isOpenGLES() && context->hasExtension(QByteArrayLiteral("GL_APPLE_texture_format_BGRA8888"))) {
|
||||||
|
// Is only allowed as an external format like OpenGL.
|
||||||
|
externalFormat = GL_BGRA;
|
||||||
|
internalFormat = GL_RGBA;
|
||||||
|
pixelType = GL_UNSIGNED_BYTE;
|
||||||
|
#endif
|
||||||
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
|
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
|
||||||
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||||
GLint swizzle[4] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA };
|
GLint swizzle[4] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA };
|
||||||
@ -125,25 +137,8 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
|
|||||||
externalFormat = internalFormat = GL_RGBA;
|
externalFormat = internalFormat = GL_RGBA;
|
||||||
pixelType = GL_UNSIGNED_BYTE;
|
pixelType = GL_UNSIGNED_BYTE;
|
||||||
} else {
|
} else {
|
||||||
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
// No support for direct ARGB32 upload.
|
||||||
// Without GL_UNSIGNED_INT_8_8_8_8_REV, BGRA only matches ARGB on little endian.
|
|
||||||
if (funcs->hasOpenGLExtension(QOpenGLExtensions::BGRATextureFormat) && !sRgbBinding) {
|
|
||||||
// The GL_EXT_texture_format_BGRA8888 extension requires the internal format to match the external.
|
|
||||||
externalFormat = internalFormat = GL_BGRA;
|
|
||||||
pixelType = GL_UNSIGNED_BYTE;
|
|
||||||
} else if (context->isOpenGLES() && context->hasExtension(QByteArrayLiteral("GL_APPLE_texture_format_BGRA8888"))) {
|
|
||||||
// Is only allowed as an external format like OpenGL.
|
|
||||||
externalFormat = GL_BGRA;
|
|
||||||
internalFormat = GL_RGBA;
|
|
||||||
pixelType = GL_UNSIGNED_BYTE;
|
|
||||||
} else {
|
|
||||||
// No support for direct ARGB32 upload.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Big endian requires GL_UNSIGNED_INT_8_8_8_8_REV for ARGB to match BGRA
|
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
targetFormat = image.format();
|
targetFormat = image.format();
|
||||||
break;
|
break;
|
||||||
|
@ -333,7 +333,9 @@ static ShiftResult shift(const QBezier *orig, QBezier *shifted, qreal offset, qr
|
|||||||
*shifted = QBezier::fromPoints(points_shifted[map[0]], points_shifted[map[1]],
|
*shifted = QBezier::fromPoints(points_shifted[map[0]], points_shifted[map[1]],
|
||||||
points_shifted[map[2]], points_shifted[map[3]]);
|
points_shifted[map[2]], points_shifted[map[3]]);
|
||||||
|
|
||||||
return good_offset(orig, shifted, offset, threshold);
|
if (np > 2)
|
||||||
|
return good_offset(orig, shifted, offset, threshold);
|
||||||
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This value is used to determine the length of control point vectors
|
// This value is used to determine the length of control point vectors
|
||||||
@ -432,7 +434,6 @@ redo:
|
|||||||
} else if (res == Ok) {
|
} else if (res == Ok) {
|
||||||
++o;
|
++o;
|
||||||
--b;
|
--b;
|
||||||
continue;
|
|
||||||
} else if (res == Circle && maxSegments - (o - curveSegments) >= 2) {
|
} else if (res == Circle && maxSegments - (o - curveSegments) >= 2) {
|
||||||
// add semi circle
|
// add semi circle
|
||||||
if (addCircle(b, offset, o))
|
if (addCircle(b, offset, o))
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include <QtCore/qdebug.h>
|
#include <QtCore/qdebug.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ HeaderSize entry_size(const QByteArray &name, const QByteArray &value)
|
|||||||
// for counting the number of references to the name and value would have
|
// for counting the number of references to the name and value would have
|
||||||
// 32 octets of overhead."
|
// 32 octets of overhead."
|
||||||
|
|
||||||
const unsigned sum = unsigned(name.size()) + value.size();
|
const unsigned sum = unsigned(name.size() + value.size());
|
||||||
if (std::numeric_limits<unsigned>::max() - 32 < sum)
|
if (std::numeric_limits<unsigned>::max() - 32 < sum)
|
||||||
return HeaderSize();
|
return HeaderSize();
|
||||||
return HeaderSize(true, quint32(sum + 32));
|
return HeaderSize(true, quint32(sum + 32));
|
||||||
@ -75,7 +76,7 @@ int compare(const QByteArray &lhs, const QByteArray &rhs)
|
|||||||
if (const int minLen = std::min(lhs.size(), rhs.size())) {
|
if (const int minLen = std::min(lhs.size(), rhs.size())) {
|
||||||
// We use memcmp, since strings in headers are allowed
|
// We use memcmp, since strings in headers are allowed
|
||||||
// to contain '\0'.
|
// to contain '\0'.
|
||||||
const int cmp = std::memcmp(lhs.constData(), rhs.constData(), minLen);
|
const int cmp = std::memcmp(lhs.constData(), rhs.constData(), std::size_t(minLen));
|
||||||
if (cmp)
|
if (cmp)
|
||||||
return cmp;
|
return cmp;
|
||||||
}
|
}
|
||||||
@ -138,82 +139,6 @@ bool FieldLookupTable::SearchEntry::operator < (const SearchEntry &rhs)const
|
|||||||
return offset > rhs.offset;
|
return offset > rhs.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This data is from HPACK's specs and it's quite
|
|
||||||
// conveniently sorted == works with binary search as it is.
|
|
||||||
// Later this can probably change and instead of simple
|
|
||||||
// vector we'll just reuse FieldLookupTable.
|
|
||||||
// TODO: it makes sense to generate this table while ...
|
|
||||||
// configuring/building Qt (some script downloading/parsing/generating
|
|
||||||
// would be quite handy).
|
|
||||||
const std::vector<HeaderField> &staticTable()
|
|
||||||
{
|
|
||||||
static std::vector<HeaderField> table = {
|
|
||||||
{":authority", ""},
|
|
||||||
{":method", "GET"},
|
|
||||||
{":method", "POST"},
|
|
||||||
{":path", "/"},
|
|
||||||
{":path", "/index.html"},
|
|
||||||
{":scheme", "http"},
|
|
||||||
{":scheme", "https"},
|
|
||||||
{":status", "200"},
|
|
||||||
{":status", "204"},
|
|
||||||
{":status", "206"},
|
|
||||||
{":status", "304"},
|
|
||||||
{":status", "400"},
|
|
||||||
{":status", "404"},
|
|
||||||
{":status", "500"},
|
|
||||||
{"accept-charset", ""},
|
|
||||||
{"accept-encoding", "gzip, deflate"},
|
|
||||||
{"accept-language", ""},
|
|
||||||
{"accept-ranges", ""},
|
|
||||||
{"accept", ""},
|
|
||||||
{"access-control-allow-origin", ""},
|
|
||||||
{"age", ""},
|
|
||||||
{"allow", ""},
|
|
||||||
{"authorization", ""},
|
|
||||||
{"cache-control", ""},
|
|
||||||
{"content-disposition", ""},
|
|
||||||
{"content-encoding", ""},
|
|
||||||
{"content-language", ""},
|
|
||||||
{"content-length", ""},
|
|
||||||
{"content-location", ""},
|
|
||||||
{"content-range", ""},
|
|
||||||
{"content-type", ""},
|
|
||||||
{"cookie", ""},
|
|
||||||
{"date", ""},
|
|
||||||
{"etag", ""},
|
|
||||||
{"expect", ""},
|
|
||||||
{"expires", ""},
|
|
||||||
{"from", ""},
|
|
||||||
{"host", ""},
|
|
||||||
{"if-match", ""},
|
|
||||||
{"if-modified-since", ""},
|
|
||||||
{"if-none-match", ""},
|
|
||||||
{"if-range", ""},
|
|
||||||
{"if-unmodified-since", ""},
|
|
||||||
{"last-modified", ""},
|
|
||||||
{"link", ""},
|
|
||||||
{"location", ""},
|
|
||||||
{"max-forwards", ""},
|
|
||||||
{"proxy-authenticate", ""},
|
|
||||||
{"proxy-authorization", ""},
|
|
||||||
{"range", ""},
|
|
||||||
{"referer", ""},
|
|
||||||
{"refresh", ""},
|
|
||||||
{"retry-after", ""},
|
|
||||||
{"server", ""},
|
|
||||||
{"set-cookie", ""},
|
|
||||||
{"strict-transport-security", ""},
|
|
||||||
{"transfer-encoding", ""},
|
|
||||||
{"user-agent", ""},
|
|
||||||
{"vary", ""},
|
|
||||||
{"via", ""},
|
|
||||||
{"www-authenticate", ""}
|
|
||||||
};
|
|
||||||
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
|
|
||||||
FieldLookupTable::FieldLookupTable(quint32 maxSize, bool use)
|
FieldLookupTable::FieldLookupTable(quint32 maxSize, bool use)
|
||||||
: maxTableSize(maxSize),
|
: maxTableSize(maxSize),
|
||||||
tableCapacity(maxSize),
|
tableCapacity(maxSize),
|
||||||
@ -296,12 +221,12 @@ void FieldLookupTable::evictEntry()
|
|||||||
|
|
||||||
quint32 FieldLookupTable::numberOfEntries() const
|
quint32 FieldLookupTable::numberOfEntries() const
|
||||||
{
|
{
|
||||||
return quint32(staticTable().size()) + nDynamic;
|
return quint32(staticPart().size()) + nDynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
quint32 FieldLookupTable::numberOfStaticEntries() const
|
quint32 FieldLookupTable::numberOfStaticEntries() const
|
||||||
{
|
{
|
||||||
return quint32(staticTable().size());
|
return quint32(staticPart().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
quint32 FieldLookupTable::numberOfDynamicEntries() const
|
quint32 FieldLookupTable::numberOfDynamicEntries() const
|
||||||
@ -326,24 +251,18 @@ void FieldLookupTable::clearDynamicTable()
|
|||||||
|
|
||||||
bool FieldLookupTable::indexIsValid(quint32 index) const
|
bool FieldLookupTable::indexIsValid(quint32 index) const
|
||||||
{
|
{
|
||||||
return index && index <= staticTable().size() + nDynamic;
|
return index && index <= staticPart().size() + nDynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
quint32 FieldLookupTable::indexOf(const QByteArray &name, const QByteArray &value)const
|
quint32 FieldLookupTable::indexOf(const QByteArray &name, const QByteArray &value)const
|
||||||
{
|
{
|
||||||
// Start from the static part first:
|
// Start from the static part first:
|
||||||
const auto &table = staticTable();
|
const auto &table = staticPart();
|
||||||
const HeaderField field(name, value);
|
const HeaderField field(name, value);
|
||||||
const auto staticPos = std::lower_bound(table.begin(), table.end(), field,
|
const auto staticPos = findInStaticPart(field, CompareMode::nameAndValue);
|
||||||
[](const HeaderField &lhs, const HeaderField &rhs) {
|
|
||||||
int cmp = compare(lhs.name, rhs.name);
|
|
||||||
if (cmp)
|
|
||||||
return cmp < 0;
|
|
||||||
return compare(lhs.value, rhs.value) < 0;
|
|
||||||
});
|
|
||||||
if (staticPos != table.end()) {
|
if (staticPos != table.end()) {
|
||||||
if (staticPos->name == name && staticPos->value == value)
|
if (staticPos->name == name && staticPos->value == value)
|
||||||
return staticPos - table.begin() + 1;
|
return quint32(staticPos - table.begin() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we have to lookup in our dynamic part ...
|
// Now we have to lookup in our dynamic part ...
|
||||||
@ -366,15 +285,12 @@ quint32 FieldLookupTable::indexOf(const QByteArray &name, const QByteArray &valu
|
|||||||
quint32 FieldLookupTable::indexOf(const QByteArray &name) const
|
quint32 FieldLookupTable::indexOf(const QByteArray &name) const
|
||||||
{
|
{
|
||||||
// Start from the static part first:
|
// Start from the static part first:
|
||||||
const auto &table = staticTable();
|
const auto &table = staticPart();
|
||||||
const HeaderField field(name, QByteArray());
|
const HeaderField field(name, QByteArray());
|
||||||
const auto staticPos = std::lower_bound(table.begin(), table.end(), field,
|
const auto staticPos = findInStaticPart(field, CompareMode::nameOnly);
|
||||||
[](const HeaderField &lhs, const HeaderField &rhs) {
|
|
||||||
return compare(lhs.name, rhs.name) < 0;
|
|
||||||
});
|
|
||||||
if (staticPos != table.end()) {
|
if (staticPos != table.end()) {
|
||||||
if (staticPos->name == name)
|
if (staticPos->name == name)
|
||||||
return staticPos - table.begin() + 1;
|
return quint32(staticPos - table.begin() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we have to lookup in our dynamic part ...
|
// Now we have to lookup in our dynamic part ...
|
||||||
@ -402,7 +318,7 @@ bool FieldLookupTable::field(quint32 index, QByteArray *name, QByteArray *value)
|
|||||||
if (!indexIsValid(index))
|
if (!indexIsValid(index))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const auto &table = staticTable();
|
const auto &table = staticPart();
|
||||||
if (index - 1 < table.size()) {
|
if (index - 1 < table.size()) {
|
||||||
*name = table[index - 1].name;
|
*name = table[index - 1].name;
|
||||||
*value = table[index - 1].value;
|
*value = table[index - 1].value;
|
||||||
@ -477,7 +393,7 @@ quint32 FieldLookupTable::keyToIndex(const SearchEntry &key) const
|
|||||||
Q_ASSERT(offset < ChunkSize);
|
Q_ASSERT(offset < ChunkSize);
|
||||||
Q_ASSERT(chunkIndex || offset >= begin);
|
Q_ASSERT(chunkIndex || offset >= begin);
|
||||||
|
|
||||||
return quint32(offset + chunkIndex * ChunkSize - begin + 1 + staticTable().size());
|
return quint32(offset + chunkIndex * ChunkSize - begin + 1 + staticPart().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldLookupTable::SearchEntry FieldLookupTable::frontKey() const
|
FieldLookupTable::SearchEntry FieldLookupTable::frontKey() const
|
||||||
@ -526,6 +442,103 @@ void FieldLookupTable::setMaxDynamicTableSize(quint32 size)
|
|||||||
updateDynamicTableSize(size);
|
updateDynamicTableSize(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This data is from the HPACK's specs and it's quite conveniently sorted,
|
||||||
|
// except ... 'accept' is in the wrong position, see how we handle it below.
|
||||||
|
const std::vector<HeaderField> &FieldLookupTable::staticPart()
|
||||||
|
{
|
||||||
|
static std::vector<HeaderField> table = {
|
||||||
|
{":authority", ""},
|
||||||
|
{":method", "GET"},
|
||||||
|
{":method", "POST"},
|
||||||
|
{":path", "/"},
|
||||||
|
{":path", "/index.html"},
|
||||||
|
{":scheme", "http"},
|
||||||
|
{":scheme", "https"},
|
||||||
|
{":status", "200"},
|
||||||
|
{":status", "204"},
|
||||||
|
{":status", "206"},
|
||||||
|
{":status", "304"},
|
||||||
|
{":status", "400"},
|
||||||
|
{":status", "404"},
|
||||||
|
{":status", "500"},
|
||||||
|
{"accept-charset", ""},
|
||||||
|
{"accept-encoding", "gzip, deflate"},
|
||||||
|
{"accept-language", ""},
|
||||||
|
{"accept-ranges", ""},
|
||||||
|
{"accept", ""},
|
||||||
|
{"access-control-allow-origin", ""},
|
||||||
|
{"age", ""},
|
||||||
|
{"allow", ""},
|
||||||
|
{"authorization", ""},
|
||||||
|
{"cache-control", ""},
|
||||||
|
{"content-disposition", ""},
|
||||||
|
{"content-encoding", ""},
|
||||||
|
{"content-language", ""},
|
||||||
|
{"content-length", ""},
|
||||||
|
{"content-location", ""},
|
||||||
|
{"content-range", ""},
|
||||||
|
{"content-type", ""},
|
||||||
|
{"cookie", ""},
|
||||||
|
{"date", ""},
|
||||||
|
{"etag", ""},
|
||||||
|
{"expect", ""},
|
||||||
|
{"expires", ""},
|
||||||
|
{"from", ""},
|
||||||
|
{"host", ""},
|
||||||
|
{"if-match", ""},
|
||||||
|
{"if-modified-since", ""},
|
||||||
|
{"if-none-match", ""},
|
||||||
|
{"if-range", ""},
|
||||||
|
{"if-unmodified-since", ""},
|
||||||
|
{"last-modified", ""},
|
||||||
|
{"link", ""},
|
||||||
|
{"location", ""},
|
||||||
|
{"max-forwards", ""},
|
||||||
|
{"proxy-authenticate", ""},
|
||||||
|
{"proxy-authorization", ""},
|
||||||
|
{"range", ""},
|
||||||
|
{"referer", ""},
|
||||||
|
{"refresh", ""},
|
||||||
|
{"retry-after", ""},
|
||||||
|
{"server", ""},
|
||||||
|
{"set-cookie", ""},
|
||||||
|
{"strict-transport-security", ""},
|
||||||
|
{"transfer-encoding", ""},
|
||||||
|
{"user-agent", ""},
|
||||||
|
{"vary", ""},
|
||||||
|
{"via", ""},
|
||||||
|
{"www-authenticate", ""}
|
||||||
|
};
|
||||||
|
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<HeaderField>::const_iterator FieldLookupTable::findInStaticPart(const HeaderField &field, CompareMode mode)
|
||||||
|
{
|
||||||
|
const auto &table = staticPart();
|
||||||
|
const auto acceptPos = table.begin() + 18;
|
||||||
|
if (field.name == "accept") {
|
||||||
|
if (mode == CompareMode::nameAndValue && field.value != "")
|
||||||
|
return table.end();
|
||||||
|
return acceptPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto predicate = [mode](const HeaderField &lhs, const HeaderField &rhs) {
|
||||||
|
const int cmp = compare(lhs.name, rhs.name);
|
||||||
|
if (cmp)
|
||||||
|
return cmp < 0;
|
||||||
|
else if (mode == CompareMode::nameAndValue)
|
||||||
|
return compare(lhs.value, rhs.value) < 0;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto staticPos = std::lower_bound(table.begin(), acceptPos, field, predicate);
|
||||||
|
if (staticPos != acceptPos)
|
||||||
|
return staticPos;
|
||||||
|
|
||||||
|
return std::lower_bound(acceptPos + 1, table.end(), field, predicate);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -173,6 +173,8 @@ public:
|
|||||||
bool updateDynamicTableSize(quint32 size);
|
bool updateDynamicTableSize(quint32 size);
|
||||||
void setMaxDynamicTableSize(quint32 size);
|
void setMaxDynamicTableSize(quint32 size);
|
||||||
|
|
||||||
|
static const std::vector<HeaderField> &staticPart();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Table's maximum size is controlled
|
// Table's maximum size is controlled
|
||||||
// by SETTINGS_HEADER_TABLE_SIZE (HTTP/2, 6.5.2).
|
// by SETTINGS_HEADER_TABLE_SIZE (HTTP/2, 6.5.2).
|
||||||
@ -225,9 +227,16 @@ private:
|
|||||||
quint32 indexOfChunk(const Chunk *chunk) const;
|
quint32 indexOfChunk(const Chunk *chunk) const;
|
||||||
quint32 keyToIndex(const SearchEntry &key) const;
|
quint32 keyToIndex(const SearchEntry &key) const;
|
||||||
|
|
||||||
|
enum class CompareMode {
|
||||||
|
nameOnly,
|
||||||
|
nameAndValue
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::vector<HeaderField>::const_iterator findInStaticPart(const HeaderField &field, CompareMode mode);
|
||||||
|
|
||||||
mutable QByteArray dummyDst;
|
mutable QByteArray dummyDst;
|
||||||
|
|
||||||
Q_DISABLE_COPY_MOVE(FieldLookupTable);
|
Q_DISABLE_COPY_MOVE(FieldLookupTable)
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -265,7 +265,7 @@ qint64 QNetworkReplyWasmImpl::readData(char *data, qint64 maxlen)
|
|||||||
Q_D(QNetworkReplyWasmImpl);
|
Q_D(QNetworkReplyWasmImpl);
|
||||||
|
|
||||||
qint64 howMuch = qMin(maxlen, (d->downloadBuffer.size() - d->downloadBufferReadPosition));
|
qint64 howMuch = qMin(maxlen, (d->downloadBuffer.size() - d->downloadBufferReadPosition));
|
||||||
memcpy(data, d->downloadBuffer.constData(), howMuch);
|
memcpy(data, d->downloadBuffer.constData() + d->downloadBufferReadPosition, howMuch);
|
||||||
d->downloadBufferReadPosition += howMuch;
|
d->downloadBufferReadPosition += howMuch;
|
||||||
|
|
||||||
return howMuch;
|
return howMuch;
|
||||||
|
@ -179,7 +179,15 @@ static inline bool checkNeedPortalSupport()
|
|||||||
return !QStandardPaths::locate(QStandardPaths::RuntimeLocation, QLatin1String("flatpak-info")).isEmpty() || qEnvironmentVariableIsSet("SNAP");
|
return !QStandardPaths::locate(QStandardPaths::RuntimeLocation, QLatin1String("flatpak-info")).isEmpty() || qEnvironmentVariableIsSet("SNAP");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool xdgDesktopPortalOpenFile(const QUrl &url)
|
static inline bool isPortalReturnPermanent(const QDBusError &error)
|
||||||
|
{
|
||||||
|
// A service unknown error isn't permanent, it just indicates that we
|
||||||
|
// should fall back to the regular way. This check includes
|
||||||
|
// QDBusError::NoError.
|
||||||
|
return error.type() != QDBusError::ServiceUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline QDBusMessage xdgDesktopPortalOpenFile(const QUrl &url)
|
||||||
{
|
{
|
||||||
// DBus signature:
|
// DBus signature:
|
||||||
// OpenFile (IN s parent_window,
|
// OpenFile (IN s parent_window,
|
||||||
@ -198,23 +206,22 @@ static inline bool xdgDesktopPortalOpenFile(const QUrl &url)
|
|||||||
QLatin1String("org.freedesktop.portal.OpenURI"),
|
QLatin1String("org.freedesktop.portal.OpenURI"),
|
||||||
QLatin1String("OpenFile"));
|
QLatin1String("OpenFile"));
|
||||||
|
|
||||||
QDBusUnixFileDescriptor descriptor(fd);
|
QDBusUnixFileDescriptor descriptor;
|
||||||
qt_safe_close(fd);
|
descriptor.giveFileDescriptor(fd);
|
||||||
|
|
||||||
// FIXME parent_window_id and handle writable option
|
// FIXME parent_window_id and handle writable option
|
||||||
message << QString() << QVariant::fromValue(descriptor) << QVariantMap();
|
message << QString() << QVariant::fromValue(descriptor) << QVariantMap();
|
||||||
|
|
||||||
QDBusPendingReply<QDBusObjectPath> reply = QDBusConnection::sessionBus().call(message);
|
return QDBusConnection::sessionBus().call(message);
|
||||||
return !reply.isError();
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Q_UNUSED(url)
|
Q_UNUSED(url)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return false;
|
return QDBusMessage::createError(QDBusError::InternalError, qt_error_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool xdgDesktopPortalOpenUrl(const QUrl &url)
|
static inline QDBusMessage xdgDesktopPortalOpenUrl(const QUrl &url)
|
||||||
{
|
{
|
||||||
// DBus signature:
|
// DBus signature:
|
||||||
// OpenURI (IN s parent_window,
|
// OpenURI (IN s parent_window,
|
||||||
@ -234,11 +241,10 @@ static inline bool xdgDesktopPortalOpenUrl(const QUrl &url)
|
|||||||
// FIXME parent_window_id and handle writable option
|
// FIXME parent_window_id and handle writable option
|
||||||
message << QString() << url.toString() << QVariantMap();
|
message << QString() << url.toString() << QVariantMap();
|
||||||
|
|
||||||
QDBusPendingReply<QDBusObjectPath> reply = QDBusConnection::sessionBus().call(message);
|
return QDBusConnection::sessionBus().call(message);
|
||||||
return !reply.isError();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool xdgDesktopPortalSendEmail(const QUrl &url)
|
static inline QDBusMessage xdgDesktopPortalSendEmail(const QUrl &url)
|
||||||
{
|
{
|
||||||
// DBus signature:
|
// DBus signature:
|
||||||
// ComposeEmail (IN s parent_window,
|
// ComposeEmail (IN s parent_window,
|
||||||
@ -281,8 +287,7 @@ static inline bool xdgDesktopPortalSendEmail(const QUrl &url)
|
|||||||
// FIXME parent_window_id
|
// FIXME parent_window_id
|
||||||
message << QString() << options;
|
message << QString() << options;
|
||||||
|
|
||||||
QDBusPendingReply<QDBusObjectPath> reply = QDBusConnection::sessionBus().call(message);
|
return QDBusConnection::sessionBus().call(message);
|
||||||
return !reply.isError();
|
|
||||||
}
|
}
|
||||||
#endif // QT_CONFIG(dbus)
|
#endif // QT_CONFIG(dbus)
|
||||||
|
|
||||||
@ -296,15 +301,23 @@ bool QGenericUnixServices::openUrl(const QUrl &url)
|
|||||||
{
|
{
|
||||||
if (url.scheme() == QLatin1String("mailto")) {
|
if (url.scheme() == QLatin1String("mailto")) {
|
||||||
#if QT_CONFIG(dbus)
|
#if QT_CONFIG(dbus)
|
||||||
if (checkNeedPortalSupport())
|
if (checkNeedPortalSupport()) {
|
||||||
return xdgDesktopPortalSendEmail(url);
|
QDBusError error = xdgDesktopPortalSendEmail(url);
|
||||||
|
if (isPortalReturnPermanent(error))
|
||||||
|
return !error.isValid();
|
||||||
|
|
||||||
|
// service not running, fall back
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return openDocument(url);
|
return openDocument(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_CONFIG(dbus)
|
#if QT_CONFIG(dbus)
|
||||||
if (checkNeedPortalSupport())
|
if (checkNeedPortalSupport()) {
|
||||||
return xdgDesktopPortalOpenUrl(url);
|
QDBusError error = xdgDesktopPortalOpenUrl(url);
|
||||||
|
if (isPortalReturnPermanent(error))
|
||||||
|
return !error.isValid();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_webBrowser.isEmpty() && !detectWebBrowser(desktopEnvironment(), true, &m_webBrowser)) {
|
if (m_webBrowser.isEmpty() && !detectWebBrowser(desktopEnvironment(), true, &m_webBrowser)) {
|
||||||
@ -317,8 +330,11 @@ bool QGenericUnixServices::openUrl(const QUrl &url)
|
|||||||
bool QGenericUnixServices::openDocument(const QUrl &url)
|
bool QGenericUnixServices::openDocument(const QUrl &url)
|
||||||
{
|
{
|
||||||
#if QT_CONFIG(dbus)
|
#if QT_CONFIG(dbus)
|
||||||
if (checkNeedPortalSupport())
|
if (checkNeedPortalSupport()) {
|
||||||
return xdgDesktopPortalOpenFile(url);
|
QDBusError error = xdgDesktopPortalOpenFile(url);
|
||||||
|
if (isPortalReturnPermanent(error))
|
||||||
|
return !error.isValid();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_documentLauncher.isEmpty() && !detectWebBrowser(desktopEnvironment(), false, &m_documentLauncher)) {
|
if (m_documentLauncher.isEmpty() && !detectWebBrowser(desktopEnvironment(), false, &m_documentLauncher)) {
|
||||||
|
@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
|
Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
|
||||||
Q_LOGGING_CATEGORY(lcQpaDrawing, "qt.qpa.drawing");
|
Q_LOGGING_CATEGORY(lcQpaDrawing, "qt.qpa.drawing");
|
||||||
Q_LOGGING_CATEGORY(lcQpaMouse, "qt.qpa.input.mouse");
|
Q_LOGGING_CATEGORY(lcQpaMouse, "qt.qpa.input.mouse", QtCriticalMsg);
|
||||||
Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen");
|
Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen");
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -137,22 +137,13 @@
|
|||||||
{
|
{
|
||||||
if ((self = [super initWithFrame:NSZeroRect])) {
|
if ((self = [super initWithFrame:NSZeroRect])) {
|
||||||
m_platformWindow = platformWindow;
|
m_platformWindow = platformWindow;
|
||||||
m_buttons = Qt::NoButton;
|
|
||||||
m_acceptedMouseDowns = Qt::NoButton;
|
|
||||||
m_frameStrutButtons = Qt::NoButton;
|
|
||||||
m_sendKeyEvent = false;
|
m_sendKeyEvent = false;
|
||||||
m_sendUpAsRightButton = false;
|
|
||||||
m_inputSource = nil;
|
m_inputSource = nil;
|
||||||
m_mouseMoveHelper = [[QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) alloc] initWithView:self];
|
|
||||||
m_resendKeyEvent = false;
|
m_resendKeyEvent = false;
|
||||||
m_scrolling = false;
|
|
||||||
m_updatingDrag = false;
|
m_updatingDrag = false;
|
||||||
m_currentlyInterpretedKeyEvent = nil;
|
m_currentlyInterpretedKeyEvent = nil;
|
||||||
m_dontOverrideCtrlLMB = qt_mac_resolveOption(false, platformWindow->window(),
|
|
||||||
"_q_platform_MacDontOverrideCtrlLMB", "QT_MAC_DONT_OVERRIDE_CTRL_LMB");
|
|
||||||
|
|
||||||
self.focusRingType = NSFocusRingTypeNone;
|
self.focusRingType = NSFocusRingTypeNone;
|
||||||
self.cursor = nil;
|
|
||||||
|
|
||||||
self.previousSuperview = nil;
|
self.previousSuperview = nil;
|
||||||
self.previousWindow = nil;
|
self.previousWindow = nil;
|
||||||
|
@ -57,9 +57,9 @@
|
|||||||
NSFilesPromisePboardType, NSInkTextPboardType,
|
NSFilesPromisePboardType, NSInkTextPboardType,
|
||||||
NSMultipleTextSelectionPboardType, mimeTypeGeneric]];
|
NSMultipleTextSelectionPboardType, mimeTypeGeneric]];
|
||||||
|
|
||||||
// Add custom types supported by the application.
|
// Add custom types supported by the application
|
||||||
for (const QString &customType : qt_mac_enabledDraggedTypes())
|
for (const QString &customType : qt_mac_enabledDraggedTypes())
|
||||||
[supportedTypes addObject:customType.toNSString()];
|
[supportedTypes addObject:customType.toNSString()];
|
||||||
|
|
||||||
[self registerForDraggedTypes:supportedTypes];
|
[self registerForDraggedTypes:supportedTypes];
|
||||||
}
|
}
|
||||||
@ -79,11 +79,11 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
|
|||||||
return target->mapFromGlobal(source->mapToGlobal(point));
|
return target->mapFromGlobal(source->mapToGlobal(point));
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDragOperation)draggingSession:(NSDraggingSession *)session
|
- (NSDragOperation)draggingSession:(NSDraggingSession *)session sourceOperationMaskForDraggingContext:(NSDraggingContext)context
|
||||||
sourceOperationMaskForDraggingContext:(NSDraggingContext)context
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(session);
|
Q_UNUSED(session);
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
|
|
||||||
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
|
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
|
||||||
return qt_mac_mapDropActions(nativeDrag->currentDrag()->supportedActions());
|
return qt_mac_mapDropActions(nativeDrag->currentDrag()->supportedActions());
|
||||||
}
|
}
|
||||||
@ -134,30 +134,29 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
|
|||||||
|
|
||||||
if (pixmapCursor.isNull()) {
|
if (pixmapCursor.isNull()) {
|
||||||
switch (response.acceptedAction()) {
|
switch (response.acceptedAction()) {
|
||||||
case Qt::CopyAction:
|
case Qt::CopyAction:
|
||||||
nativeCursor = [NSCursor dragCopyCursor];
|
nativeCursor = [NSCursor dragCopyCursor];
|
||||||
break;
|
break;
|
||||||
case Qt::LinkAction:
|
case Qt::LinkAction:
|
||||||
nativeCursor = [NSCursor dragLinkCursor];
|
nativeCursor = [NSCursor dragLinkCursor];
|
||||||
break;
|
break;
|
||||||
case Qt::IgnoreAction:
|
case Qt::IgnoreAction:
|
||||||
// Uncomment the next lines if forbiden cursor wanted on non droppable targets.
|
// Uncomment the next lines if forbidden cursor is wanted on undroppable targets.
|
||||||
/*nativeCursor = [NSCursor operationNotAllowedCursor];
|
/*nativeCursor = [NSCursor operationNotAllowedCursor];
|
||||||
break;*/
|
break;*/
|
||||||
case Qt::MoveAction:
|
case Qt::MoveAction:
|
||||||
default:
|
default:
|
||||||
nativeCursor = [NSCursor arrowCursor];
|
nativeCursor = [NSCursor arrowCursor];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
NSImage *nsimage = qt_mac_create_nsimage(pixmapCursor);
|
NSImage *nsimage = qt_mac_create_nsimage(pixmapCursor);
|
||||||
nsimage.size = NSSizeFromCGSize((pixmapCursor.size() / pixmapCursor.devicePixelRatioF()).toCGSize());
|
nsimage.size = NSSizeFromCGSize((pixmapCursor.size() / pixmapCursor.devicePixelRatioF()).toCGSize());
|
||||||
nativeCursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSZeroPoint];
|
nativeCursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSZeroPoint];
|
||||||
[nsimage release];
|
[nsimage release];
|
||||||
}
|
}
|
||||||
|
|
||||||
// change the cursor
|
// Change the cursor
|
||||||
[nativeCursor set];
|
[nativeCursor set];
|
||||||
|
|
||||||
// Make sure the cursor is updated correctly if the mouse does not move and window is under cursor
|
// Make sure the cursor is updated correctly if the mouse does not move and window is under cursor
|
||||||
@ -169,39 +168,33 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
|
|||||||
if (m_updatingDrag)
|
if (m_updatingDrag)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const QPoint mousePos(QCursor::pos());
|
QCFType<CGEventRef> moveEvent = CGEventCreateMouseEvent(
|
||||||
CGEventRef moveEvent(CGEventCreateMouseEvent(
|
nullptr, kCGEventMouseMoved, QCursor::pos().toCGPoint(),
|
||||||
NULL, kCGEventMouseMoved,
|
|
||||||
CGPointMake(mousePos.x(), mousePos.y()),
|
|
||||||
kCGMouseButtonLeft // ignored
|
kCGMouseButtonLeft // ignored
|
||||||
));
|
);
|
||||||
CGEventPost(kCGHIDEventTap, moveEvent);
|
CGEventPost(kCGHIDEventTap, moveEvent);
|
||||||
CFRelease(moveEvent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender
|
||||||
{
|
{
|
||||||
return [self handleDrag : sender];
|
return [self handleDrag:(QEvent::DragEnter) sender:sender];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
|
- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender
|
||||||
{
|
{
|
||||||
m_updatingDrag = true;
|
QScopedValueRollback<bool> rollback(m_updatingDrag, true);
|
||||||
const NSDragOperation ret([self handleDrag : sender]);
|
return [self handleDrag:(QEvent::DragMove) sender:sender];
|
||||||
m_updatingDrag = false;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends drag update to Qt, return the action
|
// Sends drag update to Qt, return the action
|
||||||
- (NSDragOperation)handleDrag:(id <NSDraggingInfo>)sender
|
- (NSDragOperation)handleDrag:(QEvent::Type)dragType sender:(id<NSDraggingInfo>)sender
|
||||||
{
|
{
|
||||||
if (!m_platformWindow)
|
if (!m_platformWindow)
|
||||||
return NSDragOperationNone;
|
return NSDragOperationNone;
|
||||||
|
|
||||||
NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
|
QPoint windowPoint = QPointF::fromCGPoint([self convertPoint:sender.draggingLocation fromView:nil]).toPoint();
|
||||||
QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
|
|
||||||
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]);
|
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations(sender.draggingSourceOperationMask);
|
||||||
|
|
||||||
QWindow *target = findEventTargetWindow(m_platformWindow->window());
|
QWindow *target = findEventTargetWindow(m_platformWindow->window());
|
||||||
if (!target)
|
if (!target)
|
||||||
@ -209,7 +202,12 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
|
|||||||
|
|
||||||
const auto modifiers = [QNSView convertKeyModifiers:NSApp.currentEvent.modifierFlags];
|
const auto modifiers = [QNSView convertKeyModifiers:NSApp.currentEvent.modifierFlags];
|
||||||
const auto buttons = currentlyPressedMouseButtons();
|
const auto buttons = currentlyPressedMouseButtons();
|
||||||
const auto point = mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint);
|
const auto point = mapWindowCoordinates(m_platformWindow->window(), target, windowPoint);
|
||||||
|
|
||||||
|
if (dragType == QEvent::DragEnter)
|
||||||
|
qCDebug(lcQpaMouse) << dragType << self << "at" << windowPoint;
|
||||||
|
else
|
||||||
|
qCDebug(lcQpaMouse) << dragType << "at" << windowPoint << "with" << buttons;
|
||||||
|
|
||||||
QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect());
|
QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect());
|
||||||
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
|
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
|
||||||
@ -219,7 +217,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
|
|||||||
point, qtAllowed, buttons, modifiers);
|
point, qtAllowed, buttons, modifiers);
|
||||||
[self updateCursorFromDragResponse:response drag:nativeDrag];
|
[self updateCursorFromDragResponse:response drag:nativeDrag];
|
||||||
} else {
|
} else {
|
||||||
QCocoaDropData mimeData([sender draggingPasteboard]);
|
QCocoaDropData mimeData(sender.draggingPasteboard);
|
||||||
response = QWindowSystemInterface::handleDrag(target, &mimeData,
|
response = QWindowSystemInterface::handleDrag(target, &mimeData,
|
||||||
point, qtAllowed, buttons, modifiers);
|
point, qtAllowed, buttons, modifiers);
|
||||||
}
|
}
|
||||||
@ -227,7 +225,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
|
|||||||
return qt_mac_mapDropAction(response.acceptedAction());
|
return qt_mac_mapDropAction(response.acceptedAction());
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)draggingExited:(id <NSDraggingInfo>)sender
|
- (void)draggingExited:(id<NSDraggingInfo>)sender
|
||||||
{
|
{
|
||||||
if (!m_platformWindow)
|
if (!m_platformWindow)
|
||||||
return;
|
return;
|
||||||
@ -236,17 +234,18 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
|
|||||||
if (!target)
|
if (!target)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
|
QPoint windowPoint = QPointF::fromCGPoint([self convertPoint:sender.draggingLocation fromView:nil]).toPoint();
|
||||||
QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
|
|
||||||
|
qCDebug(lcQpaMouse) << QEvent::DragLeave << self << "at" << windowPoint;
|
||||||
|
|
||||||
// Send 0 mime data to indicate drag exit
|
// Send 0 mime data to indicate drag exit
|
||||||
QWindowSystemInterface::handleDrag(target, nullptr,
|
QWindowSystemInterface::handleDrag(target, nullptr,
|
||||||
mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint),
|
mapWindowCoordinates(m_platformWindow->window(), target, windowPoint),
|
||||||
Qt::IgnoreAction, Qt::NoButton, Qt::NoModifier);
|
Qt::IgnoreAction, Qt::NoButton, Qt::NoModifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
// called on drop, send the drop to Qt and return if it was accepted.
|
// Called on drop, send the drop to Qt and return if it was accepted
|
||||||
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
|
||||||
{
|
{
|
||||||
if (!m_platformWindow)
|
if (!m_platformWindow)
|
||||||
return false;
|
return false;
|
||||||
@ -255,31 +254,31 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
|
|||||||
if (!target)
|
if (!target)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
|
QPoint windowPoint = QPointF::fromCGPoint([self convertPoint:sender.draggingLocation fromView:nil]).toPoint();
|
||||||
QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
|
|
||||||
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]);
|
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations(sender.draggingSourceOperationMask);
|
||||||
|
|
||||||
QPlatformDropQtResponse response(false, Qt::IgnoreAction);
|
QPlatformDropQtResponse response(false, Qt::IgnoreAction);
|
||||||
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
|
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
|
||||||
const auto modifiers = [QNSView convertKeyModifiers:NSApp.currentEvent.modifierFlags];
|
const auto modifiers = [QNSView convertKeyModifiers:NSApp.currentEvent.modifierFlags];
|
||||||
const auto buttons = currentlyPressedMouseButtons();
|
const auto buttons = currentlyPressedMouseButtons();
|
||||||
const auto point = mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint);
|
const auto point = mapWindowCoordinates(m_platformWindow->window(), target, windowPoint);
|
||||||
|
|
||||||
|
qCDebug(lcQpaMouse) << QEvent::Drop << "at" << windowPoint << "with" << buttons;
|
||||||
|
|
||||||
if (nativeDrag->currentDrag()) {
|
if (nativeDrag->currentDrag()) {
|
||||||
// The drag was started from within the application
|
// The drag was started from within the application
|
||||||
response = QWindowSystemInterface::handleDrop(target, nativeDrag->dragMimeData(),
|
response = QWindowSystemInterface::handleDrop(target, nativeDrag->dragMimeData(),
|
||||||
point, qtAllowed, buttons, modifiers);
|
point, qtAllowed, buttons, modifiers);
|
||||||
} else {
|
} else {
|
||||||
QCocoaDropData mimeData([sender draggingPasteboard]);
|
QCocoaDropData mimeData(sender.draggingPasteboard);
|
||||||
response = QWindowSystemInterface::handleDrop(target, &mimeData,
|
response = QWindowSystemInterface::handleDrop(target, &mimeData,
|
||||||
point, qtAllowed, buttons, modifiers);
|
point, qtAllowed, buttons, modifiers);
|
||||||
}
|
}
|
||||||
return response.isAccepted();
|
return response.isAccepted();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)draggingSession:(NSDraggingSession *)session
|
- (void)draggingSession:(NSDraggingSession *)session endedAtPoint:(NSPoint)screenPoint operation:(NSDragOperation)operation
|
||||||
endedAtPoint:(NSPoint)screenPoint
|
|
||||||
operation:(NSDragOperation)operation
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(session);
|
Q_UNUSED(session);
|
||||||
Q_UNUSED(screenPoint);
|
Q_UNUSED(screenPoint);
|
||||||
@ -295,6 +294,8 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
|
|||||||
nativeDrag->setAcceptedAction(qt_mac_mapNSDragOperation(operation));
|
nativeDrag->setAcceptedAction(qt_mac_mapNSDragOperation(operation));
|
||||||
|
|
||||||
m_buttons = currentlyPressedMouseButtons();
|
m_buttons = currentlyPressedMouseButtons();
|
||||||
|
|
||||||
|
qCDebug(lcQpaMouse) << "Drag session" << session << "ended, with" << m_buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -93,6 +93,7 @@
|
|||||||
|
|
||||||
- (void)resetMouseButtons
|
- (void)resetMouseButtons
|
||||||
{
|
{
|
||||||
|
qCDebug(lcQpaMouse) << "Reseting mouse buttons";
|
||||||
m_buttons = Qt::NoButton;
|
m_buttons = Qt::NoButton;
|
||||||
m_frameStrutButtons = Qt::NoButton;
|
m_frameStrutButtons = Qt::NoButton;
|
||||||
}
|
}
|
||||||
@ -145,6 +146,9 @@
|
|||||||
QPoint qtScreenPoint = QCocoaScreen::mapFromNative(screenPoint).toPoint();
|
QPoint qtScreenPoint = QCocoaScreen::mapFromNative(screenPoint).toPoint();
|
||||||
|
|
||||||
ulong timestamp = [theEvent timestamp] * 1000;
|
ulong timestamp = [theEvent timestamp] * 1000;
|
||||||
|
|
||||||
|
auto eventType = cocoaEvent2QtMouseEvent(theEvent);
|
||||||
|
qCInfo(lcQpaMouse) << "Frame-strut" << eventType << "at" << qtWindowPoint << "with" << m_frameStrutButtons << "in" << self.window;
|
||||||
QWindowSystemInterface::handleFrameStrutMouseEvent(m_platformWindow->window(), timestamp, qtWindowPoint, qtScreenPoint, m_frameStrutButtons);
|
QWindowSystemInterface::handleFrameStrutMouseEvent(m_platformWindow->window(), timestamp, qtWindowPoint, qtScreenPoint, m_frameStrutButtons);
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
@ -153,6 +157,19 @@
|
|||||||
|
|
||||||
- (void)initMouse
|
- (void)initMouse
|
||||||
{
|
{
|
||||||
|
m_buttons = Qt::NoButton;
|
||||||
|
m_acceptedMouseDowns = Qt::NoButton;
|
||||||
|
m_frameStrutButtons = Qt::NoButton;
|
||||||
|
|
||||||
|
m_scrolling = false;
|
||||||
|
self.cursor = nil;
|
||||||
|
|
||||||
|
m_sendUpAsRightButton = false;
|
||||||
|
m_dontOverrideCtrlLMB = qt_mac_resolveOption(false, m_platformWindow->window(),
|
||||||
|
"_q_platform_MacDontOverrideCtrlLMB", "QT_MAC_DONT_OVERRIDE_CTRL_LMB");
|
||||||
|
|
||||||
|
m_mouseMoveHelper = [[QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) alloc] initWithView:self];
|
||||||
|
|
||||||
NSUInteger trackingOptions = NSTrackingActiveInActiveApp
|
NSUInteger trackingOptions = NSTrackingActiveInActiveApp
|
||||||
| NSTrackingMouseEnteredAndExited | NSTrackingCursorUpdate;
|
| NSTrackingMouseEnteredAndExited | NSTrackingCursorUpdate;
|
||||||
|
|
||||||
@ -241,6 +258,11 @@
|
|||||||
button = Qt::RightButton;
|
button = Qt::RightButton;
|
||||||
const auto eventType = cocoaEvent2QtMouseEvent(theEvent);
|
const auto eventType = cocoaEvent2QtMouseEvent(theEvent);
|
||||||
|
|
||||||
|
if (eventType == QEvent::MouseMove)
|
||||||
|
qCDebug(lcQpaMouse) << eventType << "at" << qtWindowPoint << "with" << buttons;
|
||||||
|
else
|
||||||
|
qCInfo(lcQpaMouse) << eventType << "of" << button << "at" << qtWindowPoint << "with" << buttons;
|
||||||
|
|
||||||
QWindowSystemInterface::handleMouseEvent(targetView->m_platformWindow->window(),
|
QWindowSystemInterface::handleMouseEvent(targetView->m_platformWindow->window(),
|
||||||
timestamp, qtWindowPoint, qtScreenPoint,
|
timestamp, qtWindowPoint, qtScreenPoint,
|
||||||
buttons, button, eventType, modifiers);
|
buttons, button, eventType, modifiers);
|
||||||
@ -446,16 +468,16 @@
|
|||||||
|
|
||||||
- (void)cursorUpdate:(NSEvent *)theEvent
|
- (void)cursorUpdate:(NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
qCDebug(lcQpaMouse) << "Updating cursor for" << self << "to" << self.cursor;
|
|
||||||
|
|
||||||
// Note: We do not get this callback when moving from a subview that
|
// Note: We do not get this callback when moving from a subview that
|
||||||
// uses the legacy cursorRect API, so the cursor is reset to the arrow
|
// uses the legacy cursorRect API, so the cursor is reset to the arrow
|
||||||
// cursor. See rdar://34183708
|
// cursor. See rdar://34183708
|
||||||
|
|
||||||
if (self.cursor)
|
if (self.cursor && self.cursor != NSCursor.currentCursor) {
|
||||||
|
qCInfo(lcQpaMouse) << "Updating cursor for" << self << "to" << self.cursor;
|
||||||
[self.cursor set];
|
[self.cursor set];
|
||||||
else
|
} else {
|
||||||
[super cursorUpdate:theEvent];
|
[super cursorUpdate:theEvent];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseMovedImpl:(NSEvent *)theEvent
|
- (void)mouseMovedImpl:(NSEvent *)theEvent
|
||||||
@ -510,6 +532,8 @@
|
|||||||
QPointF screenPoint;
|
QPointF screenPoint;
|
||||||
[self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
|
[self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
|
||||||
m_platformWindow->m_enterLeaveTargetWindow = m_platformWindow->childWindowAt(windowPoint.toPoint());
|
m_platformWindow->m_enterLeaveTargetWindow = m_platformWindow->childWindowAt(windowPoint.toPoint());
|
||||||
|
|
||||||
|
qCInfo(lcQpaMouse) << QEvent::Enter << self << "at" << windowPoint << "with" << currentlyPressedMouseButtons();
|
||||||
QWindowSystemInterface::handleEnterEvent(m_platformWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
|
QWindowSystemInterface::handleEnterEvent(m_platformWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,6 +552,7 @@
|
|||||||
if (!m_platformWindow->isContentView())
|
if (!m_platformWindow->isContentView())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
qCInfo(lcQpaMouse) << QEvent::Leave << self;
|
||||||
QWindowSystemInterface::handleLeaveEvent(m_platformWindow->m_enterLeaveTargetWindow);
|
QWindowSystemInterface::handleLeaveEvent(m_platformWindow->m_enterLeaveTargetWindow);
|
||||||
m_platformWindow->m_enterLeaveTargetWindow = 0;
|
m_platformWindow->m_enterLeaveTargetWindow = 0;
|
||||||
}
|
}
|
||||||
@ -626,8 +651,10 @@
|
|||||||
// "isInverted": natural OS X scrolling, inverted from the Qt/other platform/Jens perspective.
|
// "isInverted": natural OS X scrolling, inverted from the Qt/other platform/Jens perspective.
|
||||||
bool isInverted = [theEvent isDirectionInvertedFromDevice];
|
bool isInverted = [theEvent isDirectionInvertedFromDevice];
|
||||||
|
|
||||||
qCDebug(lcQpaMouse) << "scroll wheel @ window pos" << qt_windowPoint << "delta px" << pixelDelta
|
qCInfo(lcQpaMouse).nospace() << phase << " at " << qt_windowPoint
|
||||||
<< "angle" << angleDelta << "phase" << phase << (isInverted ? "inverted" : "");
|
<< " pixelDelta=" << pixelDelta << " angleDelta=" << angleDelta
|
||||||
|
<< (isInverted ? " inverted=true" : "");
|
||||||
|
|
||||||
QWindowSystemInterface::handleWheelEvent(m_platformWindow->window(), qt_timestamp, qt_windowPoint,
|
QWindowSystemInterface::handleWheelEvent(m_platformWindow->window(), qt_timestamp, qt_windowPoint,
|
||||||
qt_screenPoint, pixelDelta, angleDelta, m_currentWheelModifiers, phase, source, isInverted);
|
qt_screenPoint, pixelDelta, angleDelta, m_currentWheelModifiers, phase, source, isInverted);
|
||||||
}
|
}
|
||||||
|
@ -55,9 +55,8 @@ bool QAppleTestLogger::debugLoggingEnabled()
|
|||||||
return os_log_type_enabled(OS_LOG_DEFAULT, OS_LOG_TYPE_DEBUG);
|
return os_log_type_enabled(OS_LOG_DEFAULT, OS_LOG_TYPE_DEBUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
QAppleTestLogger::QAppleTestLogger(QAbstractTestLogger *logger)
|
QAppleTestLogger::QAppleTestLogger()
|
||||||
: QAbstractTestLogger(nullptr)
|
: QAbstractTestLogger(nullptr)
|
||||||
, m_logger(logger)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +64,8 @@ static QAppleLogActivity testFunctionActivity;
|
|||||||
|
|
||||||
void QAppleTestLogger::enterTestFunction(const char *function)
|
void QAppleTestLogger::enterTestFunction(const char *function)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(function);
|
||||||
|
|
||||||
// Re-create activity each time
|
// Re-create activity each time
|
||||||
testFunctionActivity = QT_APPLE_LOG_ACTIVITY("Running test function").enter();
|
testFunctionActivity = QT_APPLE_LOG_ACTIVITY("Running test function").enter();
|
||||||
|
|
||||||
@ -73,15 +74,12 @@ void QAppleTestLogger::enterTestFunction(const char *function)
|
|||||||
QString identifier = QString::fromLatin1(testIdentifier.data());
|
QString identifier = QString::fromLatin1(testIdentifier.data());
|
||||||
QMessageLogContext context(nullptr, 0, nullptr, "qt.test.enter");
|
QMessageLogContext context(nullptr, 0, nullptr, "qt.test.enter");
|
||||||
QString message = identifier;
|
QString message = identifier;
|
||||||
if (AppleUnifiedLogger::messageHandler(QtDebugMsg, context, message, identifier))
|
|
||||||
return; // AUL already printed to stderr
|
|
||||||
|
|
||||||
m_logger->enterTestFunction(function);
|
AppleUnifiedLogger::messageHandler(QtDebugMsg, context, message, identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QAppleTestLogger::leaveTestFunction()
|
void QAppleTestLogger::leaveTestFunction()
|
||||||
{
|
{
|
||||||
m_logger->leaveTestFunction();
|
|
||||||
testFunctionActivity.leave();
|
testFunctionActivity.leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,18 +132,12 @@ void QAppleTestLogger::addIncident(IncidentTypes type, const char *description,
|
|||||||
if (qstrlen(description))
|
if (qstrlen(description))
|
||||||
message += QLatin1Char('\n') % QString::fromLatin1(description);
|
message += QLatin1Char('\n') % QString::fromLatin1(description);
|
||||||
|
|
||||||
if (AppleUnifiedLogger::messageHandler(incidentClassification.first, context, message, subsystem))
|
AppleUnifiedLogger::messageHandler(incidentClassification.first, context, message, subsystem);
|
||||||
return; // AUL already printed to stderr
|
|
||||||
|
|
||||||
m_logger->addIncident(type, description, file, line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QAppleTestLogger::addMessage(QtMsgType type, const QMessageLogContext &context, const QString &message)
|
void QAppleTestLogger::addMessage(QtMsgType type, const QMessageLogContext &context, const QString &message)
|
||||||
{
|
{
|
||||||
if (AppleUnifiedLogger::messageHandler(type, context, message))
|
AppleUnifiedLogger::messageHandler(type, context, message);
|
||||||
return; // AUL already printed to stderr
|
|
||||||
|
|
||||||
m_logger->addMessage(type, context, message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // QT_USE_APPLE_UNIFIED_LOGGING
|
#endif // QT_USE_APPLE_UNIFIED_LOGGING
|
||||||
|
@ -63,12 +63,7 @@ class QAppleTestLogger : public QAbstractTestLogger
|
|||||||
public:
|
public:
|
||||||
static bool debugLoggingEnabled();
|
static bool debugLoggingEnabled();
|
||||||
|
|
||||||
QAppleTestLogger(QAbstractTestLogger *logger);
|
QAppleTestLogger();
|
||||||
|
|
||||||
void startLogging() override
|
|
||||||
{ m_logger->startLogging(); }
|
|
||||||
void stopLogging() override
|
|
||||||
{ m_logger->stopLogging(); }
|
|
||||||
|
|
||||||
void enterTestFunction(const char *function) override;
|
void enterTestFunction(const char *function) override;
|
||||||
void leaveTestFunction() override;
|
void leaveTestFunction() override;
|
||||||
@ -77,16 +72,12 @@ public:
|
|||||||
const char *file = 0, int line = 0) override;
|
const char *file = 0, int line = 0) override;
|
||||||
void addMessage(QtMsgType, const QMessageLogContext &,
|
void addMessage(QtMsgType, const QMessageLogContext &,
|
||||||
const QString &) override;
|
const QString &) override;
|
||||||
|
|
||||||
void addBenchmarkResult(const QBenchmarkResult &result) override
|
|
||||||
{ m_logger->addBenchmarkResult(result); }
|
|
||||||
|
|
||||||
void addMessage(MessageTypes type, const QString &message,
|
void addMessage(MessageTypes type, const QString &message,
|
||||||
const char *file = 0, int line = 0) override
|
const char *file = 0, int line = 0) override
|
||||||
{ m_logger->addMessage(type, message, file, line); }
|
{ Q_UNUSED(type); Q_UNUSED(message); Q_UNUSED(file); Q_UNUSED(line); Q_UNREACHABLE(); }
|
||||||
|
|
||||||
private:
|
void addBenchmarkResult(const QBenchmarkResult &result) override
|
||||||
QScopedPointer<QAbstractTestLogger> m_logger;
|
{ Q_UNUSED(result); }
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -78,6 +78,10 @@
|
|||||||
#include <QtTest/private/qtestutil_macos_p.h>
|
#include <QtTest/private/qtestutil_macos_p.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(Q_OS_DARWIN)
|
||||||
|
#include <QtTest/private/qappletestlogger_p.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -511,7 +515,7 @@ static int qToInt(const char *str)
|
|||||||
|
|
||||||
Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, const char *const argv[], bool qml)
|
Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, const char *const argv[], bool qml)
|
||||||
{
|
{
|
||||||
QTestLog::LogMode logFormat = QTestLog::Plain;
|
int logFormat = -1; // Not set
|
||||||
const char *logFilename = 0;
|
const char *logFilename = 0;
|
||||||
|
|
||||||
QTest::testFunctions.clear();
|
QTest::testFunctions.clear();
|
||||||
@ -679,7 +683,7 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, const char *const argv[], bool
|
|||||||
fprintf(stderr, "only one logger can log to stdout\n");
|
fprintf(stderr, "only one logger can log to stdout\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
QTestLog::addLogger(logFormat, filename);
|
QTestLog::addLogger(QTestLog::LogMode(logFormat), filename);
|
||||||
}
|
}
|
||||||
delete [] filename;
|
delete [] filename;
|
||||||
delete [] format;
|
delete [] format;
|
||||||
@ -841,10 +845,25 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, const char *const argv[], bool
|
|||||||
QTestLog::setInstalledTestCoverage(installedTestCoverage);
|
QTestLog::setInstalledTestCoverage(installedTestCoverage);
|
||||||
|
|
||||||
// If no loggers were created by the long version of the -o command-line
|
// If no loggers were created by the long version of the -o command-line
|
||||||
// option, create a logger using whatever filename and format were
|
// option, but a logger was requested via the old-style option, add it.
|
||||||
// set using the old-style command-line options.
|
const bool explicitLoggerRequested = logFormat != -1;
|
||||||
if (QTestLog::loggerCount() == 0)
|
if (QTestLog::loggerCount() == 0 && explicitLoggerRequested)
|
||||||
QTestLog::addLogger(logFormat, logFilename);
|
QTestLog::addLogger(QTestLog::LogMode(logFormat), logFilename);
|
||||||
|
|
||||||
|
bool addFallbackLogger = !explicitLoggerRequested;
|
||||||
|
|
||||||
|
#if defined(QT_USE_APPLE_UNIFIED_LOGGING)
|
||||||
|
// Any explicitly requested loggers will be added by now, so we can check if they use stdout
|
||||||
|
const bool safeToAddAppleLogger = !AppleUnifiedLogger::willMirrorToStderr() || !QTestLog::loggerUsingStdout();
|
||||||
|
if (safeToAddAppleLogger && QAppleTestLogger::debugLoggingEnabled()) {
|
||||||
|
QTestLog::addLogger(QTestLog::Apple, nullptr);
|
||||||
|
if (AppleUnifiedLogger::willMirrorToStderr() && !logFilename)
|
||||||
|
addFallbackLogger = false; // Prevent plain test logger fallback below
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (addFallbackLogger)
|
||||||
|
QTestLog::addLogger(QTestLog::Plain, logFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporary, backwards compatibility, until qtdeclarative's use of it is converted
|
// Temporary, backwards compatibility, until qtdeclarative's use of it is converted
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
#include <QtCore/qbytearray.h>
|
#include <QtCore/qbytearray.h>
|
||||||
#include <QtCore/QElapsedTimer>
|
#include <QtCore/QElapsedTimer>
|
||||||
#include <QtCore/QVariant>
|
#include <QtCore/QVariant>
|
||||||
|
#include <QtCore/qvector.h>
|
||||||
#if QT_CONFIG(regularexpression)
|
#if QT_CONFIG(regularexpression)
|
||||||
#include <QtCore/QRegularExpression>
|
#include <QtCore/QRegularExpression>
|
||||||
#endif
|
#endif
|
||||||
@ -98,6 +99,8 @@ static void saveCoverageTool(const char * appname, bool testfailed, bool install
|
|||||||
static QElapsedTimer elapsedFunctionTime;
|
static QElapsedTimer elapsedFunctionTime;
|
||||||
static QElapsedTimer elapsedTotalTime;
|
static QElapsedTimer elapsedTotalTime;
|
||||||
|
|
||||||
|
#define FOREACH_TEST_LOGGER for (QAbstractTestLogger *logger : QTest::loggers)
|
||||||
|
|
||||||
namespace QTest {
|
namespace QTest {
|
||||||
|
|
||||||
int fails = 0;
|
int fails = 0;
|
||||||
@ -165,109 +168,7 @@ namespace QTest {
|
|||||||
|
|
||||||
static IgnoreResultList *ignoreResultList = 0;
|
static IgnoreResultList *ignoreResultList = 0;
|
||||||
|
|
||||||
struct LoggerList
|
static QVector<QAbstractTestLogger*> loggers;
|
||||||
{
|
|
||||||
QAbstractTestLogger *logger;
|
|
||||||
LoggerList *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TestLoggers
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static void addLogger(QAbstractTestLogger *logger)
|
|
||||||
{
|
|
||||||
LoggerList *l = new LoggerList;
|
|
||||||
l->logger = logger;
|
|
||||||
l->next = loggers;
|
|
||||||
loggers = l;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void destroyLoggers()
|
|
||||||
{
|
|
||||||
while (loggers) {
|
|
||||||
LoggerList *l = loggers;
|
|
||||||
loggers = loggers->next;
|
|
||||||
delete l->logger;
|
|
||||||
delete l;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FOREACH_LOGGER(operation) \
|
|
||||||
LoggerList *l = loggers; \
|
|
||||||
while (l) { \
|
|
||||||
QAbstractTestLogger *logger = l->logger; \
|
|
||||||
Q_UNUSED(logger); \
|
|
||||||
operation; \
|
|
||||||
l = l->next; \
|
|
||||||
}
|
|
||||||
|
|
||||||
static void startLogging()
|
|
||||||
{
|
|
||||||
FOREACH_LOGGER(logger->startLogging());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void stopLogging()
|
|
||||||
{
|
|
||||||
FOREACH_LOGGER(logger->stopLogging());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void enterTestFunction(const char *function)
|
|
||||||
{
|
|
||||||
FOREACH_LOGGER(logger->enterTestFunction(function));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void leaveTestFunction()
|
|
||||||
{
|
|
||||||
FOREACH_LOGGER(logger->leaveTestFunction());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void enterTestData(QTestData *data)
|
|
||||||
{
|
|
||||||
FOREACH_LOGGER(logger->enterTestData(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addIncident(QAbstractTestLogger::IncidentTypes type, const char *description,
|
|
||||||
const char *file = 0, int line = 0)
|
|
||||||
{
|
|
||||||
FOREACH_LOGGER(logger->addIncident(type, description, file, line));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addBenchmarkResult(const QBenchmarkResult &result)
|
|
||||||
{
|
|
||||||
FOREACH_LOGGER(logger->addBenchmarkResult(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addMessage(QtMsgType type, const QMessageLogContext &context,
|
|
||||||
const QString &message)
|
|
||||||
{
|
|
||||||
FOREACH_LOGGER(logger->addMessage(type, context, message));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addMessage(QAbstractTestLogger::MessageTypes type, const QString &message,
|
|
||||||
const char *file = 0, int line = 0)
|
|
||||||
{
|
|
||||||
FOREACH_LOGGER(logger->addMessage(type, message, file, line));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void outputString(const char *msg)
|
|
||||||
{
|
|
||||||
FOREACH_LOGGER(logger->outputString(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int loggerCount()
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
FOREACH_LOGGER(++count);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static LoggerList *loggers;
|
|
||||||
};
|
|
||||||
|
|
||||||
#undef FOREACH_LOGGER
|
|
||||||
|
|
||||||
LoggerList *TestLoggers::loggers = 0;
|
|
||||||
static bool loggerUsingStdout = false;
|
static bool loggerUsingStdout = false;
|
||||||
|
|
||||||
static int verbosity = 0;
|
static int verbosity = 0;
|
||||||
@ -306,10 +207,10 @@ namespace QTest {
|
|||||||
{
|
{
|
||||||
static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(QTest::maxWarnings);
|
static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(QTest::maxWarnings);
|
||||||
|
|
||||||
if (QTest::TestLoggers::loggerCount() == 0) {
|
if (QTestLog::loggerCount() == 0) {
|
||||||
// if this goes wrong, something is seriously broken.
|
// if this goes wrong, something is seriously broken.
|
||||||
qInstallMessageHandler(oldMessageHandler);
|
qInstallMessageHandler(oldMessageHandler);
|
||||||
QTEST_ASSERT(QTest::TestLoggers::loggerCount() != 0);
|
QTEST_ASSERT(QTestLog::loggerCount() != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handleIgnoredMessage(type, message)) {
|
if (handleIgnoredMessage(type, message)) {
|
||||||
@ -322,13 +223,16 @@ namespace QTest {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!counter.deref()) {
|
if (!counter.deref()) {
|
||||||
QTest::TestLoggers::addMessage(QAbstractTestLogger::QSystem,
|
FOREACH_TEST_LOGGER {
|
||||||
|
logger->addMessage(QAbstractTestLogger::QSystem,
|
||||||
QStringLiteral("Maximum amount of warnings exceeded. Use -maxwarnings to override."));
|
QStringLiteral("Maximum amount of warnings exceeded. Use -maxwarnings to override."));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QTest::TestLoggers::addMessage(type, context, message);
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->addMessage(type, context, message);
|
||||||
|
|
||||||
if (type == QtFatalMsg) {
|
if (type == QtFatalMsg) {
|
||||||
/* Right now, we're inside the custom message handler and we're
|
/* Right now, we're inside the custom message handler and we're
|
||||||
@ -351,13 +255,16 @@ void QTestLog::enterTestFunction(const char* function)
|
|||||||
|
|
||||||
QTEST_ASSERT(function);
|
QTEST_ASSERT(function);
|
||||||
|
|
||||||
QTest::TestLoggers::enterTestFunction(function);
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->enterTestFunction(function);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTestLog::enterTestData(QTestData *data)
|
void QTestLog::enterTestData(QTestData *data)
|
||||||
{
|
{
|
||||||
QTEST_ASSERT(data);
|
QTEST_ASSERT(data);
|
||||||
QTest::TestLoggers::enterTestData(data);
|
|
||||||
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->enterTestData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
int QTestLog::unhandledIgnoreMessages()
|
int QTestLog::unhandledIgnoreMessages()
|
||||||
@ -376,7 +283,8 @@ void QTestLog::leaveTestFunction()
|
|||||||
if (printAvailableTags)
|
if (printAvailableTags)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QTest::TestLoggers::leaveTestFunction();
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->leaveTestFunction();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTestLog::printUnhandledIgnoreMessages()
|
void QTestLog::printUnhandledIgnoreMessages()
|
||||||
@ -391,7 +299,8 @@ void QTestLog::printUnhandledIgnoreMessages()
|
|||||||
message = QStringLiteral("Did not receive any message matching: \"") + list->pattern.toRegularExpression().pattern() + QLatin1Char('"');
|
message = QStringLiteral("Did not receive any message matching: \"") + list->pattern.toRegularExpression().pattern() + QLatin1Char('"');
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
QTest::TestLoggers::addMessage(QAbstractTestLogger::Info, message);
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->addMessage(QAbstractTestLogger::Info, message);
|
||||||
|
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
@ -411,7 +320,8 @@ void QTestLog::addPass(const char *msg)
|
|||||||
|
|
||||||
++QTest::passes;
|
++QTest::passes;
|
||||||
|
|
||||||
QTest::TestLoggers::addIncident(QAbstractTestLogger::Pass, msg);
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->addIncident(QAbstractTestLogger::Pass, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTestLog::addFail(const char *msg, const char *file, int line)
|
void QTestLog::addFail(const char *msg, const char *file, int line)
|
||||||
@ -420,7 +330,8 @@ void QTestLog::addFail(const char *msg, const char *file, int line)
|
|||||||
|
|
||||||
++QTest::fails;
|
++QTest::fails;
|
||||||
|
|
||||||
QTest::TestLoggers::addIncident(QAbstractTestLogger::Fail, msg, file, line);
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->addIncident(QAbstractTestLogger::Fail, msg, file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTestLog::addXFail(const char *msg, const char *file, int line)
|
void QTestLog::addXFail(const char *msg, const char *file, int line)
|
||||||
@ -428,7 +339,8 @@ void QTestLog::addXFail(const char *msg, const char *file, int line)
|
|||||||
QTEST_ASSERT(msg);
|
QTEST_ASSERT(msg);
|
||||||
QTEST_ASSERT(file);
|
QTEST_ASSERT(file);
|
||||||
|
|
||||||
QTest::TestLoggers::addIncident(QAbstractTestLogger::XFail, msg, file, line);
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->addIncident(QAbstractTestLogger::XFail, msg, file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTestLog::addXPass(const char *msg, const char *file, int line)
|
void QTestLog::addXPass(const char *msg, const char *file, int line)
|
||||||
@ -438,7 +350,8 @@ void QTestLog::addXPass(const char *msg, const char *file, int line)
|
|||||||
|
|
||||||
++QTest::fails;
|
++QTest::fails;
|
||||||
|
|
||||||
QTest::TestLoggers::addIncident(QAbstractTestLogger::XPass, msg, file, line);
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->addIncident(QAbstractTestLogger::XPass, msg, file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTestLog::addBPass(const char *msg)
|
void QTestLog::addBPass(const char *msg)
|
||||||
@ -447,7 +360,8 @@ void QTestLog::addBPass(const char *msg)
|
|||||||
|
|
||||||
++QTest::blacklists;
|
++QTest::blacklists;
|
||||||
|
|
||||||
QTest::TestLoggers::addIncident(QAbstractTestLogger::BlacklistedPass, msg);
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->addIncident(QAbstractTestLogger::BlacklistedPass, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTestLog::addBFail(const char *msg, const char *file, int line)
|
void QTestLog::addBFail(const char *msg, const char *file, int line)
|
||||||
@ -457,7 +371,8 @@ void QTestLog::addBFail(const char *msg, const char *file, int line)
|
|||||||
|
|
||||||
++QTest::blacklists;
|
++QTest::blacklists;
|
||||||
|
|
||||||
QTest::TestLoggers::addIncident(QAbstractTestLogger::BlacklistedFail, msg, file, line);
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->addIncident(QAbstractTestLogger::BlacklistedFail, msg, file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTestLog::addBXPass(const char *msg, const char *file, int line)
|
void QTestLog::addBXPass(const char *msg, const char *file, int line)
|
||||||
@ -467,7 +382,8 @@ void QTestLog::addBXPass(const char *msg, const char *file, int line)
|
|||||||
|
|
||||||
++QTest::blacklists;
|
++QTest::blacklists;
|
||||||
|
|
||||||
QTest::TestLoggers::addIncident(QAbstractTestLogger::BlacklistedXPass, msg, file, line);
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->addIncident(QAbstractTestLogger::BlacklistedXPass, msg, file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTestLog::addBXFail(const char *msg, const char *file, int line)
|
void QTestLog::addBXFail(const char *msg, const char *file, int line)
|
||||||
@ -477,7 +393,8 @@ void QTestLog::addBXFail(const char *msg, const char *file, int line)
|
|||||||
|
|
||||||
++QTest::blacklists;
|
++QTest::blacklists;
|
||||||
|
|
||||||
QTest::TestLoggers::addIncident(QAbstractTestLogger::BlacklistedXFail, msg, file, line);
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->addIncident(QAbstractTestLogger::BlacklistedXFail, msg, file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTestLog::addSkip(const char *msg, const char *file, int line)
|
void QTestLog::addSkip(const char *msg, const char *file, int line)
|
||||||
@ -487,27 +404,33 @@ void QTestLog::addSkip(const char *msg, const char *file, int line)
|
|||||||
|
|
||||||
++QTest::skips;
|
++QTest::skips;
|
||||||
|
|
||||||
QTest::TestLoggers::addMessage(QAbstractTestLogger::Skip, QString::fromUtf8(msg), file, line);
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->addMessage(QAbstractTestLogger::Skip, QString::fromUtf8(msg), file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTestLog::addBenchmarkResult(const QBenchmarkResult &result)
|
void QTestLog::addBenchmarkResult(const QBenchmarkResult &result)
|
||||||
{
|
{
|
||||||
QTest::TestLoggers::addBenchmarkResult(result);
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->addBenchmarkResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTestLog::startLogging()
|
void QTestLog::startLogging()
|
||||||
{
|
{
|
||||||
elapsedTotalTime.start();
|
elapsedTotalTime.start();
|
||||||
elapsedFunctionTime.start();
|
elapsedFunctionTime.start();
|
||||||
QTest::TestLoggers::startLogging();
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->startLogging();
|
||||||
QTest::oldMessageHandler = qInstallMessageHandler(QTest::messageHandler);
|
QTest::oldMessageHandler = qInstallMessageHandler(QTest::messageHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTestLog::stopLogging()
|
void QTestLog::stopLogging()
|
||||||
{
|
{
|
||||||
qInstallMessageHandler(QTest::oldMessageHandler);
|
qInstallMessageHandler(QTest::oldMessageHandler);
|
||||||
QTest::TestLoggers::stopLogging();
|
FOREACH_TEST_LOGGER {
|
||||||
QTest::TestLoggers::destroyLoggers();
|
logger->stopLogging();
|
||||||
|
delete logger;
|
||||||
|
}
|
||||||
|
QTest::loggers.clear();
|
||||||
QTest::loggerUsingStdout = false;
|
QTest::loggerUsingStdout = false;
|
||||||
saveCoverageTool(QTestResult::currentAppName(), failCount() != 0, QTestLog::installedTestCoverage());
|
saveCoverageTool(QTestResult::currentAppName(), failCount() != 0, QTestLog::installedTestCoverage());
|
||||||
}
|
}
|
||||||
@ -542,6 +465,11 @@ void QTestLog::addLogger(LogMode mode, const char *filename)
|
|||||||
case QTestLog::TAP:
|
case QTestLog::TAP:
|
||||||
logger = new QTapTestLogger(filename);
|
logger = new QTapTestLogger(filename);
|
||||||
break;
|
break;
|
||||||
|
#if defined(QT_USE_APPLE_UNIFIED_LOGGING)
|
||||||
|
case QTestLog::Apple:
|
||||||
|
logger = new QAppleTestLogger;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
#if defined(HAVE_XCTEST)
|
#if defined(HAVE_XCTEST)
|
||||||
case QTestLog::XCTest:
|
case QTestLog::XCTest:
|
||||||
logger = new QXcodeTestLogger;
|
logger = new QXcodeTestLogger;
|
||||||
@ -549,21 +477,13 @@ void QTestLog::addLogger(LogMode mode, const char *filename)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(QT_USE_APPLE_UNIFIED_LOGGING)
|
|
||||||
// Logger that also feeds messages to AUL. It needs to wrap the existing
|
|
||||||
// logger, as it needs to be able to short circuit the existing logger
|
|
||||||
// in case AUL prints to stderr.
|
|
||||||
if (QAppleTestLogger::debugLoggingEnabled())
|
|
||||||
logger = new QAppleTestLogger(logger);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QTEST_ASSERT(logger);
|
QTEST_ASSERT(logger);
|
||||||
QTest::TestLoggers::addLogger(logger);
|
QTest::loggers.append(logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
int QTestLog::loggerCount()
|
int QTestLog::loggerCount()
|
||||||
{
|
{
|
||||||
return QTest::TestLoggers::loggerCount();
|
return QTest::loggers.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QTestLog::loggerUsingStdout()
|
bool QTestLog::loggerUsingStdout()
|
||||||
@ -575,15 +495,16 @@ void QTestLog::warn(const char *msg, const char *file, int line)
|
|||||||
{
|
{
|
||||||
QTEST_ASSERT(msg);
|
QTEST_ASSERT(msg);
|
||||||
|
|
||||||
if (QTest::TestLoggers::loggerCount() > 0)
|
FOREACH_TEST_LOGGER
|
||||||
QTest::TestLoggers::addMessage(QAbstractTestLogger::Warn, QString::fromUtf8(msg), file, line);
|
logger->addMessage(QAbstractTestLogger::Warn, QString::fromUtf8(msg), file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTestLog::info(const char *msg, const char *file, int line)
|
void QTestLog::info(const char *msg, const char *file, int line)
|
||||||
{
|
{
|
||||||
QTEST_ASSERT(msg);
|
QTEST_ASSERT(msg);
|
||||||
|
|
||||||
QTest::TestLoggers::addMessage(QAbstractTestLogger::Info, QString::fromUtf8(msg), file, line);
|
FOREACH_TEST_LOGGER
|
||||||
|
logger->addMessage(QAbstractTestLogger::Info, QString::fromUtf8(msg), file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTestLog::setVerboseLevel(int level)
|
void QTestLog::setVerboseLevel(int level)
|
||||||
|
@ -53,6 +53,10 @@
|
|||||||
|
|
||||||
#include <QtTest/qttestglobal.h>
|
#include <QtTest/qttestglobal.h>
|
||||||
|
|
||||||
|
#if defined(Q_OS_DARWIN)
|
||||||
|
#include <QtCore/private/qcore_mac_p.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QBenchmarkResult;
|
class QBenchmarkResult;
|
||||||
@ -63,9 +67,12 @@ class Q_TESTLIB_EXPORT QTestLog
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum LogMode {
|
enum LogMode {
|
||||||
Plain = 0, XML, LightXML, XunitXML, CSV, TeamCity, TAP,
|
Plain = 0, XML, LightXML, XunitXML, CSV, TeamCity, TAP
|
||||||
|
#if defined(QT_USE_APPLE_UNIFIED_LOGGING)
|
||||||
|
, Apple
|
||||||
|
#endif
|
||||||
#if defined(HAVE_XCTEST)
|
#if defined(HAVE_XCTEST)
|
||||||
XCTest
|
, XCTest
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ SUBDIRS = lib \
|
|||||||
tst.depends += almostplugin
|
tst.depends += almostplugin
|
||||||
SUBDIRS += almostplugin
|
SUBDIRS += almostplugin
|
||||||
}
|
}
|
||||||
macos:qtConfig(private_tests) {
|
macos:qtConfig(private_tests):qtHaveModule(gui) {
|
||||||
tst.depends += machtest
|
tst.depends += machtest
|
||||||
SUBDIRS += machtest
|
SUBDIRS += machtest
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,6 @@ private Q_SLOTS:
|
|||||||
|
|
||||||
void lookupTableConstructor();
|
void lookupTableConstructor();
|
||||||
|
|
||||||
void lookupTableStatic_data();
|
|
||||||
void lookupTableStatic();
|
void lookupTableStatic();
|
||||||
void lookupTableDynamic();
|
void lookupTableDynamic();
|
||||||
|
|
||||||
@ -126,7 +125,7 @@ void tst_Hpack::bitstreamConstruction()
|
|||||||
// 'Read' some data back:
|
// 'Read' some data back:
|
||||||
for (int i = 0; i < size; ++i) {
|
for (int i = 0; i < size; ++i) {
|
||||||
uchar bitPattern = 0;
|
uchar bitPattern = 0;
|
||||||
const auto bitsRead = in.peekBits(i * 8, 8, &bitPattern);
|
const auto bitsRead = in.peekBits(quint64(i * 8), 8, &bitPattern);
|
||||||
QVERIFY(bitsRead == 8);
|
QVERIFY(bitsRead == 8);
|
||||||
QVERIFY(bitPattern == bytes[i]);
|
QVERIFY(bitPattern == bytes[i]);
|
||||||
}
|
}
|
||||||
@ -282,7 +281,7 @@ void tst_Hpack::bitstreamCompression()
|
|||||||
const auto start = QRandomGenerator::global()->bounded(uint(bytes.length()) / 2);
|
const auto start = QRandomGenerator::global()->bounded(uint(bytes.length()) / 2);
|
||||||
auto end = start * 2;
|
auto end = start * 2;
|
||||||
if (!end)
|
if (!end)
|
||||||
end = bytes.length() / 2;
|
end = unsigned(bytes.length() / 2);
|
||||||
strings.push_back(bytes.substr(start, end - start));
|
strings.push_back(bytes.substr(start, end - start));
|
||||||
const auto &s = strings.back();
|
const auto &s = strings.back();
|
||||||
totalStringBytes += s.size();
|
totalStringBytes += s.size();
|
||||||
@ -384,43 +383,21 @@ void tst_Hpack::lookupTableConstructor()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_Hpack::lookupTableStatic_data()
|
|
||||||
{
|
|
||||||
QTest::addColumn<QByteArray>("expectedName");
|
|
||||||
QTest::addColumn<QByteArray>("expectedValue");
|
|
||||||
|
|
||||||
// Some predefined fields to find
|
|
||||||
// (they are always defined/required by HPACK).
|
|
||||||
QTest::newRow(":authority|") << QByteArray(":authority") << QByteArray("");
|
|
||||||
QTest::newRow(":method|GET") << QByteArray(":method") << QByteArray("GET");
|
|
||||||
QTest::newRow(":method|POST") << QByteArray(":method") << QByteArray("POST");
|
|
||||||
QTest::newRow(":path|/") << QByteArray(":path") << QByteArray("/");
|
|
||||||
QTest::newRow(":path|/index.html") << QByteArray(":path") << QByteArray("/index.html");
|
|
||||||
QTest::newRow(":scheme|http") << QByteArray(":scheme") << QByteArray("http");
|
|
||||||
QTest::newRow(":scheme|https") << QByteArray(":scheme") << QByteArray("https");
|
|
||||||
QTest::newRow(":status|200") << QByteArray(":status") << QByteArray("200");
|
|
||||||
QTest::newRow(":status|204") << QByteArray(":status") << QByteArray("204");
|
|
||||||
QTest::newRow(":status|206") << QByteArray(":status") << QByteArray("206");
|
|
||||||
QTest::newRow(":status|304") << QByteArray(":status") << QByteArray("304");
|
|
||||||
QTest::newRow(":status|400") << QByteArray(":status") << QByteArray("400");
|
|
||||||
QTest::newRow(":status|404") << QByteArray(":status") << QByteArray("404");
|
|
||||||
QTest::newRow(":status|500") << QByteArray(":status") << QByteArray("500");
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_Hpack::lookupTableStatic()
|
void tst_Hpack::lookupTableStatic()
|
||||||
{
|
{
|
||||||
const FieldLookupTable table(0, false /*all static, no need in 'search index'*/);
|
const FieldLookupTable table(0, false /*all static, no need in 'search index'*/);
|
||||||
|
const auto &staticTable = FieldLookupTable::staticPart();
|
||||||
QFETCH(QByteArray, expectedName);
|
|
||||||
QFETCH(QByteArray, expectedValue);
|
|
||||||
|
|
||||||
const quint32 index = table.indexOf(expectedName, expectedValue);
|
|
||||||
QVERIFY(index != 0);
|
|
||||||
|
|
||||||
QByteArray name, value;
|
QByteArray name, value;
|
||||||
QVERIFY(table.field(index, &name, &value));
|
quint32 currentIndex = 1; // HPACK is indexing starting from 1.
|
||||||
QCOMPARE(name, expectedName);
|
for (const HeaderField &field : staticTable) {
|
||||||
QCOMPARE(value, expectedValue);
|
const quint32 index = table.indexOf(field.name, field.value);
|
||||||
|
QVERIFY(index != 0);
|
||||||
|
QCOMPARE(index, currentIndex);
|
||||||
|
QVERIFY(table.field(index, &name, &value));
|
||||||
|
QCOMPARE(name, field.name);
|
||||||
|
QCOMPARE(value, field.value);
|
||||||
|
++currentIndex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_Hpack::lookupTableDynamic()
|
void tst_Hpack::lookupTableDynamic()
|
||||||
|
@ -56,7 +56,7 @@ winrt|!qtHaveModule(gui)|!qtConfig(accessibility): SUBDIRS -= qaccessibility
|
|||||||
|
|
||||||
!qtConfig(process): SUBDIRS -= qprocess_and_guieventloop
|
!qtConfig(process): SUBDIRS -= qprocess_and_guieventloop
|
||||||
|
|
||||||
!mac: SUBDIRS -= \
|
!macos|!qtHaveModule(gui): SUBDIRS -= \
|
||||||
macgui \
|
macgui \
|
||||||
macnativeevents \
|
macnativeevents \
|
||||||
macplist \
|
macplist \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user