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

Conflicts:
	qmake/generators/win32/mingw_make.cpp

Change-Id: I2f790bc8572bd22fea01edf7ca74595b29f063eb
This commit is contained in:
Liang Qi 2019-07-30 13:47:36 +02:00
commit 71ec1d6d79
19 changed files with 288 additions and 87 deletions

View File

@ -497,21 +497,20 @@ UnixMakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
// Make sure we keep the dependency order of libraries
lflags[arch].removeAll(opt);
lflags[arch].append(opt);
} else if (target_mode == TARG_MAC_MODE && opt.startsWith("-framework")) {
if (opt.length() > 10) {
opt = opt.mid(10).trimmed();
} else {
opt = l.at(++lit);
if (opt.startsWith("-Xarch"))
opt = l.at(++lit); // The user has done the right thing and prefixed each part
}
} else if (target_mode == TARG_MAC_MODE
&& (opt == "-framework" || opt == "-force_load")) {
// Handle space separated options
ProString dashOpt = opt;
opt = l.at(++lit);
if (opt.startsWith("-Xarch"))
opt = l.at(++lit); // The user has done the right thing and prefixed each part
for(int x = 0; x < lflags[arch].size(); ++x) {
if (lflags[arch].at(x) == "-framework" && lflags[arch].at(++x) == opt) {
if (lflags[arch].at(x) == dashOpt && lflags[arch].at(++x) == opt) {
lflags[arch].remove(x - 1, 2);
break;
}
}
lflags[arch].append("-framework");
lflags[arch].append(dashOpt);
lflags[arch].append(opt);
} else {
lflags[arch].append(opt);

View File

@ -127,7 +127,7 @@ QString MingwMakefileGenerator::installRoot() const
return QStringLiteral("$(INSTALL_ROOT:@msyshack@%=%)");
}
void createLdResponseFile(const QString &fileName, const ProStringList &objList)
static void createResponseFile(const QString &fileName, const ProStringList &objList)
{
QString filePath = Option::output_dir + QDir::separator() + fileName;
QFile file(filePath);
@ -151,23 +151,6 @@ void createLdResponseFile(const QString &fileName, const ProStringList &objList)
}
}
void createArObjectScriptFile(const QString &fileName, const QString &target, const ProStringList &objList)
{
QString filePath = Option::output_dir + QDir::separator() + fileName;
QFile file(filePath);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream t(&file);
// ### quoting?
t << "CREATE " << target << Qt::endl;
for (ProStringList::ConstIterator it = objList.constBegin(); it != objList.constEnd(); ++it) {
t << "ADDMOD " << *it << Qt::endl;
}
t << "SAVE\n";
t.flush();
file.close();
}
}
void MingwMakefileGenerator::writeMingwParts(QTextStream &t)
{
writeStandardParts(t);
@ -294,26 +277,25 @@ void MingwMakefileGenerator::writeObjectsPart(QTextStream &t)
if (objmax.isEmpty() || project->values("OBJECTS").count() < objmax.toInt()) {
objectsLinkLine = "$(OBJECTS)";
} else if (project->isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") {
QString ar_script_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET");
QString ar_response_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET");
if (!var("BUILD_NAME").isEmpty()) {
ar_script_file += "." + var("BUILD_NAME");
ar_response_file += "." + var("BUILD_NAME");
}
if (!var("MAKEFILE").isEmpty())
ar_script_file += "." + var("MAKEFILE");
ar_response_file += "." + var("MAKEFILE");
// QMAKE_LIB is used for win32, including mingw, whereas QMAKE_AR is used on Unix.
// Strip off any options since the ar commands will be read from file.
QString ar_cmd = var("QMAKE_LIB").section(" ", 0, 0);
QString ar_cmd = var("QMAKE_LIB");
if (ar_cmd.isEmpty())
ar_cmd = "ar";
createArObjectScriptFile(ar_script_file, var("DEST_TARGET"), project->values("OBJECTS"));
objectsLinkLine = ar_cmd + " -M < " + escapeFilePath(ar_script_file);
ar_cmd = "ar -rc";
createResponseFile(ar_response_file, project->values("OBJECTS"));
objectsLinkLine = ar_cmd + ' ' + var("DEST_TARGET") + " @" + escapeFilePath(ar_response_file);
} else {
QString ld_response_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET");
if (!var("BUILD_NAME").isEmpty())
ld_response_file += "." + var("BUILD_NAME");
if (!var("MAKEFILE").isEmpty())
ld_response_file += "." + var("MAKEFILE");
createLdResponseFile(ld_response_file, project->values("OBJECTS"));
createResponseFile(ld_response_file, project->values("OBJECTS"));
objectsLinkLine = "@" + escapeFilePath(ld_response_file);
}
Win32MakefileGenerator::writeObjectsPart(t);

View File

@ -167,19 +167,21 @@ QFSFileEngine::QFSFileEngine(QFSFileEnginePrivate &dd)
/*!
\internal
*/
bool QFSFileEngine::processOpenModeFlags(QIODevice::OpenMode *mode)
ProcessOpenModeResult processOpenModeFlags(QIODevice::OpenMode openMode)
{
QIODevice::OpenMode &openMode = *mode;
ProcessOpenModeResult result;
result.ok = false;
if ((openMode & QFile::NewOnly) && (openMode & QFile::ExistingOnly)) {
qWarning("NewOnly and ExistingOnly are mutually exclusive");
setError(QFile::OpenError, QLatin1String("NewOnly and ExistingOnly are mutually exclusive"));
return false;
result.error = QLatin1String("NewOnly and ExistingOnly are mutually exclusive");
return result;
}
if ((openMode & QFile::ExistingOnly) && !(openMode & (QFile::ReadOnly | QFile::WriteOnly))) {
qWarning("ExistingOnly must be specified alongside ReadOnly, WriteOnly, or ReadWrite");
setError(QFile::OpenError, QLatin1String("ExistingOnly must be specified alongside ReadOnly, WriteOnly, or ReadWrite"));
return false;
result.error = QLatin1String(
"ExistingOnly must be specified alongside ReadOnly, WriteOnly, or ReadWrite");
return result;
}
// Either Append or NewOnly implies WriteOnly
@ -190,7 +192,9 @@ bool QFSFileEngine::processOpenModeFlags(QIODevice::OpenMode *mode)
if ((openMode & QFile::WriteOnly) && !(openMode & (QFile::ReadOnly | QFile::Append | QFile::NewOnly)))
openMode |= QFile::Truncate;
return true;
result.ok = true;
result.openMode = openMode;
return result;
}
/*!
@ -234,16 +238,19 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode)
return false;
}
if (!processOpenModeFlags(&openMode))
const ProcessOpenModeResult res = processOpenModeFlags(openMode);
if (!res.ok) {
setError(QFileDevice::OpenError, res.error);
return false;
}
d->openMode = openMode;
d->openMode = res.openMode;
d->lastFlushFailed = false;
d->tried_stat = 0;
d->fh = nullptr;
d->fd = -1;
return d->nativeOpen(openMode);
return d->nativeOpen(d->openMode);
}
/*!
@ -262,17 +269,20 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, FILE *fh, QFile::FileHand
Q_D(QFSFileEngine);
if (!processOpenModeFlags(&openMode))
const ProcessOpenModeResult res = processOpenModeFlags(openMode);
if (!res.ok) {
setError(QFileDevice::OpenError, res.error);
return false;
}
d->openMode = openMode;
d->openMode = res.openMode;
d->lastFlushFailed = false;
d->closeFileHandle = (handleFlags & QFile::AutoCloseHandle);
d->fileEntry.clear();
d->tried_stat = 0;
d->fd = -1;
return d->openFh(openMode, fh);
return d->openFh(d->openMode, fh);
}
/*!
@ -321,10 +331,13 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, int fd, QFile::FileHandle
{
Q_D(QFSFileEngine);
if (!processOpenModeFlags(&openMode))
const ProcessOpenModeResult res = processOpenModeFlags(openMode);
if (!res.ok) {
setError(QFileDevice::OpenError, res.error);
return false;
}
d->openMode = openMode;
d->openMode = res.openMode;
d->lastFlushFailed = false;
d->closeFileHandle = (handleFlags & QFile::AutoCloseHandle);
d->fileEntry.clear();
@ -332,7 +345,7 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, int fd, QFile::FileHandle
d->fd = -1;
d->tried_stat = 0;
return d->openFd(openMode, fd);
return d->openFd(d->openMode, fd);
}

View File

@ -61,6 +61,13 @@
QT_BEGIN_NAMESPACE
struct ProcessOpenModeResult {
bool ok;
QIODevice::OpenMode openMode;
QString error;
};
inline Q_CORE_EXPORT ProcessOpenModeResult processOpenModeFlags(QIODevice::OpenMode mode);
class QFSFileEnginePrivate;
class Q_CORE_EXPORT QFSFileEngine : public QAbstractFileEngine
@ -131,9 +138,6 @@ public:
protected:
QFSFileEngine(QFSFileEnginePrivate &dd);
private:
inline bool processOpenModeFlags(QIODevice::OpenMode *mode);
};
class Q_AUTOTEST_EXPORT QFSFileEnginePrivate : public QAbstractFileEnginePrivate

View File

@ -948,8 +948,10 @@ bool QResourceRoot::mappingRootSubdir(const QString &path, QString *match) const
Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree,
const unsigned char *name, const unsigned char *data)
{
if (resourceGlobalData.isDestroyed())
return false;
QMutexLocker lock(resourceMutex());
if (version >= 0x01 && version <= 0x3 && resourceList()) {
if (version >= 0x01 && version <= 0x3) {
bool found = false;
QResourceRoot res(version, tree, name, data);
for(int i = 0; i < resourceList()->size(); ++i) {
@ -975,7 +977,7 @@ Q_CORE_EXPORT bool qUnregisterResourceData(int version, const unsigned char *tre
return false;
QMutexLocker lock(resourceMutex());
if (version >= 0x01 && version <= 0x3 && resourceList()) {
if (version >= 0x01 && version <= 0x3) {
QResourceRoot res(version, tree, name, data);
for(int i = 0; i < resourceList()->size(); ) {
if(*resourceList()->at(i) == res) {

View File

@ -135,8 +135,10 @@ static void q_loadCallback(val event)
if (readyState == 4) { // done
reply->setReplyAttributes(xhr["data-handler"].as<quintptr>(), status, statusText);
if (!responseString.isEmpty())
reply->dataReceived(responseString.toUtf8(), responseString.size());
if (!responseString.isEmpty()) {
QByteArray responseStringArray = responseString.toUtf8();
reply->dataReceived(responseStringArray, responseStringArray.size());
}
}
}
if (status >= 400 && !statusText.isEmpty())

View File

@ -112,11 +112,39 @@ int get_signal_index()
return signal_index + QMetaObjectPrivate::signalOffset(senderMetaObject);
}
void emit_results_ready(const QHostInfo &hostInfo, const QObject *receiver,
QtPrivate::QSlotObjectBase *slotObj)
}
/*
The calling thread is likely the one that executes the lookup via
QHostInfoRunnable. Unless we operate with a queued connection already,
posts the QHostInfo to a dedicated QHostInfoResult object that lives in
the same thread as the user-provided receiver, or (if there is none) in
the thread that made the call to lookupHost. That QHostInfoResult object
then calls the user code in the correct thread.
The 'result' object deletes itself (via deleteLater) when the metacall
event is received.
*/
void QHostInfoResult::postResultsReady(const QHostInfo &info)
{
// queued connection will take care of dispatching to right thread
if (!slotObj) {
emitResultsReady(info);
return;
}
static const int signal_index = get_signal_index();
// we used to have a context object, but it's already destroyed
if (withContextObject && !receiver)
return;
/* QHostInfoResult c'tor moves the result object to the thread of receiver.
If we don't have a receiver, then the result object will not live in a
thread that runs an event loop - so move it to this' thread, which is the thread
that initiated the lookup, and required to have a running event loop. */
auto result = new QHostInfoResult(receiver, slotObj);
if (!receiver)
result->moveToThread(thread());
Q_CHECK_PTR(result);
const int nargs = 2;
auto types = reinterpret_cast<int *>(malloc(nargs * sizeof(int)));
@ -126,15 +154,13 @@ void emit_results_ready(const QHostInfo &hostInfo, const QObject *receiver,
auto args = reinterpret_cast<void **>(malloc(nargs * sizeof(void *)));
Q_CHECK_PTR(args);
args[0] = 0;
args[1] = QMetaType::create(types[1], &hostInfo);
args[1] = QMetaType::create(types[1], &info);
Q_CHECK_PTR(args[1]);
auto metaCallEvent = new QMetaCallEvent(slotObj, nullptr, signal_index, nargs, types, args);
Q_CHECK_PTR(metaCallEvent);
qApp->postEvent(result, metaCallEvent);
}
}
/*!
\class QHostInfo
\brief The QHostInfo class provides static functions for host name lookups.
@ -322,6 +348,10 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver,
ready, the \a functor is called with a QHostInfo argument. The
QHostInfo object can then be inspected to get the results of the
lookup.
The \a functor will be run in the thread that makes the call to lookupHost;
that thread must have a running Qt event loop.
\note There is no guarantee on the order the signals will be emitted
if you start multiple requests with lookupHost().
@ -810,7 +840,8 @@ int QHostInfo::lookupHostImpl(const QString &name,
QHostInfo hostInfo(id);
hostInfo.setError(QHostInfo::HostNotFound);
hostInfo.setErrorString(QCoreApplication::translate("QHostInfo", "No host name given"));
emit_results_ready(hostInfo, receiver, slotObj);
QHostInfoResult result(receiver, slotObj);
result.postResultsReady(hostInfo);
return id;
}
@ -824,7 +855,8 @@ int QHostInfo::lookupHostImpl(const QString &name,
QHostInfo info = manager->cache.get(name, &valid);
if (valid) {
info.setLookupId(id);
emit_results_ready(info, receiver, slotObj);
QHostInfoResult result(receiver, slotObj);
result.postResultsReady(info);
return id;
}
}
@ -882,7 +914,7 @@ void QHostInfoRunnable::run()
// signal emission
hostInfo.setLookupId(id);
resultEmitter.emitResultsReady(hostInfo);
resultEmitter.postResultsReady(hostInfo);
#if QT_CONFIG(thread)
// now also iterate through the postponed ones
@ -895,7 +927,7 @@ void QHostInfoRunnable::run()
QHostInfoRunnable* postponed = *it;
// we can now emit
hostInfo.setLookupId(postponed->id);
postponed->resultEmitter.emitResultsReady(hostInfo);
postponed->resultEmitter.postResultsReady(hostInfo);
delete postponed;
}
manager->postponedLookups.erase(partitionBegin, partitionEnd);

View File

@ -84,12 +84,14 @@ class QHostInfoResult : public QObject
QPointer<const QObject> receiver = nullptr;
QtPrivate::QSlotObjectBase *slotObj = nullptr;
const bool withContextObject = false;
public:
QHostInfoResult() = default;
QHostInfoResult(const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj) :
receiver(receiver),
slotObj(slotObj)
slotObj(slotObj),
withContextObject(slotObj && receiver)
{
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this,
&QObject::deleteLater);
@ -97,10 +99,15 @@ public:
moveToThread(receiver->thread());
}
void postResultsReady(const QHostInfo &info);
public Q_SLOTS:
inline void emitResultsReady(const QHostInfo &info)
{
if (slotObj) {
// we used to have a context object, but it's already destroyed
if (withContextObject && !receiver)
return;
QHostInfo copy = info;
void *args[2] = { nullptr, reinterpret_cast<void *>(&copy) };
slotObj->call(const_cast<QObject*>(receiver.data()), args);

View File

@ -882,8 +882,25 @@ static LoadedOpenSsl loadOpenSsl()
// macOS's /usr/lib/libssl.dylib, /usr/lib/libcrypto.dylib will be picked up in the third
// attempt, _after_ <bundle>/Contents/Frameworks has been searched.
// iOS does not ship a system libssl.dylib, libcrypto.dylib in the first place.
# if defined(Q_OS_ANDROID)
// OpenSSL 1.1.x must be suffixed otherwise it will use the system libcrypto.so libssl.so which on API-21 are OpenSSL 1.0 not 1.1
auto openSSLSuffix = [](const QByteArray &defaultSuffix = {}) {
auto suffix = qgetenv("ANDROID_OPENSSL_SUFFIX");
if (suffix.isEmpty())
return defaultSuffix;
return suffix;
};
# if QT_CONFIG(opensslv11)
static QString suffix = QString::fromLatin1(openSSLSuffix("_1_1"));
# else
static QString suffix = QString::fromLatin1(openSSLSuffix());
# endif
libssl->setFileNameAndVersion(QLatin1String("ssl") + suffix, -1);
libcrypto->setFileNameAndVersion(QLatin1String("crypto") + suffix, -1);
# else
libssl->setFileNameAndVersion(QLatin1String("ssl"), -1);
libcrypto->setFileNameAndVersion(QLatin1String("crypto"), -1);
# endif
if (libcrypto->load() && libssl->load()) {
// libssl.so.0 and libcrypto.so.0 found
return result;

View File

@ -49,7 +49,14 @@
QT_BEGIN_NAMESPACE
class QNSWindowBackingStore : public QRasterBackingStore
class QCocoaBackingStore : public QRasterBackingStore
{
protected:
QCocoaBackingStore(QWindow *window);
QCFType<CGColorSpaceRef> colorSpace() const;
};
class QNSWindowBackingStore : public QCocoaBackingStore
{
public:
QNSWindowBackingStore(QWindow *window);
@ -64,7 +71,7 @@ private:
void redrawRoundedBottomCorners(CGRect) const;
};
class QCALayerBackingStore : public QPlatformBackingStore
class QCALayerBackingStore : public QCocoaBackingStore
{
public:
QCALayerBackingStore(QWindow *window);

View File

@ -48,11 +48,24 @@
QT_BEGIN_NAMESPACE
QNSWindowBackingStore::QNSWindowBackingStore(QWindow *window)
QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
: QRasterBackingStore(window)
{
}
QCFType<CGColorSpaceRef> QCocoaBackingStore::colorSpace() const
{
NSView *view = static_cast<QCocoaWindow *>(window()->handle())->view();
return QCFType<CGColorSpaceRef>::constructFromGet(view.window.colorSpace.CGColorSpace);
}
// ----------------------------------------------------------------------------
QNSWindowBackingStore::QNSWindowBackingStore(QWindow *window)
: QCocoaBackingStore(window)
{
}
QNSWindowBackingStore::~QNSWindowBackingStore()
{
}
@ -175,11 +188,10 @@ void QNSWindowBackingStore::flush(QWindow *window, const QRegion &region, const
Q_ASSERT_X(graphicsContext, "QCocoaBackingStore",
"Focusing the view should give us a current graphics context");
// Prevent potentially costly color conversion by assigning the display color space
// to the backingstore image. This does not copy the underlying image data.
CGColorSpaceRef displayColorSpace = view.window.screen.colorSpace.CGColorSpace;
// Tag backingstore image with color space based on the window.
// Note: This does not copy the underlying image data.
QCFType<CGImageRef> cgImage = CGImageCreateCopyWithColorSpace(
QCFType<CGImageRef>(m_image.toCGImage()), displayColorSpace);
QCFType<CGImageRef>(m_image.toCGImage()), colorSpace());
// Create temporary image to use for blitting, without copying image data
NSImage *backingStoreImage = [[[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize] autorelease];
@ -293,7 +305,7 @@ void QNSWindowBackingStore::redrawRoundedBottomCorners(CGRect windowRect) const
// ----------------------------------------------------------------------------
QCALayerBackingStore::QCALayerBackingStore(QWindow *window)
: QPlatformBackingStore(window)
: QCocoaBackingStore(window)
{
qCDebug(lcQpaBackingStore) << "Creating QCALayerBackingStore for" << window;
m_buffers.resize(1);
@ -432,11 +444,7 @@ bool QCALayerBackingStore::recreateBackBufferIfNeeded()
<< "based on requested" << m_requestedSize << "and dpr =" << devicePixelRatio;
static auto pixelFormat = QImage::toPixelFormat(QImage::Format_ARGB32_Premultiplied);
NSView *view = static_cast<QCocoaWindow *>(window()->handle())->view();
auto colorSpace = QCFType<CGColorSpaceRef>::constructFromGet(view.window.screen.colorSpace.CGColorSpace);
m_buffers.back().reset(new GraphicsBuffer(requestedBufferSize, devicePixelRatio, pixelFormat, colorSpace));
m_buffers.back().reset(new GraphicsBuffer(requestedBufferSize, devicePixelRatio, pixelFormat, colorSpace()));
return true;
}

View File

@ -1648,6 +1648,9 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
[nsWindow setDepthLimit:NSWindowDepthTwentyfourBitRGB];
}
if (format().colorSpace() == QSurfaceFormat::sRGBColorSpace)
nsWindow.colorSpace = NSColorSpace.sRGBColorSpace;
return nsWindow;
}

View File

@ -1301,7 +1301,23 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, MSG msg,
|| code == Qt::Key_Control
|| code == Qt::Key_Meta
|| code == Qt::Key_Alt)) {
// Someone ate the key down event
// Workaround for QTBUG-77153:
// The Surface Pen eraser button generates Meta+F18/19/20 keystrokes,
// but when it is not touching the screen the Fn Down is eaten and only
// a Fn Up with the previous state as "not pressed" is generated, which
// would be ignored. We detect this case and synthesize the expected events.
if ((msg.lParam & 0x40000000) == 0 &&
Qt::KeyboardModifier(state) == Qt::NoModifier &&
((code == Qt::Key_F18) || (code == Qt::Key_F19) || (code == Qt::Key_F20))) {
QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyPress, code,
Qt::MetaModifier, scancode,
quint32(msg.wParam), MetaLeft);
QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyRelease, code,
Qt::NoModifier, scancode,
quint32(msg.wParam), 0);
result = true;
}
} else {
if (!code)
code = asciiToKeycode(rec->ascii ? char(rec->ascii) : char(msg.wParam), state);

View File

@ -43,6 +43,7 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QHash>
#include <QtCore/qfunctions_winrt.h>
#include <QtCore/private/qfsfileengine_p.h>
#include <wrl.h>
#include <windows.storage.h>
@ -196,7 +197,19 @@ bool QWinRTFileEngine::open(QIODevice::OpenMode openMode)
hr = QWinRTFunctions::await(op, d->stream.GetAddressOf());
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::OpenError, false);
d->openMode = openMode;
const ProcessOpenModeResult res = processOpenModeFlags(openMode);
if (!res.ok) {
setError(QFileDevice::OpenError, res.error);
return false;
}
d->openMode = res.openMode;
if (d->openMode & QIODevice::Truncate) {
if (!setSize(0)) {
close();
setError(QFileDevice::OpenError, QLatin1String("Could not truncate file"));
return false;
}
}
return SUCCEEDED(hr);
}
@ -257,6 +270,29 @@ qint64 QWinRTFileEngine::size() const
return qint64(size);
}
bool QWinRTFileEngine::setSize(qint64 size)
{
Q_D(QWinRTFileEngine);
if (!d->stream) {
setError(QFileDevice::ResizeError, QLatin1String("File must be open to be resized"));
return false;
}
if (size < 0) {
setError(QFileDevice::ResizeError, QLatin1String("File size cannot be negative"));
return false;
}
HRESULT hr = d->stream->put_Size(static_cast<quint64>(size));
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ResizeError, false);
if (!flush()) {
setError(QFileDevice::ResizeError, QLatin1String("Could not flush file"));
return false;
}
return true;
}
qint64 QWinRTFileEngine::pos() const
{
Q_D(const QWinRTFileEngine);

View File

@ -79,6 +79,7 @@ public:
bool close() override;
bool flush() override;
qint64 size() const override;
bool setSize(qint64 size) override;
qint64 pos() const override;
bool seek(qint64 pos) override;
bool remove() override;

View File

@ -5327,10 +5327,10 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
const CGRect barRect = [cell barRectFlipped:hasTicks];
if (drawBar) {
[cell drawBarInside:barRect flipped:!verticalFlip];
// This ain't HIG kosher: force unfilled bar look.
if (hasDoubleTicks)
slider.numberOfTickMarks = numberOfTickMarks;
[cell drawBarInside:barRect flipped:!verticalFlip];
}
if (hasTicks && drawTicks) {

View File

@ -6457,8 +6457,18 @@ void QWidget::setFocusProxy(QWidget * w)
}
}
QWidget *oldDeepestFocusProxy = d_func()->deepestFocusProxy();
if (!oldDeepestFocusProxy)
oldDeepestFocusProxy = this;
const bool changingAppFocusWidget = (QApplicationPrivate::focus_widget == oldDeepestFocusProxy);
d->createExtra();
d->extra->focus_proxy = w;
if (changingAppFocusWidget) {
QWidget *newDeepestFocusProxy = d_func()->deepestFocusProxy();
QApplicationPrivate::focus_widget = newDeepestFocusProxy ? newDeepestFocusProxy : this;
}
}

View File

@ -92,6 +92,7 @@ private slots:
void lookupIPv6();
void lookupConnectToFunctionPointer_data();
void lookupConnectToFunctionPointer();
void lookupConnectToFunctionPointerDeleted();
void lookupConnectToLambda_data();
void lookupConnectToLambda();
void reverseLookup_data();
@ -358,6 +359,17 @@ void tst_QHostInfo::lookupConnectToFunctionPointer()
QCOMPARE(tmp.join(' '), expected.join(' '));
}
void tst_QHostInfo::lookupConnectToFunctionPointerDeleted()
{
{
QObject contextObject;
QHostInfo::lookupHost("localhost", &contextObject, [](const QHostInfo){
QFAIL("This should never be called!");
});
}
QTestEventLoop::instance().enterLoop(3);
}
void tst_QHostInfo::lookupConnectToLambda_data()
{
lookupIPv4_data();
@ -464,7 +476,9 @@ void tst_QHostInfo::reverseLookup_data()
QTest::newRow("dns.google") << QString("8.8.8.8") << reverseLookupHelper("8.8.8.8") << 0 << false;
QTest::newRow("one.one.one.one") << QString("1.1.1.1") << reverseLookupHelper("1.1.1.1") << 0 << false;
QTest::newRow("bogus-name") << QString("1::2::3::4") << QStringList() << 1 << true;
QTest::newRow("dns.google IPv6") << QString("2001:4860:4860::8888") << reverseLookupHelper("2001:4860:4860::8888") << 0 << true;
QTest::newRow("cloudflare IPv6") << QString("2606:4700:4700::1111") << reverseLookupHelper("2606:4700:4700::1111") << 0 << true;
QTest::newRow("bogus-name IPv6") << QString("1::2::3::4") << QStringList() << 1 << true;
}
void tst_QHostInfo::reverseLookup()
@ -705,6 +719,7 @@ void tst_QHostInfo::cache()
void tst_QHostInfo::resultsReady(const QHostInfo &hi)
{
QVERIFY(QThread::currentThread() == thread());
lookupDone = true;
lookupResults = hi;
lookupsDoneCounter++;

View File

@ -182,6 +182,8 @@ private slots:
void tabOrderWithCompoundWidgets();
void tabOrderNoChange();
void tabOrderNoChange2();
void appFocusWidgetWithFocusProxyLater();
void appFocusWidgetWhenLosingFocusProxy();
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
void activation();
#endif
@ -2032,6 +2034,51 @@ void tst_QWidget::tabOrderNoChange2()
QCOMPARE(focusChainBackward, getFocusChain(&w, false));
}
void tst_QWidget::appFocusWidgetWithFocusProxyLater()
{
// Given a lineedit without a focus proxy
QWidget window;
window.setWindowTitle(QTest::currentTestFunction());
QLineEdit *lineEditFocusProxy = new QLineEdit(&window);
QLineEdit *lineEdit = new QLineEdit(&window);
lineEdit->setFocus();
window.show();
QApplication::setActiveWindow(&window);
QVERIFY(QTest::qWaitForWindowActive(&window));
QCOMPARE(QApplication::focusWidget(), lineEdit);
// When setting a focus proxy for the focus widget (like QWebEngineView does)
lineEdit->setFocusProxy(lineEditFocusProxy);
// Then the focus widget should be updated
QCOMPARE(QApplication::focusWidget(), lineEditFocusProxy);
// So that deleting the lineEdit and later the window, doesn't crash
delete lineEdit;
QCOMPARE(QApplication::focusWidget(), nullptr);
}
void tst_QWidget::appFocusWidgetWhenLosingFocusProxy()
{
// Given a lineedit with a focus proxy
QWidget window;
window.setWindowTitle(QTest::currentTestFunction());
QLineEdit *lineEditFocusProxy = new QLineEdit(&window);
QLineEdit *lineEdit = new QLineEdit(&window);
lineEdit->setFocusProxy(lineEditFocusProxy);
lineEdit->setFocus();
window.show();
QApplication::setActiveWindow(&window);
QVERIFY(QTest::qWaitForWindowActive(&window));
QCOMPARE(QApplication::focusWidget(), lineEditFocusProxy);
// When unsetting the focus proxy
lineEdit->setFocusProxy(nullptr);
// Then the application focus widget should be back to the lineedit
QCOMPARE(QApplication::focusWidget(), lineEdit);
}
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
void tst_QWidget::activation()
{