summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qlogging.cpp4
-rw-r--r--src/corelib/global/qnamespace.qdoc2
-rw-r--r--src/corelib/global/qrandom.cpp19
-rw-r--r--src/corelib/plugin/qlibrary.cpp2
-rw-r--r--src/corelib/time/qhijricalendar.cpp1
-rw-r--r--src/corelib/time/qislamiccivilcalendar.cpp3
-rw-r--r--src/gui/image/qiconloader.cpp2
-rw-r--r--src/gui/kernel/qguiapplication.cpp12
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp2
-rw-r--r--src/gui/rhi/qrhi.cpp17
-rw-r--r--src/gui/rhi/qrhi_p.h2
-rw-r--r--src/gui/rhi/qrhi_p_p.h3
-rw-r--r--src/gui/rhi/qrhid3d11.cpp116
-rw-r--r--src/gui/rhi/qrhid3d11_p_p.h10
-rw-r--r--src/gui/rhi/qrhigles2.cpp63
-rw-r--r--src/gui/rhi/qrhigles2_p_p.h3
-rw-r--r--src/gui/rhi/qrhimetal.mm229
-rw-r--r--src/gui/rhi/qrhimetal_p_p.h1
-rw-r--r--src/gui/rhi/qrhinull.cpp5
-rw-r--r--src/gui/rhi/qrhinull_p_p.h1
-rw-r--r--src/gui/rhi/qrhivulkan.cpp5
-rw-r--r--src/gui/rhi/qrhivulkan_p_p.h1
-rw-r--r--src/gui/text/qtextdocument.cpp5
-rw-r--r--src/gui/text/qtextengine.cpp15
-rw-r--r--src/gui/text/qtextformat.cpp1
-rw-r--r--src/network/access/qhttp2configuration.cpp2
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp7
-rw-r--r--src/network/ssl/qsslsocket.cpp2
-rw-r--r--src/network/ssl/qsslsocket_schannel.cpp12
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.h3
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp12
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp12
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp26
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h2
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp10
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp18
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp18
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp18
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp38
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp21
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp39
-rw-r--r--src/widgets/kernel/qshortcut.cpp6
-rw-r--r--src/widgets/styles/qstyleoption.cpp2
-rw-r--r--src/widgets/widgets/qcombobox.cpp21
-rw-r--r--src/widgets/widgets/qmenu.cpp17
47 files changed, 528 insertions, 290 deletions
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index cebab1daef..17f2246082 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -1803,8 +1803,8 @@ static void qt_message_print(QtMsgType msgType, const QMessageLogContext &contex
#ifndef QT_BOOTSTRAPPED
Q_TRACE(qt_message_print, msgType, context.category, context.function, context.file, context.line, message);
- // qDebug, qWarning, ... macros do not check whether category is enabled
- if (isDefaultCategory(context.category)) {
+ // qDebug, qWarning, ... macros do not check whether category is enabledgc
+ if (msgType != QtFatalMsg && isDefaultCategory(context.category)) {
if (QLoggingCategory *defaultCategory = QLoggingCategory::defaultCategory()) {
if (!defaultCategory->isEnabled(msgType))
return;
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 886aedb4f3..cce88782e9 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -3287,7 +3287,7 @@
the application object is created, or by setting the QT_SCALE_FACTOR_ROUNDING_POLICY
environment variable.
- \sa QGuiApplication::setHighDdpiScaleFactorRoundingPolicy()
+ \sa QGuiApplication::setHighDpiScaleFactorRoundingPolicy()
\sa AA_EnableHighDpiScaling.
\omitvalue Unset
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
index 711eb8f4d5..e5b2399566 100644
--- a/src/corelib/global/qrandom.cpp
+++ b/src/corelib/global/qrandom.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 Intel Corporation.
+** Copyright (C) 2019 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -103,17 +103,22 @@ static QT_FUNCTION_TARGET(RDRND) qsizetype qt_random_cpu(void *buffer, qsizetype
{
unsigned *ptr = reinterpret_cast<unsigned *>(buffer);
unsigned *end = ptr + count;
+ int retries = 10;
while (ptr + sizeof(qregisteruint)/sizeof(*ptr) <= end) {
- if (_rdrandXX_step(reinterpret_cast<qregisteruint *>(ptr)) == 0)
+ if (_rdrandXX_step(reinterpret_cast<qregisteruint *>(ptr)))
+ ptr += sizeof(qregisteruint)/sizeof(*ptr);
+ else if (--retries == 0)
goto out;
- ptr += sizeof(qregisteruint)/sizeof(*ptr);
}
- if (sizeof(*ptr) != sizeof(qregisteruint) && ptr != end) {
- if (_rdrand32_step(ptr))
- goto out;
- ++ptr;
+ while (sizeof(*ptr) != sizeof(qregisteruint) && ptr != end) {
+ bool ok = _rdrand32_step(ptr);
+ if (!ok && --retries)
+ continue;
+ if (ok)
+ ++ptr;
+ break;
}
out:
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 1ace28c93f..98a198df43 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE
# define QLIBRARY_AS_DEBUG true
#endif
-#if defined(Q_OS_UNIX) || defined(Q_CC_MINGW)
+#if defined(Q_OS_UNIX)
// We don't use separate debug and release libs on UNIX, so we want
// to allow loading plugins, regardless of how they were built.
# define QT_NO_DEBUG_PLUGIN_CHECK
diff --git a/src/corelib/time/qhijricalendar.cpp b/src/corelib/time/qhijricalendar.cpp
index 9aabe46570..a0e6905e91 100644
--- a/src/corelib/time/qhijricalendar.cpp
+++ b/src/corelib/time/qhijricalendar.cpp
@@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE
/*!
\since 5.14
+ \internal
\class QHijriCalendar
\inmodule QtCore
diff --git a/src/corelib/time/qislamiccivilcalendar.cpp b/src/corelib/time/qislamiccivilcalendar.cpp
index 27c93f5c00..84562849cc 100644
--- a/src/corelib/time/qislamiccivilcalendar.cpp
+++ b/src/corelib/time/qislamiccivilcalendar.cpp
@@ -48,6 +48,7 @@ using namespace QRoundingDown;
/*!
\since 5.14
+ \internal
\class QIslamicCivilCalendar
\inmodule QtCore
@@ -67,7 +68,7 @@ using namespace QRoundingDown;
long. Its determination of leap years follows a 30-year cycle, in each of
which the years 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 and 29 are leap years.
- \sa QJijriCalendar, QCalendar
+ \sa QHijriCalendar, QCalendar
*/
QIslamicCivilCalendar::QIslamicCivilCalendar()
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index 1d0c93f26f..27c82bc09f 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -281,7 +281,7 @@ static quint32 icon_name_hash(const char *p)
QVector<const char *> QIconCacheGtkReader::lookup(const QStringRef &name)
{
QVector<const char *> ret;
- if (!isValid())
+ if (!isValid() || name.isEmpty())
return ret;
QByteArray nameUtf8 = name.toUtf8();
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index cb7a0b8ac9..47bd5727a9 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -2762,7 +2762,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
QWindow *window = e->window.data();
typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
QHash<QWindow *, StatesAndTouchPoints> windowsNeedingEvents;
- bool stationaryTouchPointChangedVelocity = false;
+ bool stationaryTouchPointChangedProperty = false;
for (int i = 0; i < e->points.count(); ++i) {
QTouchEvent::TouchPoint touchPoint = e->points.at(i);
@@ -2842,7 +2842,11 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
if (touchPoint.state() == Qt::TouchPointStationary) {
if (touchInfo.touchPoint.velocity() != touchPoint.velocity()) {
touchInfo.touchPoint.setVelocity(touchPoint.velocity());
- stationaryTouchPointChangedVelocity = true;
+ stationaryTouchPointChangedProperty = true;
+ }
+ if (!qFuzzyCompare(touchInfo.touchPoint.pressure(), touchPoint.pressure())) {
+ touchInfo.touchPoint.setPressure(touchPoint.pressure());
+ stationaryTouchPointChangedProperty = true;
}
} else {
touchInfo.touchPoint = touchPoint;
@@ -2883,7 +2887,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
break;
case Qt::TouchPointStationary:
// don't send the event if nothing changed
- if (!stationaryTouchPointChangedVelocity)
+ if (!stationaryTouchPointChangedProperty)
continue;
Q_FALLTHROUGH();
default:
@@ -3501,7 +3505,7 @@ Qt::ApplicationState QGuiApplication::applicationState()
\since 5.14
Sets the high-DPI scale factor rounding policy for the application. The
- policy decides how non-integer scale factors (such as Windows 150%) are
+ \a policy decides how non-integer scale factors (such as Windows 150%) are
handled, for applications that have AA_EnableHighDpiScaling enabled.
The two principal options are whether fractional scale factors should
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index ec4feeba8b..dcbae4f5c0 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -538,7 +538,7 @@ void QHighDpiScaling::updateHighDpiScaling()
++i;
}
}
- m_active = m_globalScalingActive || m_usePixelDensity;
+ m_active = m_globalScalingActive || m_screenFactorSet || m_usePixelDensity;
}
/*
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index 4414b61d55..88d2f73541 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -5020,6 +5020,23 @@ QRhiProfiler *QRhi::profiler()
}
/*!
+ Attempts to release resources in the backend's caches. This can include both
+ CPU and GPU resources. Only memory and resources that can be recreated
+ automatically are in scope. As an example, if the backend's
+ QRhiGraphicsPipeline implementation maintains a cache of shader compilation
+ results, calling this function leads to emptying that cache, thus
+ potentially freeing up memory and graphics resources.
+
+ Calling this function makes sense in resource constrained environments,
+ where at a certain point there is a need to ensure minimal resource usage,
+ at the expense of performance.
+ */
+void QRhi::releaseCachedResources()
+{
+ d->releaseCachedResources();
+}
+
+/*!
\return a new graphics pipeline resource.
\sa QRhiResource::release()
diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h
index 2d36c19e99..928d1f8fa7 100644
--- a/src/gui/rhi/qrhi_p.h
+++ b/src/gui/rhi/qrhi_p.h
@@ -1420,6 +1420,8 @@ public:
static const int MAX_LAYERS = 6; // cubemaps only
static const int MAX_LEVELS = 16; // a width and/or height of 65536 should be enough for everyone
+ void releaseCachedResources();
+
protected:
QRhi();
diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h
index 0914cf268b..b69757ae6d 100644
--- a/src/gui/rhi/qrhi_p_p.h
+++ b/src/gui/rhi/qrhi_p_p.h
@@ -157,6 +157,7 @@ public:
virtual const QRhiNativeHandles *nativeHandles() = 0;
virtual void sendVMemStatsToProfiler() = 0;
virtual void makeThreadLocalNativeContextCurrent() = 0;
+ virtual void releaseCachedResources() = 0;
bool isCompressedFormat(QRhiTexture::Format format) const;
void compressedFormatInfo(QRhiTexture::Format format, const QSize &size,
@@ -205,6 +206,8 @@ public:
QRhi *q;
+ static const int MAX_SHADER_CACHE_ENTRIES = 128;
+
protected:
bool debugMarkers = false;
int currentFrameSlot = 0; // for vk, mtl, and similar. unused by gl and d3d11.
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index 9e8533be23..93eadc047d 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -267,10 +267,20 @@ bool QRhiD3D11::create(QRhi::Flags flags)
return true;
}
+void QRhiD3D11::clearShaderCache()
+{
+ for (Shader &s : m_shaderCache)
+ s.s->Release();
+
+ m_shaderCache.clear();
+}
+
void QRhiD3D11::destroy()
{
finishActiveReadbacks();
+ clearShaderCache();
+
if (annotations) {
annotations->Release();
annotations = nullptr;
@@ -461,6 +471,11 @@ void QRhiD3D11::makeThreadLocalNativeContextCurrent()
// nothing to do here
}
+void QRhiD3D11::releaseCachedResources()
+{
+ clearShaderCache();
+}
+
QRhiRenderBuffer *QRhiD3D11::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
int sampleCount, QRhiRenderBuffer::Flags flags)
{
@@ -3408,30 +3423,57 @@ bool QD3D11GraphicsPipeline::build()
QByteArray vsByteCode;
for (const QRhiShaderStage &shaderStage : qAsConst(m_shaderStages)) {
- QString error;
- QByteArray bytecode = compileHlslShaderSource(shaderStage.shader(), shaderStage.shaderVariant(), &error);
- if (bytecode.isEmpty()) {
- qWarning("HLSL shader compilation failed: %s", qPrintable(error));
- return false;
- }
- switch (shaderStage.type()) {
- case QRhiShaderStage::Vertex:
- hr = rhiD->dev->CreateVertexShader(bytecode.constData(), bytecode.size(), nullptr, &vs);
- if (FAILED(hr)) {
- qWarning("Failed to create vertex shader: %s", qPrintable(comErrorMessage(hr)));
- return false;
+ auto cacheIt = rhiD->m_shaderCache.constFind(shaderStage);
+ if (cacheIt != rhiD->m_shaderCache.constEnd()) {
+ switch (shaderStage.type()) {
+ case QRhiShaderStage::Vertex:
+ vs = static_cast<ID3D11VertexShader *>(cacheIt->s);
+ vs->AddRef();
+ vsByteCode = cacheIt->bytecode;
+ break;
+ case QRhiShaderStage::Fragment:
+ fs = static_cast<ID3D11PixelShader *>(cacheIt->s);
+ fs->AddRef();
+ break;
+ default:
+ break;
}
- vsByteCode = bytecode;
- break;
- case QRhiShaderStage::Fragment:
- hr = rhiD->dev->CreatePixelShader(bytecode.constData(), bytecode.size(), nullptr, &fs);
- if (FAILED(hr)) {
- qWarning("Failed to create pixel shader: %s", qPrintable(comErrorMessage(hr)));
+ } else {
+ QString error;
+ const QByteArray bytecode = compileHlslShaderSource(shaderStage.shader(), shaderStage.shaderVariant(), &error);
+ if (bytecode.isEmpty()) {
+ qWarning("HLSL shader compilation failed: %s", qPrintable(error));
return false;
}
- break;
- default:
- break;
+
+ if (rhiD->m_shaderCache.count() >= QRhiD3D11::MAX_SHADER_CACHE_ENTRIES) {
+ // Use the simplest strategy: too many cached shaders -> drop them all.
+ rhiD->clearShaderCache();
+ }
+
+ switch (shaderStage.type()) {
+ case QRhiShaderStage::Vertex:
+ hr = rhiD->dev->CreateVertexShader(bytecode.constData(), bytecode.size(), nullptr, &vs);
+ if (FAILED(hr)) {
+ qWarning("Failed to create vertex shader: %s", qPrintable(comErrorMessage(hr)));
+ return false;
+ }
+ vsByteCode = bytecode;
+ rhiD->m_shaderCache.insert(shaderStage, QRhiD3D11::Shader(vs, bytecode));
+ vs->AddRef();
+ break;
+ case QRhiShaderStage::Fragment:
+ hr = rhiD->dev->CreatePixelShader(bytecode.constData(), bytecode.size(), nullptr, &fs);
+ if (FAILED(hr)) {
+ qWarning("Failed to create pixel shader: %s", qPrintable(comErrorMessage(hr)));
+ return false;
+ }
+ rhiD->m_shaderCache.insert(shaderStage, QRhiD3D11::Shader(fs, bytecode));
+ fs->AddRef();
+ break;
+ default:
+ break;
+ }
}
}
@@ -3501,19 +3543,31 @@ bool QD3D11ComputePipeline::build()
QRHI_RES_RHI(QRhiD3D11);
- QString error;
- QByteArray bytecode = compileHlslShaderSource(m_shaderStage.shader(), m_shaderStage.shaderVariant(), &error);
- if (bytecode.isEmpty()) {
- qWarning("HLSL compute shader compilation failed: %s", qPrintable(error));
- return false;
- }
+ auto cacheIt = rhiD->m_shaderCache.constFind(m_shaderStage);
+ if (cacheIt != rhiD->m_shaderCache.constEnd()) {
+ cs = static_cast<ID3D11ComputeShader *>(cacheIt->s);
+ } else {
+ QString error;
+ const QByteArray bytecode = compileHlslShaderSource(m_shaderStage.shader(), m_shaderStage.shaderVariant(), &error);
+ if (bytecode.isEmpty()) {
+ qWarning("HLSL compute shader compilation failed: %s", qPrintable(error));
+ return false;
+ }
- HRESULT hr = rhiD->dev->CreateComputeShader(bytecode.constData(), bytecode.size(), nullptr, &cs);
- if (FAILED(hr)) {
- qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
- return false;
+ HRESULT hr = rhiD->dev->CreateComputeShader(bytecode.constData(), bytecode.size(), nullptr, &cs);
+ if (FAILED(hr)) {
+ qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
+ return false;
+ }
+
+ if (rhiD->m_shaderCache.count() >= QRhiD3D11::MAX_SHADER_CACHE_ENTRIES)
+ rhiD->clearShaderCache();
+
+ rhiD->m_shaderCache.insert(m_shaderStage, QRhiD3D11::Shader(cs, bytecode));
}
+ cs->AddRef();
+
generation += 1;
rhiD->registerResource(this);
return true;
diff --git a/src/gui/rhi/qrhid3d11_p_p.h b/src/gui/rhi/qrhid3d11_p_p.h
index 582146315d..cd44519aaa 100644
--- a/src/gui/rhi/qrhid3d11_p_p.h
+++ b/src/gui/rhi/qrhid3d11_p_p.h
@@ -632,6 +632,7 @@ public:
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
void makeThreadLocalNativeContextCurrent() override;
+ void releaseCachedResources() override;
void enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD,
int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc);
@@ -646,6 +647,7 @@ public:
DXGI_SAMPLE_DESC effectiveSampleCount(int sampleCount) const;
void finishActiveReadbacks();
void reportLiveObjects(ID3D11Device *device);
+ void clearShaderCache();
bool debugLayer = false;
bool importedDevice = false;
@@ -684,6 +686,14 @@ public:
QRhiTexture::Format format;
};
QVector<ActiveReadback> activeReadbacks;
+
+ struct Shader {
+ Shader() = default;
+ Shader(IUnknown *s, const QByteArray &bytecode) : s(s), bytecode(bytecode) { }
+ IUnknown *s;
+ QByteArray bytecode;
+ };
+ QHash<QRhiShaderStage, Shader> m_shaderCache;
};
Q_DECLARE_TYPEINFO(QRhiD3D11::ActiveReadback, Q_MOVABLE_TYPE);
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index f4e711e33e..9ad591a17a 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -502,6 +502,10 @@ void QRhiGles2::destroy()
ensureContext();
executeDeferredReleases();
+ for (uint shader : m_shaderCache)
+ f->glDeleteShader(shader);
+ m_shaderCache.clear();
+
if (!importedContext) {
delete ctx;
ctx = nullptr;
@@ -757,6 +761,17 @@ void QRhiGles2::makeThreadLocalNativeContextCurrent()
ensureContext();
}
+void QRhiGles2::releaseCachedResources()
+{
+ if (!ensureContext())
+ return;
+
+ for (uint shader : m_shaderCache)
+ f->glDeleteShader(shader);
+
+ m_shaderCache.clear();
+}
+
QRhiRenderBuffer *QRhiGles2::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
int sampleCount, QRhiRenderBuffer::Flags flags)
{
@@ -2673,7 +2688,6 @@ static inline GLenum toGlShaderType(QRhiShaderStage::Type type)
bool QRhiGles2::compileShader(GLuint program, const QRhiShaderStage &shaderStage,
QShaderDescription *desc, int *glslVersionUsed)
{
- GLuint shader = f->glCreateShader(toGlShaderType(shaderStage.type()));
const QShader bakedShader = shaderStage.shader();
QVector<int> versionsToTry;
QByteArray source;
@@ -2733,27 +2747,40 @@ bool QRhiGles2::compileShader(GLuint program, const QRhiShaderStage &shaderStage
return false;
}
- const char *srcStr = source.constData();
- const GLint srcLength = source.count();
- f->glShaderSource(shader, 1, &srcStr, &srcLength);
- f->glCompileShader(shader);
- GLint compiled = 0;
- f->glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
- if (!compiled) {
- GLint infoLogLength = 0;
- f->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
- QByteArray log;
- if (infoLogLength > 1) {
- GLsizei length = 0;
- log.resize(infoLogLength);
- f->glGetShaderInfoLog(shader, infoLogLength, &length, log.data());
+ GLuint shader;
+ auto cacheIt = m_shaderCache.constFind(shaderStage);
+ if (cacheIt != m_shaderCache.constEnd()) {
+ shader = *cacheIt;
+ } else {
+ shader = f->glCreateShader(toGlShaderType(shaderStage.type()));
+ const char *srcStr = source.constData();
+ const GLint srcLength = source.count();
+ f->glShaderSource(shader, 1, &srcStr, &srcLength);
+ f->glCompileShader(shader);
+ GLint compiled = 0;
+ f->glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled) {
+ GLint infoLogLength = 0;
+ f->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
+ QByteArray log;
+ if (infoLogLength > 1) {
+ GLsizei length = 0;
+ log.resize(infoLogLength);
+ f->glGetShaderInfoLog(shader, infoLogLength, &length, log.data());
+ }
+ qWarning("Failed to compile shader: %s\nSource was:\n%s", log.constData(), source.constData());
+ return false;
}
- qWarning("Failed to compile shader: %s\nSource was:\n%s", log.constData(), source.constData());
- return false;
+ if (m_shaderCache.count() >= MAX_SHADER_CACHE_ENTRIES) {
+ // Use the simplest strategy: too many cached shaders -> drop them all.
+ for (uint shader : m_shaderCache)
+ f->glDeleteShader(shader); // does not actually get released yet when attached to a not-yet-released program
+ m_shaderCache.clear();
+ }
+ m_shaderCache.insert(shaderStage, shader);
}
f->glAttachShader(program, shader);
- f->glDeleteShader(shader);
*desc = bakedShader.description();
return true;
diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h
index 6da529be92..877eb88d27 100644
--- a/src/gui/rhi/qrhigles2_p_p.h
+++ b/src/gui/rhi/qrhigles2_p_p.h
@@ -665,6 +665,7 @@ public:
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
void makeThreadLocalNativeContextCurrent() override;
+ void releaseCachedResources() override;
bool ensureContext(QSurface *surface = nullptr) const;
void executeDeferredReleases();
@@ -804,6 +805,8 @@ public:
bool active = false;
QGles2CommandBuffer cbWrapper;
} ofr;
+
+ QHash<QRhiShaderStage, uint> m_shaderCache;
};
Q_DECLARE_TYPEINFO(QRhiGles2::DeferredReleaseEntry, Q_MOVABLE_TYPE);
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index dfa79edb00..a14ffa7173 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -138,6 +138,20 @@ QT_BEGIN_NAMESPACE
\l{QRhiCommandBuffer::endPass()}.
*/
+struct QMetalShader
+{
+ id<MTLLibrary> lib = nil;
+ id<MTLFunction> func = nil;
+ std::array<uint, 3> localSize;
+
+ void release() {
+ [lib release];
+ lib = nil;
+ [func release];
+ func = nil;
+ }
+};
+
struct QRhiMetalData
{
QRhiMetalData(QRhiImplementation *rhi) : ofr(rhi) { }
@@ -206,6 +220,8 @@ struct QRhiMetalData
API_AVAILABLE(macos(10.13), ios(11.0)) id<MTLCaptureScope> captureScope = nil;
static const int TEXBUF_ALIGN = 256; // probably not accurate
+
+ QHash<QRhiShaderStage, QMetalShader> shaderCache;
};
Q_DECLARE_TYPEINFO(QRhiMetalData::DeferredReleaseEntry, Q_MOVABLE_TYPE);
@@ -289,17 +305,14 @@ struct QMetalGraphicsPipelineData
MTLPrimitiveType primitiveType;
MTLWinding winding;
MTLCullMode cullMode;
- id<MTLLibrary> vsLib = nil;
- id<MTLFunction> vsFunc = nil;
- id<MTLLibrary> fsLib = nil;
- id<MTLFunction> fsFunc = nil;
+ QMetalShader vs;
+ QMetalShader fs;
};
struct QMetalComputePipelineData
{
id<MTLComputePipelineState> ps = nil;
- id<MTLLibrary> csLib = nil;
- id<MTLFunction> csFunc = nil;
+ QMetalShader cs;
MTLSize localSize;
};
@@ -404,6 +417,10 @@ void QRhiMetal::destroy()
executeDeferredReleases(true);
finishActiveReadbacks(true);
+ for (QMetalShader &s : d->shaderCache)
+ s.release();
+ d->shaderCache.clear();
+
if (@available(macOS 10.13, iOS 11.0, *)) {
[d->captureScope release];
d->captureScope = nil;
@@ -570,6 +587,14 @@ void QRhiMetal::makeThreadLocalNativeContextCurrent()
// nothing to do here
}
+void QRhiMetal::releaseCachedResources()
+{
+ for (QMetalShader &s : d->shaderCache)
+ s.release();
+
+ d->shaderCache.clear();
+}
+
QRhiRenderBuffer *QRhiMetal::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
int sampleCount, QRhiRenderBuffer::Flags flags)
{
@@ -2843,36 +2868,17 @@ void QMetalGraphicsPipeline::release()
{
QRHI_RES_RHI(QRhiMetal);
- if (!d->ps)
- return;
-
- if (d->ps) {
- [d->ps release];
- d->ps = nil;
- }
+ d->vs.release();
+ d->fs.release();
- if (d->ds) {
- [d->ds release];
- d->ds = nil;
- }
+ [d->ds release];
+ d->ds = nil;
- if (d->vsFunc) {
- [d->vsFunc release];
- d->vsFunc = nil;
- }
- if (d->vsLib) {
- [d->vsLib release];
- d->vsLib = nil;
- }
+ if (!d->ps)
+ return;
- if (d->fsFunc) {
- [d->fsFunc release];
- d->fsFunc = nil;
- }
- if (d->fsLib) {
- [d->fsLib release];
- d->fsLib = nil;
- }
+ [d->ps release];
+ d->ps = nil;
rhiD->unregisterResource(this);
}
@@ -3159,34 +3165,66 @@ bool QMetalGraphicsPipeline::build()
// buffers not just the resource binding layout) so leave it at the default
for (const QRhiShaderStage &shaderStage : qAsConst(m_shaderStages)) {
- QString error;
- QByteArray entryPoint;
- id<MTLLibrary> lib = rhiD->d->createMetalLib(shaderStage.shader(), shaderStage.shaderVariant(), &error, &entryPoint);
- if (!lib) {
- qWarning("MSL shader compilation failed: %s", qPrintable(error));
- return false;
- }
- id<MTLFunction> func = rhiD->d->createMSLShaderFunction(lib, entryPoint);
- if (!func) {
- qWarning("MSL function for entry point %s not found", entryPoint.constData());
- [lib release];
- return false;
- }
- switch (shaderStage.type()) {
- case QRhiShaderStage::Vertex:
- rpDesc.vertexFunction = func;
- d->vsLib = lib;
- d->vsFunc = func;
- break;
- case QRhiShaderStage::Fragment:
- rpDesc.fragmentFunction = func;
- d->fsLib = lib;
- d->fsFunc = func;
- break;
- default:
- [func release];
- [lib release];
- break;
+ auto cacheIt = rhiD->d->shaderCache.constFind(shaderStage);
+ if (cacheIt != rhiD->d->shaderCache.constEnd()) {
+ switch (shaderStage.type()) {
+ case QRhiShaderStage::Vertex:
+ d->vs = *cacheIt;
+ [d->vs.lib retain];
+ [d->vs.func retain];
+ rpDesc.vertexFunction = d->vs.func;
+ break;
+ case QRhiShaderStage::Fragment:
+ d->fs = *cacheIt;
+ [d->fs.lib retain];
+ [d->fs.func retain];
+ rpDesc.fragmentFunction = d->fs.func;
+ break;
+ default:
+ break;
+ }
+ } else {
+ QString error;
+ QByteArray entryPoint;
+ id<MTLLibrary> lib = rhiD->d->createMetalLib(shaderStage.shader(), shaderStage.shaderVariant(), &error, &entryPoint);
+ if (!lib) {
+ qWarning("MSL shader compilation failed: %s", qPrintable(error));
+ return false;
+ }
+ id<MTLFunction> func = rhiD->d->createMSLShaderFunction(lib, entryPoint);
+ if (!func) {
+ qWarning("MSL function for entry point %s not found", entryPoint.constData());
+ [lib release];
+ return false;
+ }
+ if (rhiD->d->shaderCache.count() >= QRhiMetal::MAX_SHADER_CACHE_ENTRIES) {
+ // Use the simplest strategy: too many cached shaders -> drop them all.
+ for (QMetalShader &s : rhiD->d->shaderCache)
+ s.release();
+ rhiD->d->shaderCache.clear();
+ }
+ switch (shaderStage.type()) {
+ case QRhiShaderStage::Vertex:
+ d->vs.lib = lib;
+ d->vs.func = func;
+ rhiD->d->shaderCache.insert(shaderStage, d->vs);
+ [d->vs.lib retain];
+ [d->vs.func retain];
+ rpDesc.vertexFunction = func;
+ break;
+ case QRhiShaderStage::Fragment:
+ d->fs.lib = lib;
+ d->fs.func = func;
+ rhiD->d->shaderCache.insert(shaderStage, d->fs);
+ [d->fs.lib retain];
+ [d->fs.func retain];
+ rpDesc.fragmentFunction = func;
+ break;
+ default:
+ [func release];
+ [lib release];
+ break;
+ }
}
}
@@ -3286,22 +3324,13 @@ void QMetalComputePipeline::release()
{
QRHI_RES_RHI(QRhiMetal);
- if (d->csFunc) {
- [d->csFunc release];
- d->csFunc = nil;
- }
- if (d->csLib) {
- [d->csLib release];
- d->csLib = nil;
- }
+ d->cs.release();
if (!d->ps)
return;
- if (d->ps) {
- [d->ps release];
- d->ps = nil;
- }
+ [d->ps release];
+ d->ps = nil;
rhiD->unregisterResource(this);
}
@@ -3313,28 +3342,44 @@ bool QMetalComputePipeline::build()
QRHI_RES_RHI(QRhiMetal);
- const QShader shader = m_shaderStage.shader();
- QString error;
- QByteArray entryPoint;
- id<MTLLibrary> lib = rhiD->d->createMetalLib(shader, m_shaderStage.shaderVariant(),
- &error, &entryPoint);
- if (!lib) {
- qWarning("MSL shader compilation failed: %s", qPrintable(error));
- return false;
- }
- id<MTLFunction> func = rhiD->d->createMSLShaderFunction(lib, entryPoint);
- if (!func) {
- qWarning("MSL function for entry point %s not found", entryPoint.constData());
- [lib release];
- return false;
+ auto cacheIt = rhiD->d->shaderCache.constFind(m_shaderStage);
+ if (cacheIt != rhiD->d->shaderCache.constEnd()) {
+ d->cs = *cacheIt;
+ } else {
+ const QShader shader = m_shaderStage.shader();
+ QString error;
+ QByteArray entryPoint;
+ id<MTLLibrary> lib = rhiD->d->createMetalLib(shader, m_shaderStage.shaderVariant(),
+ &error, &entryPoint);
+ if (!lib) {
+ qWarning("MSL shader compilation failed: %s", qPrintable(error));
+ return false;
+ }
+ id<MTLFunction> func = rhiD->d->createMSLShaderFunction(lib, entryPoint);
+ if (!func) {
+ qWarning("MSL function for entry point %s not found", entryPoint.constData());
+ [lib release];
+ return false;
+ }
+ d->cs.lib = lib;
+ d->cs.func = func;
+ d->cs.localSize = shader.description().computeShaderLocalSize();
+
+ if (rhiD->d->shaderCache.count() >= QRhiMetal::MAX_SHADER_CACHE_ENTRIES) {
+ for (QMetalShader &s : rhiD->d->shaderCache)
+ s.release();
+ rhiD->d->shaderCache.clear();
+ }
+ rhiD->d->shaderCache.insert(m_shaderStage, d->cs);
}
- d->csLib = lib;
- d->csFunc = func;
- std::array<uint, 3> localSize = shader.description().computeShaderLocalSize();
- d->localSize = MTLSizeMake(localSize[0], localSize[1], localSize[2]);
+
+ [d->cs.lib retain];
+ [d->cs.func retain];
+
+ d->localSize = MTLSizeMake(d->cs.localSize[0], d->cs.localSize[1], d->cs.localSize[2]);
NSError *err = nil;
- d->ps = [rhiD->d->dev newComputePipelineStateWithFunction: d->csFunc error: &err];
+ d->ps = [rhiD->d->dev newComputePipelineStateWithFunction: d->cs.func error: &err];
if (!d->ps) {
const QString msg = QString::fromNSString(err.localizedDescription);
qWarning("Failed to create render pipeline state: %s", qPrintable(msg));
diff --git a/src/gui/rhi/qrhimetal_p_p.h b/src/gui/rhi/qrhimetal_p_p.h
index c448865f4d..01b0bf4f56 100644
--- a/src/gui/rhi/qrhimetal_p_p.h
+++ b/src/gui/rhi/qrhimetal_p_p.h
@@ -417,6 +417,7 @@ public:
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
void makeThreadLocalNativeContextCurrent() override;
+ void releaseCachedResources() override;
void executeDeferredReleases(bool forced = false);
void finishActiveReadbacks(bool forced = false);
diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp
index dff6e05268..29a3968bfc 100644
--- a/src/gui/rhi/qrhinull.cpp
+++ b/src/gui/rhi/qrhinull.cpp
@@ -174,6 +174,11 @@ void QRhiNull::makeThreadLocalNativeContextCurrent()
// nothing to do here
}
+void QRhiNull::releaseCachedResources()
+{
+ // nothing to do here
+}
+
QRhiRenderBuffer *QRhiNull::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
int sampleCount, QRhiRenderBuffer::Flags flags)
{
diff --git a/src/gui/rhi/qrhinull_p_p.h b/src/gui/rhi/qrhinull_p_p.h
index bdf0d59724..b43f830d5e 100644
--- a/src/gui/rhi/qrhinull_p_p.h
+++ b/src/gui/rhi/qrhinull_p_p.h
@@ -283,6 +283,7 @@ public:
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
void makeThreadLocalNativeContextCurrent() override;
+ void releaseCachedResources() override;
QRhiNullNativeHandles nativeHandlesStruct;
QRhiSwapChain *currentSwapChain = nullptr;
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index dfc85fb853..4f550c6a90 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -3744,6 +3744,11 @@ void QRhiVulkan::makeThreadLocalNativeContextCurrent()
// nothing to do here
}
+void QRhiVulkan::releaseCachedResources()
+{
+ // nothing to do here
+}
+
QRhiRenderBuffer *QRhiVulkan::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
int sampleCount, QRhiRenderBuffer::Flags flags)
{
diff --git a/src/gui/rhi/qrhivulkan_p_p.h b/src/gui/rhi/qrhivulkan_p_p.h
index 962a1b8eb7..23cc80b814 100644
--- a/src/gui/rhi/qrhivulkan_p_p.h
+++ b/src/gui/rhi/qrhivulkan_p_p.h
@@ -712,6 +712,7 @@ public:
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
void makeThreadLocalNativeContextCurrent() override;
+ void releaseCachedResources() override;
VkResult createDescriptorPool(VkDescriptorPool *pool);
bool allocateDescriptorSet(VkDescriptorSetAllocateInfo *allocInfo, VkDescriptorSet *result, int *resultPoolIndex);
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index c80617f929..3652a180a8 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -2067,8 +2067,9 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
\enum QTextDocument::ResourceType
This enum describes the types of resources that can be loaded by
- QTextDocument's loadResource() function.
+ QTextDocument's loadResource() function or by QTextBrowser::setSource().
+ \value UnknownResource No resource is loaded, or the resource type is not known.
\value HtmlResource The resource contains HTML.
\value ImageResource The resource contains image data.
Currently supported data types are QVariant::Pixmap and
@@ -2082,7 +2083,7 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
\value UserResource The first available value for user defined
resource types.
- \sa loadResource()
+ \sa loadResource(), QTextBrowser::sourceType()
*/
/*!
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index c267ade0c2..b37353bf2c 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -399,6 +399,7 @@ struct QBidiAlgorithm {
analysis[i].bidiDirection = (level & 1) ? QChar::DirR : QChar::DirL;
runHasContent = true;
lastRunWithContent = -1;
+ ++isolatePairPosition;
}
int runBeforeIsolate = runs.size();
ushort newLevel = isRtl ? ((stack.top().level + 1) | 1) : ((stack.top().level + 2) & ~1);
@@ -440,21 +441,19 @@ struct QBidiAlgorithm {
doEmbed(true, true, false);
break;
case QChar::DirLRI:
- Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i);
doEmbed(false, false, true);
- ++isolatePairPosition;
break;
case QChar::DirRLI:
- Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i);
doEmbed(true, false, true);
- ++isolatePairPosition;
break;
case QChar::DirFSI: {
- const auto &pair = isolatePairs.at(isolatePairPosition);
- Q_ASSERT(pair.start == i);
- bool isRtl = QStringView(text + pair.start + 1, pair.end - pair.start - 1).isRightToLeft();
+ bool isRtl = false;
+ if (isolatePairPosition < isolatePairs.size()) {
+ const auto &pair = isolatePairs.at(isolatePairPosition);
+ Q_ASSERT(pair.start == i);
+ isRtl = QStringView(text + pair.start + 1, pair.end - pair.start - 1).isRightToLeft();
+ }
doEmbed(isRtl, false, true);
- ++isolatePairPosition;
break;
}
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index 47a38db3ad..e3bd49a15e 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -650,6 +650,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
\value TableColumns
\value TableColumnWidthConstraints
\value TableHeaderRowCount
+ \value TableBorderCollapse Specifies the \l QTextTableFormat::borderCollapse property.
Table cell properties
diff --git a/src/network/access/qhttp2configuration.cpp b/src/network/access/qhttp2configuration.cpp
index a32bccfd09..bd4318d4e9 100644
--- a/src/network/access/qhttp2configuration.cpp
+++ b/src/network/access/qhttp2configuration.cpp
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QHttp2Configuration
- \brief The QHttp2Configuration class controls HTTP/2 parameters and settings
+ \brief The QHttp2Configuration class controls HTTP/2 parameters and settings.
\since 5.14
\reentrant
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 6ff2c47eb4..c5bc3f509f 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -854,8 +854,11 @@ void QHttpNetworkConnectionChannel::_q_disconnected()
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
}
state = QHttpNetworkConnectionChannel::IdleState;
-
- requeueCurrentlyPipelinedRequests();
+ if (alreadyPipelinedRequests.length()) {
+ // If nothing was in a pipeline, no need in calling
+ // _q_startNextRequest (which it does):
+ requeueCurrentlyPipelinedRequests();
+ }
pendingEncrypt = false;
}
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index ca6c58117d..e302aa1761 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1512,7 +1512,7 @@ bool QSslSocket::addDefaultCaCertificates(const QString &path, QSsl::EncodingFor
SSL socket's CA certificate database is initialized to the default
CA certificate database.
- \sa QSslConfiguration::defaultCaCertificates(), addCaCertificates()
+ \sa QSslConfiguration::caCertificates(), addCaCertificates()
*/
void QSslSocket::addDefaultCaCertificate(const QSslCertificate &certificate)
{
diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp
index 1db26ee9a1..978571e61d 100644
--- a/src/network/ssl/qsslsocket_schannel.cpp
+++ b/src/network/ssl/qsslsocket_schannel.cpp
@@ -1360,6 +1360,18 @@ void QSslSocketBackendPrivate::transmit()
#endif
schannelState = SchannelState::Renegotiate;
renegotiating = true;
+
+ if (dataBuffer[3].BufferType == SECBUFFER_EXTRA) {
+ // https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel
+ // dataBuffer[3].cbBuffer indicates the amount of bytes _NOT_ processed,
+ // the rest need to be stored.
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << "We've got excess data, moving it to the intermediate buffer:"
+ << dataBuffer[3].cbBuffer << "bytes";
+#endif
+ intermediateBuffer = ciphertext.right(int(dataBuffer[3].cbBuffer));
+ }
+
// We need to call 'continueHandshake' or else there's no guarantee it ever gets called
continueHandshake();
break;
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
index 737d85d5c3..a6e5c9b5ab 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
+++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
@@ -535,7 +535,7 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
m_currentData.state = Qt::TouchPointReleased;
if (m_typeB)
m_contacts[m_currentSlot].maj = m_currentData.maj;
- } else if (data->code == ABS_PRESSURE) {
+ } else if (data->code == ABS_PRESSURE || data->code == ABS_MT_PRESSURE) {
m_currentData.pressure = qBound(hw_pressure_min, data->value, hw_pressure_max);
if (m_typeB || m_singleTouch)
m_contacts[m_currentSlot].pressure = m_currentData.pressure;
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 8cd09a34eb..df63adf558 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -42,6 +42,7 @@
#include "qwindowswindow.h"
#include "qwindowsintegration.h"
#include "qwindowscursor.h"
+#include "qwindowstheme.h"
#include <QtCore/qt_windows.h>
@@ -543,10 +544,13 @@ bool QWindowsScreenManager::handleScreenChanges()
// Look for changed monitors, add new ones
const WindowsScreenDataList newDataList = monitorData();
const bool lockScreen = newDataList.size() == 1 && (newDataList.front().flags & QWindowsScreenData::LockScreen);
+ bool primaryScreenChanged = false;
for (const QWindowsScreenData &newData : newDataList) {
const int existingIndex = indexOfMonitor(m_screens, newData.name);
if (existingIndex != -1) {
m_screens.at(existingIndex)->handleChanges(newData);
+ if (existingIndex == 0)
+ primaryScreenChanged = true;
} else {
auto *newScreen = new QWindowsScreen(newData);
m_screens.push_back(newScreen);
@@ -563,6 +567,8 @@ bool QWindowsScreenManager::handleScreenChanges()
removeScreen(i);
} // for existing screens
} // not lock screen
+ if (primaryScreenChanged)
+ QWindowsTheme::instance()->refreshFonts();
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h
index 4e24308445..07120230ce 100644
--- a/src/plugins/platforms/windows/qwindowstheme.h
+++ b/src/plugins/platforms/windows/qwindowstheme.h
@@ -85,6 +85,8 @@ public:
static bool useNativeMenus();
+ void refreshFonts();
+
static const char *name;
private:
@@ -92,7 +94,6 @@ private:
void clearPalettes();
void refreshPalettes();
void clearFonts();
- void refreshFonts();
void refreshIconPixmapSizes();
static QWindowsTheme *m_instance;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp
index 524000b618..355dbf7d20 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -105,19 +107,17 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaGridItemProvider::get_ContainingGrid(IIRawEle
*value = nullptr;
auto accid = id();
- auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
- auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+ auto elementId = std::make_shared<QAccessible::Id>(0);
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
if (QAccessibleInterface *table = tableCellInterface->table()) {
- **ptrElementId = idForAccessible(table);
- QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
+ *elementId = idForAccessible(table);
+ QWinRTUiaMetadataCache::instance()->load(*elementId);
}
}
}
- delete ptrElementId;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp
index e469991de2..3bd90f6850 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -104,21 +106,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaGridProvider::GetItem(INT32 row, INT32 column
*returnValue = nullptr;
auto accid = id();
- auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
- auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+ auto elementId = std::make_shared<QAccessible::Id>(0);
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, row, column, ptrElementId]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, row, column, elementId]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
if ((row >= 0) && (row < tableInterface->rowCount()) && (column >= 0) && (column < tableInterface->columnCount())) {
if (QAccessibleInterface *cell = tableInterface->cellAt(row, column)) {
- **ptrElementId = idForAccessible(cell);
- QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
+ *elementId = idForAccessible(cell);
+ QWinRTUiaMetadataCache::instance()->load(*elementId);
}
}
}
}
- delete ptrElementId;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp
index 6f3ad6dcd2..0b1db306bd 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp
@@ -64,6 +64,8 @@
#include <QtCore/qfunctions_winrt.h>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
using namespace QWinRTUiAutomation;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
@@ -179,7 +181,7 @@ HRESULT QWinRTUiaMainProvider::rawProviderForAccessibleId(QAccessible::Id elemen
}
// Returns an array of IIRawElementProviderSimple instances for a list of accessible interface ids.
-HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QList<QAccessible::Id> &elementIds,
+HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QVarLengthArray<QAccessible::Id> &elementIds,
UINT32 *returnValueSize,
IIRawElementProviderSimple ***returnValue)
{
@@ -190,7 +192,7 @@ HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QList<Q
QList<IIRawElementProviderSimple *> rawProviderList;
- for (auto elementId : qAsConst(elementIds)) {
+ for (auto elementId : elementIds) {
IIRawElementProviderSimple *rawProvider;
if (SUCCEEDED(rawProviderForAccessibleId(elementId, &rawProvider)))
rawProviderList.append(rawProvider);
@@ -515,10 +517,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat
*returnValue = nullptr;
auto accid = id();
- auto children = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrChildren = new QSharedPointer<QList<QAccessible::Id>>(children);
+ auto children = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrChildren]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, children]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
int childCount = accessible->childCount();
for (int i = 0; i < childCount; ++i) {
@@ -526,11 +527,10 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat
QAccessible::Id childId = idForAccessible(childAcc);
QWinRTUiaMetadataCache::instance()->load(childId);
if (!childAcc->state().invisible)
- (*ptrChildren)->append(childId);
+ children->append(childId);
}
}
}
- delete ptrChildren;
return S_OK;
}))) {
return E_FAIL;
@@ -538,7 +538,7 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat
ComPtr<IVector<AutomationPeer *>> peerVector = Make<QWinRTUiaPeerVector>();
- for (auto childId : qAsConst(*children)) {
+ for (auto childId : *children) {
if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(childId)) {
IAutomationPeer *peer;
if (SUCCEEDED(provider.CopyTo(&peer)))
@@ -750,10 +750,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetPeerFromPointCore(ABI::Windo
// Scale coordinates from High DPI screens?
auto accid = id();
- auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
- auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+ auto elementId = std::make_shared<QAccessible::Id>(0);
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId, point]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId, point]() {
// Controls can be embedded within grouping elements. By default returns the innermost control.
QAccessibleInterface *target = accessibleForId(accid);
while (QAccessibleInterface *tmpacc = target->childAt(point.X, point.Y)) {
@@ -761,9 +760,8 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetPeerFromPointCore(ABI::Windo
// For accessibility tools it may be better to return the text element instead of its subcomponents.
if (target->textInterface()) break;
}
- **ptrElementId = idForAccessible(target);
- QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
- delete ptrElementId;
+ *elementId = idForAccessible(target);
+ QWinRTUiaMetadataCache::instance()->load(*elementId);
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h
index 384a166cf7..23a6e56ae7 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h
@@ -69,7 +69,7 @@ public:
virtual ~QWinRTUiaMainProvider();
static QWinRTUiaMainProvider *providerForAccessibleId(QAccessible::Id id);
static HRESULT rawProviderForAccessibleId(QAccessible::Id elementId, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple **returnValue);
- static HRESULT rawProviderArrayForAccessibleIdList(const QList<QAccessible::Id> &elementIds, UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue);
+ static HRESULT rawProviderArrayForAccessibleIdList(const QVarLengthArray<QAccessible::Id> &elementIds, UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue);
static void notifyFocusChange(QAccessibleEvent *event);
static void notifyVisibilityChange(QAccessibleEvent *event);
static void notifyStateChange(QAccessibleStateChangeEvent *event);
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp
index 9bc88272ba..2cb5aa685c 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -94,21 +96,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionItemProvider::get_SelectionContainer
*value = nullptr;
auto accid = id();
- auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
- auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+ auto elementId = std::make_shared<QAccessible::Id>(0);
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
// Radio buttons do not require a container.
if (accessible->role() == QAccessible::ListItem) {
if (QAccessibleInterface *parent = accessible->parent()) {
if (parent->role() == QAccessible::List) {
- **ptrElementId = idForAccessible(parent);
+ *elementId = idForAccessible(parent);
}
}
}
}
- delete ptrElementId;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp
index 9e61a8df61..4d825351c8 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -89,10 +91,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::get_IsSelectionRequired(bo
*value = false;
auto accid = id();
- auto selectionRequired = QSharedPointer<bool>(new bool(false));
- auto ptrSelectionRequired = new QSharedPointer<bool>(selectionRequired);
+ auto selectionRequired = std::make_shared<bool>(false);
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrSelectionRequired]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, selectionRequired]() {
// Initially returns false if none are selected. After the first selection, it may be required.
bool anySelected = false;
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
@@ -105,9 +106,8 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::get_IsSelectionRequired(bo
}
}
}
- **ptrSelectionRequired = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
+ *selectionRequired = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
}
- delete ptrSelectionRequired;
return S_OK;
}))) {
return E_FAIL;
@@ -128,10 +128,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::GetSelection(UINT32 *retur
*returnValue = nullptr;
auto accid = id();
- auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+ auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
int childCount = accessible->childCount();
for (int i = 0; i < childCount; ++i) {
@@ -139,12 +138,11 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::GetSelection(UINT32 *retur
if (childAcc->state().selected) {
QAccessible::Id childId = idForAccessible(childAcc);
QWinRTUiaMetadataCache::instance()->load(childId);
- (*ptrElementIds)->append(childId);
+ elementIds->append(childId);
}
}
}
}
- delete ptrElementIds;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp
index 1af74a8b72..7cd953de87 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -79,21 +81,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableItemProvider::GetColumnHeaderItems(UINT3
*returnValue = nullptr;
auto accid = id();
- auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+ auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
QList<QAccessibleInterface *> headers = tableCellInterface->columnHeaderCells();
for (auto header : qAsConst(headers)) {
QAccessible::Id headerId = idForAccessible(header);
QWinRTUiaMetadataCache::instance()->load(headerId);
- (*ptrElementIds)->append(headerId);
+ elementIds->append(headerId);
}
}
}
- delete ptrElementIds;
return S_OK;
}))) {
return E_FAIL;
@@ -113,21 +113,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableItemProvider::GetRowHeaderItems(UINT32 *
*returnValue = nullptr;
auto accid = id();
- auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+ auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
QList<QAccessibleInterface *> headers = tableCellInterface->rowHeaderCells();
for (auto header : qAsConst(headers)) {
QAccessible::Id headerId = idForAccessible(header);
QWinRTUiaMetadataCache::instance()->load(headerId);
- (*ptrElementIds)->append(headerId);
+ elementIds->append(headerId);
}
}
}
- delete ptrElementIds;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp
index e71ade3c1f..d763b320b1 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -91,10 +93,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetColumnHeaders(UINT32 *retur
*returnValue = nullptr;
auto accid = id();
- auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+ auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
for (int i = 0; i < tableInterface->columnCount(); ++i) {
@@ -105,14 +106,13 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetColumnHeaders(UINT32 *retur
for (auto header : qAsConst(headers)) {
QAccessible::Id headerId = idForAccessible(header);
QWinRTUiaMetadataCache::instance()->load(headerId);
- (*ptrElementIds)->append(headerId);
+ elementIds->append(headerId);
}
}
}
}
}
}
- delete ptrElementIds;
return S_OK;
}))) {
return E_FAIL;
@@ -132,10 +132,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetRowHeaders(UINT32 *returnVa
*returnValue = nullptr;
auto accid = id();
- auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+ auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
for (int i = 0; i < tableInterface->rowCount(); ++i) {
@@ -146,14 +145,13 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetRowHeaders(UINT32 *returnVa
for (auto header : qAsConst(headers)) {
QAccessible::Id headerId = idForAccessible(header);
QWinRTUiaMetadataCache::instance()->load(headerId);
- (*ptrElementIds)->append(headerId);
+ elementIds->append(headerId);
}
}
}
}
}
}
- delete ptrElementIds;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp
index aa120377df..cd7420f360 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -104,26 +106,26 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetSelection(UINT32 *returnValu
*returnValueSize = 0;
*returnValue = nullptr;
+ struct Selection { int startOffset, endOffset; };
+
auto accid = id();
- auto selections = QSharedPointer<QList<QPair<int,int>>>(new QList<QPair<int,int>>);
- auto ptrSelections = new QSharedPointer<QList<QPair<int,int>>>(selections);
+ auto selections = std::make_shared<QVarLengthArray<Selection>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrSelections]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, selections]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
for (int i = 0; i < textInterface->selectionCount(); ++i) {
- QPair<int,int> sel;
- textInterface->selection(i, &sel.first, &sel.second);
- (*ptrSelections)->append(sel);
+ int startOffset, endOffset;
+ textInterface->selection(i, &startOffset, &endOffset);
+ selections->append({startOffset, endOffset});
}
- if ((*ptrSelections)->size() == 0) {
+ if (selections->size() == 0) {
// If there is no selection, we return an array with a single degenerate (empty) text range at the cursor position.
- QPair<int,int> sel(textInterface->cursorPosition(), textInterface->cursorPosition());
- (*ptrSelections)->append(sel);
+ auto cur = textInterface->cursorPosition();
+ selections->append({cur, cur});
}
}
}
- delete ptrSelections;
return S_OK;
}))) {
return E_FAIL;
@@ -137,9 +139,11 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetSelection(UINT32 *returnValu
if (!providerArray)
return E_OUTOFMEMORY;
- for (int i = 0; i < selCount; ++i) {
- ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), (*selections)[i].first, (*selections)[i].second);
- textRangeProvider.CopyTo(&providerArray[i]);
+ auto dst = providerArray;
+ for (auto sel : *selections) {
+ ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider
+ = Make<QWinRTUiaTextRangeProvider>(id(), sel.startOffset, sel.endOffset);
+ textRangeProvider.CopyTo(dst++);
}
*returnValueSize = selCount;
*returnValue = providerArray;
@@ -184,14 +188,12 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::RangeFromPoint(ABI::Windows::Fo
const QPoint pt(screenLocation.X, screenLocation.Y);
auto accid = id();
- auto offset = QSharedPointer<int>(new int);
- auto ptrOffset = new QSharedPointer<int>(offset);
+ auto offset = std::make_shared<int>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, pt, ptrOffset]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, pt, offset]() {
if (QAccessibleInterface *accessible = accessibleForId(accid))
if (QAccessibleTextInterface *textInterface = accessible->textInterface())
- **ptrOffset = qBound(0, textInterface->offsetAtPoint(pt), textInterface->characterCount() - 1);
- delete ptrOffset;
+ *offset = qBound(0, textInterface->offsetAtPoint(pt), textInterface->characterCount() - 1);
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp
index fc3778d652..ca15feaff9 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -212,10 +214,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
auto accid = id();
auto startOffset = m_startOffset;
auto endOffset = m_endOffset;
- auto rects = QSharedPointer<QList<QRect>>(new QList<QRect>);
- auto ptrRects = new QSharedPointer<QList<QRect>>(rects);
+ auto rects = std::make_shared<QVarLengthArray<QRect>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset, ptrRects]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset, rects]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
int len = textInterface->characterCount();
@@ -233,7 +234,7 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
qMin(startRect.y(), endRect.y()),
qMax(startRect.x() + startRect.width(), endRect.x() + endRect.width()) - qMin(startRect.x(), endRect.x()),
qMax(startRect.y() + startRect.height(), endRect.y() + endRect.height()) - qMin(startRect.y(), endRect.y()));
- (*ptrRects)->append(lineRect);
+ rects->append(lineRect);
}
if (end >= len) break;
textInterface->textAfterOffset(end + 1, QAccessible::LineBoundary, &start, &end);
@@ -241,7 +242,6 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
}
}
}
- delete ptrRects;
return S_OK;
}))) {
return E_FAIL;
@@ -251,11 +251,12 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
if (!doubleArray)
return E_OUTOFMEMORY;
- for (int i = 0; i < rects->size(); ++i) {
- doubleArray[i*4] = (*rects)[i].left();
- doubleArray[i*4+1] = (*rects)[i].top();
- doubleArray[i*4+2] = (*rects)[i].width();
- doubleArray[i*4+3] = (*rects)[i].height();
+ DOUBLE *dst = doubleArray;
+ for (auto rect : *rects) {
+ *dst++ = rect.left();
+ *dst++ = rect.top();
+ *dst++ = rect.width();
+ *dst++ = rect.height();
}
*returnValue = doubleArray;
*returnValueSize = 4 * rects->size();
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index e9e49e0c33..a04189513a 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -57,6 +57,9 @@
#ifdef Q_OS_WIN
# include <QtCore/QVarLengthArray>
# include <qt_windows.h>
+# ifndef Q_OS_WINRT
+# include <shlobj.h>
+# endif
#endif
QT_BEGIN_NAMESPACE
@@ -837,8 +840,8 @@ QString QFileSystemModelPrivate::displayName(const QModelIndex &index) const
{
#if defined(Q_OS_WIN)
QFileSystemNode *dirNode = node(index);
- if (!dirNode->volumeName.isNull())
- return dirNode->volumeName + QLatin1String(" (") + name(index) + QLatin1Char(')');
+ if (!dirNode->volumeName.isEmpty())
+ return dirNode->volumeName;
#endif
return name(index);
}
@@ -1773,6 +1776,27 @@ void QFileSystemModelPrivate::_q_directoryChanged(const QString &directory, cons
removeNode(parentNode, toRemove[i]);
}
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+static QString volumeName(const QString &path)
+{
+ IShellItem *item = nullptr;
+ const QString native = QDir::toNativeSeparators(path);
+ HRESULT hr = SHCreateItemFromParsingName(reinterpret_cast<const wchar_t *>(native.utf16()),
+ nullptr, IID_IShellItem,
+ reinterpret_cast<void **>(&item));
+ if (FAILED(hr))
+ return QString();
+ LPWSTR name = nullptr;
+ hr = item->GetDisplayName(SIGDN_NORMALDISPLAY, &name);
+ if (FAILED(hr))
+ return QString();
+ QString result = QString::fromWCharArray(name);
+ CoTaskMemFree(name);
+ item->Release();
+ return result;
+}
+#endif // Q_OS_WIN && !Q_OS_WINRT
+
/*!
\internal
@@ -1791,15 +1815,8 @@ QFileSystemModelPrivate::QFileSystemNode* QFileSystemModelPrivate::addNode(QFile
#endif
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
//The parentNode is "" so we are listing the drives
- if (parentNode->fileName.isEmpty()) {
- wchar_t name[MAX_PATH + 1];
- //GetVolumeInformation requires to add trailing backslash
- const QString nodeName = fileName + QLatin1String("\\");
- BOOL success = ::GetVolumeInformation((wchar_t *)(nodeName.utf16()),
- name, MAX_PATH + 1, NULL, 0, NULL, NULL, 0);
- if (success && name[0])
- node->volumeName = QString::fromWCharArray(name);
- }
+ if (parentNode->fileName.isEmpty())
+ node->volumeName = volumeName(fileName);
#endif
Q_ASSERT(!parentNode->children.contains(fileName));
parentNode->children.insert(fileName, node);
diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp
index 39b08dbc1e..eec65c8625 100644
--- a/src/widgets/kernel/qshortcut.cpp
+++ b/src/widgets/kernel/qshortcut.cpp
@@ -659,24 +659,22 @@ int QShortcut::id() const
bool QShortcut::event(QEvent *e)
{
Q_D(QShortcut);
- bool handled = false;
if (d->sc_enabled && e->type() == QEvent::Shortcut) {
auto se = static_cast<QShortcutEvent *>(e);
if (se->shortcutId() == d->sc_id && se->key() == d->sc_sequence){
#if QT_CONFIG(whatsthis)
if (QWhatsThis::inWhatsThisMode()) {
QWhatsThis::showText(QCursor::pos(), d->sc_whatsthis);
- handled = true;
} else
#endif
if (se->isAmbiguous())
emit activatedAmbiguously();
else
emit activated();
- handled = true;
+ return true;
}
}
- return handled;
+ return QObject::event(e);
}
#endif // QT_NO_SHORTCUT
diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp
index 5b3efd598f..01cadd9a86 100644
--- a/src/widgets/styles/qstyleoption.cpp
+++ b/src/widgets/styles/qstyleoption.cpp
@@ -1760,7 +1760,7 @@ QStyleOptionMenuItem::QStyleOptionMenuItem(int version)
\value Exclusive The item is an exclusive check item (like a radio button).
\value NonExclusive The item is a non-exclusive check item (like a check box).
- \sa checkType, QAction::checkable, QAction::checked, QActionGroup::exclusive
+ \sa checkType, QAction::checkable, QAction::checked, QActionGroup::exclusionPolicy
*/
/*!
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index e73c63f657..a53c278aea 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -862,6 +862,16 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
when the choice is not changed. If you need to know when the
choice actually changes, use signal currentIndexChanged().
+ \obsolete Use QComboBox::textActivated() instead
+*/
+/*!
+ \fn void QComboBox::textActivated(const QString &text)
+ \since 5.14
+
+ This signal is sent when the user chooses an item in the combobox.
+ The item's \a text is passed. Note that this signal is sent even
+ when the choice is not changed. If you need to know when the
+ choice actually changes, use signal currentIndexChanged().
*/
/*!
@@ -876,6 +886,15 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
This signal is sent when an item in the combobox popup list is
highlighted by the user. The item's \a text is passed.
+
+ \obsolete Use textHighlighted() instead
+*/
+/*!
+ \fn void QComboBox::textHighlighted(const QString &text)
+ \since 5.14
+
+ This signal is sent when an item in the combobox popup list is
+ highlighted by the user. The item's \a text is passed.
*/
/*!
@@ -888,7 +907,6 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
currentIndex was reset.
*/
-#if QT_DEPRECATED_SINCE(5, 13)
/*!
\fn void QComboBox::currentIndexChanged(const QString &text)
\since 4.1
@@ -897,7 +915,6 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
changes either through user interaction or programmatically. The
item's \a text is passed.
*/
-#endif
/*!
\fn void QComboBox::currentTextChanged(const QString &text)
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index e38490dabd..51b458f03a 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -2332,14 +2332,17 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
// However if the QMenu was constructed with a QDesktopScreenWidget as its parent,
// then initialScreenIndex was set, so we should respect that for the lifetime of this menu.
// Use d->popupScreen to remember, because initialScreenIndex will be reset after the first showing.
- const int screenIndex = d->topData()->initialScreenIndex;
- if (screenIndex >= 0)
- d->popupScreen = screenIndex;
- if (auto s = QGuiApplication::screens().value(d->popupScreen)) {
- if (d->setScreen(s))
+ // However if eventLoop exists, then exec() already did this by calling createWinId(); so leave it alone. (QTBUG-76162)
+ if (!d->eventLoop) {
+ const int screenIndex = d->topData()->initialScreenIndex;
+ if (screenIndex >= 0)
+ d->popupScreen = screenIndex;
+ if (auto s = QGuiApplication::screens().value(d->popupScreen)) {
+ if (d->setScreen(s))
+ d->itemsDirty = true;
+ } else if (d->setScreenForPoint(p)) {
d->itemsDirty = true;
- } else if (d->setScreenForPoint(p)) {
- d->itemsDirty = true;
+ }
}
const bool contextMenu = d->isContextMenu();