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

Change-Id: I9c2a18f5110adf3d8f630718238866aef47bb782
This commit is contained in:
Qt Forward Merge Bot 2018-08-26 01:00:16 +02:00
commit 2cdbe29ef0
29 changed files with 269 additions and 91 deletions

View File

@ -5,7 +5,7 @@
QMAKE_PLATFORM += macos osx macx QMAKE_PLATFORM += macos osx macx
QMAKE_MAC_SDK = macosx QMAKE_MAC_SDK = macosx
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.11 QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.12
QMAKE_APPLE_DEVICE_ARCHS = x86_64 QMAKE_APPLE_DEVICE_ARCHS = x86_64
device.sdk = macosx device.sdk = macosx

View File

@ -16,7 +16,9 @@ MAKEFILE_GENERATOR = MSVC.NET
QMAKE_PLATFORM = win32 QMAKE_PLATFORM = win32
QMAKE_COMPILER = msvc QMAKE_COMPILER = msvc
CONFIG += flat debug_and_release debug_and_release_target precompile_header autogen_precompile_source embed_manifest_dll embed_manifest_exe CONFIG += flat debug_and_release debug_and_release_target precompile_header autogen_precompile_source embed_manifest_dll embed_manifest_exe
DEFINES += UNICODE _UNICODE WIN32 # MSVC 2017 15.8+ fixed std::aligned_storage but compilation fails without
# _ENABLE_EXTENDED_ALIGNED_STORAGE flag since the fix breaks binary compatibility.
DEFINES += UNICODE _UNICODE WIN32 _ENABLE_EXTENDED_ALIGNED_STORAGE
QMAKE_COMPILER_DEFINES += _WIN32 QMAKE_COMPILER_DEFINES += _WIN32
contains(QMAKE_TARGET.arch, x86_64) { contains(QMAKE_TARGET.arch, x86_64) {
DEFINES += WIN64 DEFINES += WIN64

View File

@ -110,12 +110,6 @@ greaterThan(QMAKE_MSC_VER, 1909) {
QMAKE_CXXFLAGS_CXX14 = -std:c++14 QMAKE_CXXFLAGS_CXX14 = -std:c++14
QMAKE_CXXFLAGS_CXX1Z = -std:c++17 QMAKE_CXXFLAGS_CXX1Z = -std:c++17
} }
# MSVC 2017 15.8+ fixed std::aligned_storage but compilation fails without
# this flag since the fix breaks binary compatibility.
greaterThan(QMAKE_MSC_VER, 1914) {
DEFINES += _ENABLE_EXTENDED_ALIGNED_STORAGE
}
} }
greaterThan(QMAKE_MSC_VER, 1910) { greaterThan(QMAKE_MSC_VER, 1910) {

View File

@ -2,7 +2,7 @@
# qmake configuration for macx-ios-clang # qmake configuration for macx-ios-clang
# #
QMAKE_IOS_DEPLOYMENT_TARGET = 10.0 QMAKE_IOS_DEPLOYMENT_TARGET = 11.0
# Universal target (iPhone and iPad) # Universal target (iPhone and iPad)
QMAKE_APPLE_TARGETED_DEVICE_FAMILY = 1,2 QMAKE_APPLE_TARGETED_DEVICE_FAMILY = 1,2

View File

@ -2,7 +2,7 @@
# qmake configuration for macx-tvos-clang # qmake configuration for macx-tvos-clang
# #
QMAKE_TVOS_DEPLOYMENT_TARGET = 10.0 QMAKE_TVOS_DEPLOYMENT_TARGET = 11.0
QMAKE_APPLE_TARGETED_DEVICE_FAMILY = 3 QMAKE_APPLE_TARGETED_DEVICE_FAMILY = 3

View File

@ -2,7 +2,7 @@
# qmake configuration for macx-watchos-clang # qmake configuration for macx-watchos-clang
# #
QMAKE_WATCHOS_DEPLOYMENT_TARGET = 3.0 QMAKE_WATCHOS_DEPLOYMENT_TARGET = 4.0
QMAKE_APPLE_TARGETED_DEVICE_FAMILY = 4 QMAKE_APPLE_TARGETED_DEVICE_FAMILY = 4

View File

@ -12,7 +12,6 @@ include(../common/msvc-desktop.conf)
# modifications to msvc-desktop.conf # modifications to msvc-desktop.conf
QMAKE_COMPILER += intel_icl QMAKE_COMPILER += intel_icl
DEFINES += _ENABLE_EXTENDED_ALIGNED_STORAGE
QMAKE_CFLAGS_OPTIMIZE_FULL = -O3 QMAKE_CFLAGS_OPTIMIZE_FULL = -O3

View File

@ -45,11 +45,17 @@ QT_BEGIN_NAMESPACE
// //
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
ProFileCache::ProFileCache()
{
QMakeVfs::ref();
}
ProFileCache::~ProFileCache() ProFileCache::~ProFileCache()
{ {
for (const Entry &ent : qAsConst(parsed_files)) for (const Entry &ent : qAsConst(parsed_files))
if (ent.pro) if (ent.pro)
ent.pro->deref(); ent.pro->deref();
QMakeVfs::deref();
} }
void ProFileCache::discardFile(const QString &fileName, QMakeVfs *vfs) void ProFileCache::discardFile(const QString &fileName, QMakeVfs *vfs)

View File

@ -201,7 +201,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QMakeParser::ParseFlags)
class QMAKE_EXPORT ProFileCache class QMAKE_EXPORT ProFileCache
{ {
public: public:
ProFileCache() {} ProFileCache();
~ProFileCache(); ~ProFileCache();
void discardFile(int id); void discardFile(int id);

View File

@ -52,11 +52,38 @@ QMakeVfs::QMakeVfs()
#ifndef QT_NO_TEXTCODEC #ifndef QT_NO_TEXTCODEC
m_textCodec = 0; m_textCodec = 0;
#endif #endif
ref();
}
QMakeVfs::~QMakeVfs()
{
deref();
}
void QMakeVfs::ref()
{
#ifdef PROEVALUATOR_THREAD_SAFE
QMutexLocker locker(&s_mutex);
#endif
++s_refCount;
}
void QMakeVfs::deref()
{
#ifdef PROEVALUATOR_THREAD_SAFE
QMutexLocker locker(&s_mutex);
#endif
if (!--s_refCount) {
s_fileIdCounter = 0;
s_fileIdMap.clear();
s_idFileMap.clear();
}
} }
#ifdef PROPARSER_THREAD_SAFE #ifdef PROPARSER_THREAD_SAFE
QMutex QMakeVfs::s_mutex; QMutex QMakeVfs::s_mutex;
#endif #endif
int QMakeVfs::s_refCount;
QAtomicInt QMakeVfs::s_fileIdCounter; QAtomicInt QMakeVfs::s_fileIdCounter;
QHash<QString, int> QMakeVfs::s_fileIdMap; QHash<QString, int> QMakeVfs::s_fileIdMap;
QHash<int, QString> QMakeVfs::s_idFileMap; QHash<int, QString> QMakeVfs::s_idFileMap;
@ -114,16 +141,6 @@ QString QMakeVfs::fileNameForId(int id)
return s_idFileMap.value(id); return s_idFileMap.value(id);
} }
void QMakeVfs::clearIds()
{
#ifdef PROEVALUATOR_THREAD_SAFE
QMutexLocker locker(&s_mutex);
#endif
s_fileIdCounter = 0;
s_fileIdMap.clear();
s_idFileMap.clear();
}
bool QMakeVfs::writeFile(int id, QIODevice::OpenMode mode, VfsFlags flags, bool QMakeVfs::writeFile(int id, QIODevice::OpenMode mode, VfsFlags flags,
const QString &contents, QString *errStr) const QString &contents, QString *errStr)
{ {

View File

@ -76,10 +76,13 @@ public:
Q_DECLARE_FLAGS(VfsFlags, VfsFlag) Q_DECLARE_FLAGS(VfsFlags, VfsFlag)
QMakeVfs(); QMakeVfs();
~QMakeVfs();
static void ref();
static void deref();
int idForFileName(const QString &fn, VfsFlags flags); int idForFileName(const QString &fn, VfsFlags flags);
QString fileNameForId(int id); QString fileNameForId(int id);
static void clearIds();
bool writeFile(int id, QIODevice::OpenMode mode, VfsFlags flags, const QString &contents, QString *errStr); bool writeFile(int id, QIODevice::OpenMode mode, VfsFlags flags, const QString &contents, QString *errStr);
ReadResult readFile(int id, QString *contents, QString *errStr); ReadResult readFile(int id, QString *contents, QString *errStr);
bool exists(const QString &fn, QMakeVfs::VfsFlags flags); bool exists(const QString &fn, QMakeVfs::VfsFlags flags);
@ -97,6 +100,7 @@ private:
#ifdef PROEVALUATOR_THREAD_SAFE #ifdef PROEVALUATOR_THREAD_SAFE
static QMutex s_mutex; static QMutex s_mutex;
#endif #endif
static int s_refCount;
static QAtomicInt s_fileIdCounter; static QAtomicInt s_fileIdCounter;
// Qt Creator's ProFile cache is a singleton to maximize its cross-project // Qt Creator's ProFile cache is a singleton to maximize its cross-project
// effectiveness (shared prf files from QtVersions). // effectiveness (shared prf files from QtVersions).

View File

@ -58,6 +58,8 @@
#include "private/qabstractanimation_p.h" #include "private/qabstractanimation_p.h"
#include <type_traits>
#ifndef QT_NO_ANIMATION #ifndef QT_NO_ANIMATION
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -104,7 +106,17 @@ public:
}; };
//this should make the interpolation faster //this should make the interpolation faster
template<typename T> inline T _q_interpolate(const T &f, const T &t, qreal progress) template<typename T>
typename std::enable_if<std::is_unsigned<T>::value, T>::type
_q_interpolate(const T &f, const T &t, qreal progress)
{
return T(f + t * progress - f * progress);
}
// the below will apply also to all non-arithmetic types
template<typename T>
typename std::enable_if<!std::is_unsigned<T>::value, T>::type
_q_interpolate(const T &f, const T &t, qreal progress)
{ {
return T(f + (t - f) * progress); return T(f + (t - f) * progress);
} }

View File

@ -65,6 +65,7 @@ QCFString::operator CFStringRef() const
#if defined(QT_USE_APPLE_UNIFIED_LOGGING) #if defined(QT_USE_APPLE_UNIFIED_LOGGING)
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)
{ {

View File

@ -40,8 +40,13 @@
#include <private/qcore_mac_p.h> #include <private/qcore_mac_p.h>
#ifdef Q_OS_OSX #ifdef Q_OS_MACOS
#include <AppKit/NSText.h> # include <AppKit/AppKit.h>
# if !QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14)
@interface NSApplication (MojaveForwardDeclarations)
@property (strong) NSAppearance *effectiveAppearance NS_AVAILABLE_MAC(10_14);
@end
# endif
#endif #endif
#if defined(QT_PLATFORM_UIKIT) #if defined(QT_PLATFORM_UIKIT)
@ -166,6 +171,16 @@ QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool)
} }
#endif // !QT_NO_DEBUG_STREAM #endif // !QT_NO_DEBUG_STREAM
#ifdef Q_OS_MACOS
bool qt_mac_applicationIsInDarkMode()
{
if (__builtin_available(macOS 10.14, *))
return [NSApp.effectiveAppearance.name hasSuffix:@"DarkAqua"];
else
return false;
}
#endif
bool qt_apple_isApplicationExtension() bool qt_apple_isApplicationExtension()
{ {
static bool isExtension = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSExtension"]; static bool isExtension = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSExtension"];
@ -433,16 +448,23 @@ void qt_apple_check_os_version()
version / 10000, version / 100 % 100, version % 100}; version / 10000, version / 100 % 100, version % 100};
const NSOperatingSystemVersion current = NSProcessInfo.processInfo.operatingSystemVersion; const NSOperatingSystemVersion current = NSProcessInfo.processInfo.operatingSystemVersion;
if (![NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:required]) { if (![NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:required]) {
fprintf(stderr, "You can't use this version of %s with this version of %s. " NSDictionary *plist = NSBundle.mainBundle.infoDictionary;
"You have %s %ld.%ld.%ld. Qt requires %s %ld.%ld.%ld or later.\n", NSString *applicationName = plist[@"CFBundleDisplayName"];
(reinterpret_cast<const NSString *>( if (!applicationName)
NSBundle.mainBundle.infoDictionary[@"CFBundleName"]).UTF8String), applicationName = plist[@"CFBundleName"];
os, if (!applicationName)
os, long(current.majorVersion), long(current.minorVersion), long(current.patchVersion), applicationName = NSProcessInfo.processInfo.processName;
os, long(required.majorVersion), long(required.minorVersion), long(required.patchVersion));
abort(); fprintf(stderr, "Sorry, \"%s\" can not be run on this version of %s. "
"Qt requires %s %ld.%ld.%ld or later, you have %s %ld.%ld.%ld.\n",
applicationName.UTF8String, os,
os, long(required.majorVersion), long(required.minorVersion), long(required.patchVersion),
os, long(current.majorVersion), long(current.minorVersion), long(current.patchVersion));
exit(1);
} }
} }
Q_CONSTRUCTOR_FUNCTION(qt_apple_check_os_version);
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------

View File

@ -108,6 +108,8 @@
#define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__) #define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__)
#endif #endif
#define QT_MAC_WEAK_IMPORT(symbol) extern "C" decltype(symbol) symbol __attribute__((weak_import));
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
template <typename T, typename U, U (*RetainFunction)(U), void (*ReleaseFunction)(U)> template <typename T, typename U, U (*RetainFunction)(U), void (*ReleaseFunction)(U)>
class QAppleRefCounted class QAppleRefCounted
@ -180,16 +182,16 @@ private:
QString string; QString string;
}; };
#ifdef Q_OS_OSX #ifdef Q_OS_MACOS
Q_CORE_EXPORT QChar qt_mac_qtKey2CocoaKey(Qt::Key key); Q_CORE_EXPORT QChar qt_mac_qtKey2CocoaKey(Qt::Key key);
Q_CORE_EXPORT Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode); Q_CORE_EXPORT Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode);
Q_CORE_EXPORT bool qt_mac_applicationIsInDarkMode();
#endif #endif
#ifndef QT_NO_DEBUG_STREAM #ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool); QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool);
#endif #endif
Q_CORE_EXPORT void qt_apple_check_os_version();
Q_CORE_EXPORT bool qt_apple_isApplicationExtension(); Q_CORE_EXPORT bool qt_apple_isApplicationExtension();
#if defined(Q_OS_MACOS) && !defined(QT_BOOTSTRAPPED) #if defined(Q_OS_MACOS) && !defined(QT_BOOTSTRAPPED)
@ -326,6 +328,7 @@ private:
#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT2(description, parent) QT_APPLE_LOG_ACTIVITY_WITH_PARENT3(true, description, parent) #define QT_APPLE_LOG_ACTIVITY_WITH_PARENT2(description, parent) QT_APPLE_LOG_ACTIVITY_WITH_PARENT3(true, description, parent)
#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY_WITH_PARENT, __VA_ARGS__) #define QT_APPLE_LOG_ACTIVITY_WITH_PARENT(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY_WITH_PARENT, __VA_ARGS__)
QT_MAC_WEAK_IMPORT(_os_activity_current);
#define QT_APPLE_LOG_ACTIVITY2(condition, description) QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, OS_ACTIVITY_CURRENT) #define QT_APPLE_LOG_ACTIVITY2(condition, description) QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, OS_ACTIVITY_CURRENT)
#define QT_APPLE_LOG_ACTIVITY1(description) QT_APPLE_LOG_ACTIVITY2(true, description) #define QT_APPLE_LOG_ACTIVITY1(description) QT_APPLE_LOG_ACTIVITY2(true, description)
#define QT_APPLE_LOG_ACTIVITY(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY, __VA_ARGS__) #define QT_APPLE_LOG_ACTIVITY(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY, __VA_ARGS__)

View File

@ -456,9 +456,6 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
, q_ptr(0) , q_ptr(0)
#endif #endif
{ {
#if defined(Q_OS_DARWIN)
qt_apple_check_os_version();
#endif
app_compile_version = flags & 0xffffff; app_compile_version = flags & 0xffffff;
static const char *const empty = ""; static const char *const empty = "";
if (argc == 0 || argv == 0) { if (argc == 0 || argv == 0) {

View File

@ -154,7 +154,7 @@ QT_END_NAMESPACE
#else // !QT_CONFIG(thread) #else // !QT_CONFIG(thread)
#include <qscopedpointer.h> #include <QtCore/qscopedpointer.h>
#include <type_traits> #include <type_traits>

View File

@ -2742,10 +2742,13 @@ QDebug operator<<(QDebug debug, QRegularExpression::PatternOptions patternOption
flags.append("DontCaptureOption|"); flags.append("DontCaptureOption|");
if (patternOptions & QRegularExpression::UseUnicodePropertiesOption) if (patternOptions & QRegularExpression::UseUnicodePropertiesOption)
flags.append("UseUnicodePropertiesOption|"); flags.append("UseUnicodePropertiesOption|");
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
if (patternOptions & QRegularExpression::OptimizeOnFirstUsageOption) if (patternOptions & QRegularExpression::OptimizeOnFirstUsageOption)
flags.append("OptimizeOnFirstUsageOption|"); flags.append("OptimizeOnFirstUsageOption|");
if (patternOptions & QRegularExpression::DontAutomaticallyOptimizeOption) if (patternOptions & QRegularExpression::DontAutomaticallyOptimizeOption)
flags.append("DontAutomaticallyOptimizeOption|"); flags.append("DontAutomaticallyOptimizeOption|");
QT_WARNING_POP
flags.chop(1); flags.chop(1);
} }

View File

@ -2789,7 +2789,7 @@ Qt::MouseButtons QTabletEvent::buttons() const
\header \header
\li Event Type \li Event Type
\li Description \li Description
\li Touch equence \li Touch sequence
\row \row
\li Qt::ZoomNativeGesture \li Qt::ZoomNativeGesture
\li Magnification delta in percent. \li Magnification delta in percent.

View File

@ -42,6 +42,7 @@
#include <qpa/qplatformfontdatabase.h> #include <qpa/qplatformfontdatabase.h>
#include <QtCore/qendian.h> #include <QtCore/qendian.h>
#include <QtCore/qsettings.h> #include <QtCore/qsettings.h>
#include <QtCore/qoperatingsystemversion.h>
#include <private/qimage_p.h> #include <private/qimage_p.h>
@ -652,17 +653,36 @@ bool QCoreTextFontEngine::expectsGammaCorrectedBlending() const
QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool aa, const QTransform &matrix) QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool aa, const QTransform &matrix)
{ {
glyph_metrics_t br = alphaMapBoundingBox(glyph, subPixelPosition, matrix, glyphFormat); glyph_metrics_t br = alphaMapBoundingBox(glyph, subPixelPosition, matrix, glyphFormat);
bool isColorGlyph = glyphFormat == QFontEngine::Format_ARGB; bool isColorGlyph = glyphFormat == QFontEngine::Format_ARGB;
QImage::Format imageFormat = isColorGlyph ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; QImage::Format imageFormat = isColorGlyph ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
QImage im(br.width.ceil().toInt(), br.height.ceil().toInt(), imageFormat); QImage im(br.width.ceil().toInt(), br.height.ceil().toInt(), imageFormat);
im.fill(0);
if (!im.width() || !im.height()) if (!im.width() || !im.height())
return im; return im;
#if defined(Q_OS_MACOS)
CGColorRef glyphColor = CGColorGetConstantColor(kCGColorWhite);
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave) {
// macOS 10.14 uses a new font smoothing algorithm that takes the fill color into
// account. This means our default approach of drawing white on black to produce
// the alpha map will result in non-native looking text when then drawn as black
// on white during the final blit. As a workaround we use the application's current
// appearance to decide whether to draw with white or black fill, and then invert
// the glyph image in the latter case, producing an alpha map. This covers the
// most common use-cases, but longer term we should propagate the fill color all
// the way from the paint engine, and include it in the key for the glyph cache.
if (!qt_mac_applicationIsInDarkMode())
glyphColor = CGColorGetConstantColor(kCGColorBlack);
}
const bool blackOnWhiteGlyphs = !isColorGlyph
&& CGColorEqualToColor(glyphColor, CGColorGetConstantColor(kCGColorBlack));
if (blackOnWhiteGlyphs)
im.fill(Qt::white);
else
#endif
im.fill(0); // Faster than Qt::black
CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
uint cgflags = isColorGlyph ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst; uint cgflags = isColorGlyph ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst;
#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version #ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
@ -696,7 +716,11 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
if (!isColorGlyph) { if (!isColorGlyph) {
CGContextSetTextMatrix(ctx, cgMatrix); CGContextSetTextMatrix(ctx, cgMatrix);
#if defined(Q_OS_MACOS)
CGContextSetFillColorWithColor(ctx, glyphColor);
#else
CGContextSetRGBFillColor(ctx, 1, 1, 1, 1); CGContextSetRGBFillColor(ctx, 1, 1, 1, 1);
#endif
CGContextSetTextDrawingMode(ctx, kCGTextFill); CGContextSetTextDrawingMode(ctx, kCGTextFill);
CGContextSetTextPosition(ctx, pos_x, pos_y); CGContextSetTextPosition(ctx, pos_x, pos_y);
@ -721,6 +745,11 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
CGContextRelease(ctx); CGContextRelease(ctx);
CGColorSpaceRelease(colorspace); CGColorSpaceRelease(colorspace);
#if defined(Q_OS_MACOS)
if (blackOnWhiteGlyphs)
im.invertPixels();
#endif
return im; return im;
} }

View File

@ -295,26 +295,17 @@ public:
} }
private: private:
template <std::size_t... Ts>
struct index {};
template <std::size_t N, std::size_t... Ts>
struct gen_seq : gen_seq<N - 1, N - 1, Ts...> {};
template <std::size_t... Ts>
struct gen_seq<0, Ts...> : index<Ts...> {};
template <typename ReturnType, bool V> template <typename ReturnType, bool V>
using if_requires_stret = typename std::enable_if<objc_msgsend_requires_stret<ReturnType>::value == V, ReturnType>::type; using if_requires_stret = typename std::enable_if<objc_msgsend_requires_stret<ReturnType>::value == V, ReturnType>::type;
template <typename ReturnType, std::size_t... Is> template <typename ReturnType, int... Is>
if_requires_stret<ReturnType, false> msgSendSuper(std::tuple<Args...>& args, index<Is...>) if_requires_stret<ReturnType, false> msgSendSuper(std::tuple<Args...>& args, QtPrivate::IndexesList<Is...>)
{ {
return qt_msgSendSuper<ReturnType>(m_receiver, m_selector, std::get<Is>(args)...); return qt_msgSendSuper<ReturnType>(m_receiver, m_selector, std::get<Is>(args)...);
} }
template <typename ReturnType, std::size_t... Is> template <typename ReturnType, int... Is>
if_requires_stret<ReturnType, true> msgSendSuper(std::tuple<Args...>& args, index<Is...>) if_requires_stret<ReturnType, true> msgSendSuper(std::tuple<Args...>& args, QtPrivate::IndexesList<Is...>)
{ {
return qt_msgSendSuper_stret<ReturnType>(m_receiver, m_selector, std::get<Is>(args)...); return qt_msgSendSuper_stret<ReturnType>(m_receiver, m_selector, std::get<Is>(args)...);
} }
@ -322,7 +313,7 @@ private:
template <typename ReturnType> template <typename ReturnType>
ReturnType msgSendSuper(std::tuple<Args...>& args) ReturnType msgSendSuper(std::tuple<Args...>& args)
{ {
return msgSendSuper<ReturnType>(args, gen_seq<sizeof...(Args)>{}); return msgSendSuper<ReturnType>(args, QtPrivate::makeIndexSequence<sizeof...(Args)>{});
} }
id m_receiver; id m_receiver;

View File

@ -75,6 +75,9 @@ static void writeEtwMacro(QTextStream &stream, const Tracepoint::Field &field)
<< "TraceLoggingValue(" << name << ".width(), \"width\"), " << "TraceLoggingValue(" << name << ".width(), \"width\"), "
<< "TraceLoggingValue(" << name << ".height(), \"height\")"; << "TraceLoggingValue(" << name << ".height(), \"height\")";
return; return;
case Tracepoint::Field::Pointer:
stream << "TraceLoggingPointer(" << name << ", \"" << name << "\")";
return;
default: default:
break; break;
} }

View File

@ -43,6 +43,7 @@ private slots:
void keyValueAt(); void keyValueAt();
void keyValues(); void keyValues();
void duration(); void duration();
void interpolation();
}; };
class TestableQVariantAnimation : public QVariantAnimation class TestableQVariantAnimation : public QVariantAnimation
@ -129,6 +130,30 @@ void tst_QVariantAnimation::duration()
QCOMPARE(anim.duration(), 500); QCOMPARE(anim.duration(), 500);
} }
void tst_QVariantAnimation::interpolation()
{
QVariantAnimation unsignedAnim;
unsignedAnim.setStartValue(100u);
unsignedAnim.setEndValue(0u);
unsignedAnim.setDuration(100);
unsignedAnim.setCurrentTime(50);
QCOMPARE(unsignedAnim.currentValue().toUInt(), 50u);
QVariantAnimation signedAnim;
signedAnim.setStartValue(100);
signedAnim.setEndValue(0);
signedAnim.setDuration(100);
signedAnim.setCurrentTime(50);
QCOMPARE(signedAnim.currentValue().toInt(), 50);
QVariantAnimation pointAnim;
pointAnim.setStartValue(QPoint(100, 100));
pointAnim.setEndValue(QPoint(0, 0));
pointAnim.setDuration(100);
pointAnim.setCurrentTime(50);
QCOMPARE(pointAnim.currentValue().toPoint(), QPoint(50, 50));
}
QTEST_MAIN(tst_QVariantAnimation) QTEST_MAIN(tst_QVariantAnimation)
#include "tst_qvariantanimation.moc" #include "tst_qvariantanimation.moc"

View File

@ -0,0 +1,2 @@
[timeZoneAbbreviation]
osx

View File

@ -2726,15 +2726,15 @@ void tst_QDateTime::timeZoneAbbreviation()
qDebug("(Skipped some CET-only tests)"); qDebug("(Skipped some CET-only tests)");
} }
QString cet(QStringLiteral("CET")), cest(QStringLiteral("CEST"));
#ifdef Q_OS_ANDROID // Only reports (general) zones as offsets (QTBUG-68837) #ifdef Q_OS_ANDROID // Only reports (general) zones as offsets (QTBUG-68837)
cet = QStringLiteral("GMT+01:00"); const QString cet(QStringLiteral("GMT+01:00"));
cest = QStringLiteral("GMT+02:00"); const QString cest(QStringLiteral("GMT+02:00"));
#elif defined Q_OS_DARWIN // Lacked real names until 10.13, High Sierra #elif defined Q_OS_DARWIN
if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSHighSierra) { const QString cet(QStringLiteral("GMT+1"));
cet = QStringLiteral("GMT+1"); const QString cest(QStringLiteral("GMT+2"));
cest = QStringLiteral("GMT+2"); #else
} const QString cet(QStringLiteral("CET"));
const QString cest(QStringLiteral("CEST"));
#endif #endif
QDateTime dt5(QDate(2013, 1, 1), QTime(0, 0, 0), QTimeZone("Europe/Berlin")); QDateTime dt5(QDate(2013, 1, 1), QTime(0, 0, 0), QTimeZone("Europe/Berlin"));

View File

@ -0,0 +1,2 @@
[formatTimeZone]
osx

View File

@ -1623,15 +1623,15 @@ void tst_QLocale::formatTimeZone()
qDebug("(Skipped some CET-only tests)"); qDebug("(Skipped some CET-only tests)");
} }
QString cet(QStringLiteral("CET")), cest(QStringLiteral("CEST"));
#ifdef Q_OS_ANDROID // Only reports (general) zones as offsets (QTBUG-68837) #ifdef Q_OS_ANDROID // Only reports (general) zones as offsets (QTBUG-68837)
cet = QStringLiteral("GMT+01:00"); const QString cet(QStringLiteral("GMT+01:00"));
cest = QStringLiteral("GMT+02:00"); const QString cest(QStringLiteral("GMT+02:00"));
#elif defined Q_OS_DARWIN // Lacked real names until 10.13, High Sierra #elif defined Q_OS_DARWIN
if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSHighSierra) { const QString cet(QStringLiteral("GMT+1"));
cet = QStringLiteral("GMT+1"); const QString cest(QStringLiteral("GMT+2"));
cest = QStringLiteral("GMT+2"); #else
} const QString cet(QStringLiteral("CET"));
const QString cest(QStringLiteral("CEST"));
#endif #endif
QDateTime dt6(QDate(2013, 1, 1), QTime(0, 0, 0), QTimeZone("Europe/Berlin")); QDateTime dt6(QDate(2013, 1, 1), QTime(0, 0, 0), QTimeZone("Europe/Berlin"));
@ -2467,6 +2467,10 @@ void tst_QLocale::currency()
QCOMPARE(de_DE.toCurrencyString(double(-1234.56), QLatin1String("BAZ")), QCOMPARE(de_DE.toCurrencyString(double(-1234.56), QLatin1String("BAZ")),
QString::fromUtf8("-1.234,56\xc2\xa0" "BAZ")); QString::fromUtf8("-1.234,56\xc2\xa0" "BAZ"));
const QLocale es_CR(QLocale::Spanish, QLocale::CostaRica);
QCOMPARE(es_CR.toCurrencyString(double(1565.25)),
QString::fromUtf8("\xE2\x82\xA1" "1\xC2\xA0" "565,25"));
const QLocale system = QLocale::system(); const QLocale system = QLocale::system();
QVERIFY(system.toCurrencyString(1, QLatin1String("FOO")).contains(QLatin1String("FOO"))); QVERIFY(system.toCurrencyString(1, QLatin1String("FOO")).contains(QLatin1String("FOO")));
} }

View File

@ -12,3 +12,5 @@ ubuntu-18.04
ubuntu-18.04 ubuntu-18.04
[explicitGraphicsObjectTarget] [explicitGraphicsObjectTarget]
ubuntu-18.04 ubuntu-18.04
[autoCancelGestures2]
ubuntu-18.04

View File

@ -49,6 +49,7 @@
#include <qsortfilterproxymodel.h> #include <qsortfilterproxymodel.h>
#include <qlineedit.h> #include <qlineedit.h>
#include <qlayout.h> #include <qlayout.h>
#include <qtemporarydir.h>
#include <private/qfiledialog_p.h> #include <private/qfiledialog_p.h>
#if defined QT_BUILD_INTERNAL #if defined QT_BUILD_INTERNAL
#include <private/qsidebar_p.h> #include <private/qsidebar_p.h>
@ -1310,57 +1311,116 @@ void tst_QFiledialog::saveButtonText()
QCOMPARE(button->text(), caption); QCOMPARE(button->text(), caption);
} }
// Predicate for use with QTRY_VERIFY() that checks whether the file dialog list
// has been populated (contains an entry).
class DirPopulatedPredicate
{
public:
explicit DirPopulatedPredicate(QListView *list, const QString &needle) :
m_list(list), m_needle(needle) {}
operator bool() const
{
const auto model = m_list->model();
const auto root = m_list->rootIndex();
for (int r = 0, count = model->rowCount(root); r < count; ++r) {
if (m_needle == model->index(r, 0, root).data(Qt::DisplayRole).toString())
return true;
}
return false;
}
private:
QListView *m_list;
QString m_needle;
};
// A predicate for use with QTRY_VERIFY() that ensures an entry of the file dialog
// list is selected by pressing cursor down.
class SelectDirTestPredicate
{
public:
explicit SelectDirTestPredicate(QListView *list, const QString &needle) :
m_list(list), m_needle(needle) {}
operator bool() const
{
if (m_needle == m_list->currentIndex().data(Qt::DisplayRole).toString())
return true;
QCoreApplication::processEvents();
QTest::keyClick(m_list, Qt::Key_Down);
return false;
}
private:
QListView *m_list;
QString m_needle;
};
void tst_QFiledialog::clearLineEdit() void tst_QFiledialog::clearLineEdit()
{ {
QFileDialog fd(0, "caption", "foo"); // Play it really safe by creating a directory which should show first in
// a temporary dir
QTemporaryDir workDir(QDir::tempPath() + QLatin1String("/tst_qfd_clearXXXXXX"));
QVERIFY2(workDir.isValid(), qPrintable(workDir.errorString()));
const QString workDirPath = workDir.path();
const QString dirName = QLatin1String("aaaaa");
QVERIFY(QDir(workDirPath).mkdir(dirName));
QFileDialog fd(nullptr,
QLatin1String(QTest::currentTestFunction()) + QLatin1String(" AnyFile"),
"foo");
fd.setViewMode(QFileDialog::List); fd.setViewMode(QFileDialog::List);
fd.setFileMode(QFileDialog::AnyFile); fd.setFileMode(QFileDialog::AnyFile);
fd.show(); fd.show();
//play it really safe by creating a directory
QDir::home().mkdir("_____aaaaaaaaaaaaaaaaaaaaaa");
QLineEdit *lineEdit = fd.findChild<QLineEdit*>("fileNameEdit"); QLineEdit *lineEdit = fd.findChild<QLineEdit*>("fileNameEdit");
QVERIFY(lineEdit); QVERIFY(lineEdit);
QCOMPARE(lineEdit->text(), QLatin1String("foo")); QCOMPARE(lineEdit->text(), QLatin1String("foo"));
fd.setDirectory(QDir::home());
QListView* list = fd.findChild<QListView*>("listView"); QListView* list = fd.findChild<QListView*>("listView");
QVERIFY(list); QVERIFY(list);
// saving a file the text shouldn't be cleared // When in AnyFile mode, lineEdit's text shouldn't be cleared when entering
fd.setDirectory(QDir::home()); // a directory by activating one in the list
fd.setDirectory(workDirPath);
DirPopulatedPredicate dirPopulated(list, dirName);
QTRY_VERIFY(dirPopulated);
#ifdef QT_KEYPAD_NAVIGATION #ifdef QT_KEYPAD_NAVIGATION
list->setEditFocus(true); list->setEditFocus(true);
#endif #endif
QTest::keyClick(list, Qt::Key_Down);
SelectDirTestPredicate selectTestDir(list, dirName);
QTRY_VERIFY(selectTestDir);
#ifndef Q_OS_MAC #ifndef Q_OS_MAC
QTest::keyClick(list, Qt::Key_Return); QTest::keyClick(list, Qt::Key_Return);
#else #else
QTest::keyClick(list, Qt::Key_O, Qt::ControlModifier); QTest::keyClick(list, Qt::Key_O, Qt::ControlModifier);
#endif #endif
QTRY_VERIFY(fd.directory().absolutePath() != QDir::home().absolutePath()); QTRY_VERIFY(fd.directory().absolutePath() != workDirPath);
QVERIFY(!lineEdit->text().isEmpty()); QVERIFY(!lineEdit->text().isEmpty());
// selecting a dir the text should be cleared so one can just hit ok // When in Directory mode, lineEdit's text should be cleared when entering
// a directory by activating one in the list so one can just hit ok
// and it selects that directory // and it selects that directory
fd.setFileMode(QFileDialog::Directory); fd.setFileMode(QFileDialog::Directory);
fd.setDirectory(QDir::home()); fd.setWindowTitle(QLatin1String(QTest::currentTestFunction()) + QLatin1String(" Directory"));
fd.setDirectory(workDirPath);
QTRY_VERIFY(dirPopulated);
QTRY_VERIFY(selectTestDir);
QTest::keyClick(list, Qt::Key_Down);
#ifndef Q_OS_MAC #ifndef Q_OS_MAC
QTest::keyClick(list, Qt::Key_Return); QTest::keyClick(list, Qt::Key_Return);
#else #else
QTest::keyClick(list, Qt::Key_O, Qt::ControlModifier); QTest::keyClick(list, Qt::Key_O, Qt::ControlModifier);
#endif #endif
QTRY_VERIFY(fd.directory().absolutePath() != QDir::home().absolutePath()); QTRY_VERIFY(fd.directory().absolutePath() != workDirPath);
QVERIFY(lineEdit->text().isEmpty()); QVERIFY(lineEdit->text().isEmpty());
//remove the dir
QDir::home().rmdir("_____aaaaaaaaaaaaaaaaaaaaaa");
} }
void tst_QFiledialog::enableChooseButton() void tst_QFiledialog::enableChooseButton()