summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2019-07-30 13:47:36 +0200
committerLiang Qi <liang.qi@qt.io>2019-07-30 21:41:23 +0200
commit4aec85b6bb7c5138658610521c81f80e2f2c4d6f (patch)
treeabaef77d71fc098f3e1563e97fe94a3f88e2d2ee /src
parent130fd22d399624c863bbaad2f72d2213a48e9e13 (diff)
parent71ec1d6d79c16c46837dbd10f1cd2a53027a6682 (diff)
Merge "Merge remote-tracking branch 'origin/5.13' into dev"
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qfsfileengine.cpp45
-rw-r--r--src/corelib/io/qfsfileengine_p.h10
-rw-r--r--src/corelib/io/qresource.cpp6
-rw-r--r--src/network/access/qnetworkreplywasmimpl.cpp6
-rw-r--r--src/network/kernel/qhostinfo.cpp50
-rw-r--r--src/network/kernel/qhostinfo_p.h9
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp17
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.h11
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm30
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm3
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp18
-rw-r--r--src/plugins/platforms/winrt/qwinrtfileengine.cpp38
-rw-r--r--src/plugins/platforms/winrt/qwinrtfileengine.h1
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm2
-rw-r--r--src/widgets/kernel/qwidget.cpp10
15 files changed, 207 insertions, 49 deletions
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index 0db27f3e25..0d73839f8d 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -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);
}
diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h
index 0f416f4886..79593a3e1c 100644
--- a/src/corelib/io/qfsfileengine_p.h
+++ b/src/corelib/io/qfsfileengine_p.h
@@ -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
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index 747f153f48..11d117c990 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -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) {
diff --git a/src/network/access/qnetworkreplywasmimpl.cpp b/src/network/access/qnetworkreplywasmimpl.cpp
index ee91dc20b3..53784407d8 100644
--- a/src/network/access/qnetworkreplywasmimpl.cpp
+++ b/src/network/access/qnetworkreplywasmimpl.cpp
@@ -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())
diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp
index 0dbb2cefb1..487cac6d90 100644
--- a/src/network/kernel/qhostinfo.cpp
+++ b/src/network/kernel/qhostinfo.cpp
@@ -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);
diff --git a/src/network/kernel/qhostinfo_p.h b/src/network/kernel/qhostinfo_p.h
index ee052b86d3..9a4657234e 100644
--- a/src/network/kernel/qhostinfo_p.h
+++ b/src/network/kernel/qhostinfo_p.h
@@ -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);
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 869d6d5959..1fcfdf9f16 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -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;
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
index 2398e6351e..9be6814ae7 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.h
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h
@@ -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);
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index 01b4894324..6015257f4e 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -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;
}
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 26df604f1c..8f3c192745 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -1648,6 +1648,9 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
[nsWindow setDepthLimit:NSWindowDepthTwentyfourBitRGB];
}
+ if (format().colorSpace() == QSurfaceFormat::sRGBColorSpace)
+ nsWindow.colorSpace = NSColorSpace.sRGBColorSpace;
+
return nsWindow;
}
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 4b54051e0c..4f0f846749 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -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);
diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp
index 3014b30c38..962e4ab938 100644
--- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp
@@ -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);
diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.h b/src/plugins/platforms/winrt/qwinrtfileengine.h
index 4485917c9e..453565a95a 100644
--- a/src/plugins/platforms/winrt/qwinrtfileengine.h
+++ b/src/plugins/platforms/winrt/qwinrtfileengine.h
@@ -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;
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index c162cca048..968ca68619 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -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) {
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 209a4407a0..cdea0a570c 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -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;
+ }
}