Merge "Merge remote-tracking branch 'origin/5.12.8' into 5.12"
This commit is contained in:
commit
7d7afe1d2b
5
configure
vendored
5
configure
vendored
@ -271,12 +271,9 @@ macSDKify()
|
||||
val=$(echo $sdk_val $(echo $val | cut -s -d ' ' -f 2-))
|
||||
echo "$var=$val"
|
||||
;;
|
||||
QMAKE_CFLAGS=*|QMAKE_CXXFLAGS=*)
|
||||
QMAKE_CFLAGS=*|QMAKE_CXXFLAGS=*|QMAKE_LFLAGS=*)
|
||||
echo "$line -isysroot $sysroot $version_min_flag"
|
||||
;;
|
||||
QMAKE_LFLAGS=*)
|
||||
echo "$line -Wl,-syslibroot,$sysroot $version_min_flag"
|
||||
;;
|
||||
*)
|
||||
echo "$line"
|
||||
;;
|
||||
|
70
dist/changes-5.12.8
vendored
Normal file
70
dist/changes-5.12.8
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
Qt 5.12.8 is a bug-fix release. It maintains both forward and backward
|
||||
compatibility (source and binary) with Qt 5.12.0 through 5.12.7.
|
||||
|
||||
For more details, refer to the online documentation included in this
|
||||
distribution. The documentation is also available online:
|
||||
|
||||
https://doc.qt.io/qt-5/index.html
|
||||
|
||||
The Qt version 5.12 series is binary compatible with the 5.11.x series.
|
||||
Applications compiled for 5.11 will continue to run with 5.12.
|
||||
|
||||
Some of the changes listed in this file include issue tracking numbers
|
||||
corresponding to tasks in the Qt Bug Tracker:
|
||||
|
||||
https://bugreports.qt.io/
|
||||
|
||||
Each of these identifiers can be entered in the bug tracker to obtain more
|
||||
information about a particular change.
|
||||
|
||||
****************************************************************************
|
||||
* QtCore *
|
||||
****************************************************************************
|
||||
|
||||
- QLockFile:
|
||||
* Suppressed the warning on QNX that said 'setNativeLocks failed:
|
||||
"Function not implemented"'. There is no difference in behavior: Qt
|
||||
will continue not to be able to apply an OS- level file lock, which
|
||||
means the lock could be accidentally stolen by buggy software. Correct
|
||||
software using QLockFile should not be affected.
|
||||
|
||||
- QXmlStream:
|
||||
* QTBUG-47417: QXmlStreamReader does now limit the expansion of
|
||||
entities to 4096 characters. Documents where a single entity
|
||||
expands to more characters than the limit are not considered well
|
||||
formed. The limit is there to avoid DoS attacks through
|
||||
recursively expanding entities when loading untrusted content. Qt
|
||||
5.15 will add methods that allow changing that limit.
|
||||
|
||||
****************************************************************************
|
||||
* QtSQL *
|
||||
****************************************************************************
|
||||
|
||||
- sqlite:
|
||||
* Updated to v3.31.1
|
||||
* [QTBUG-82533] Fixed CVE-2020-9327
|
||||
|
||||
****************************************************************************
|
||||
* QtNetwork *
|
||||
****************************************************************************
|
||||
|
||||
- QSslCertificate:
|
||||
* Fix a potential heap buffer overflow when parsing certificates
|
||||
- QTBUG-81762: Fix SSL symbol resolving for OPENSSL_NO_NEXPROTONEG
|
||||
|
||||
****************************************************************************
|
||||
* Platform specific changes *
|
||||
****************************************************************************
|
||||
|
||||
- macOS:
|
||||
* QTBUG-82986: Improve performance when flushing sublayers
|
||||
* QTBUG-79139: Avoid repainting OpenGL layers when resizing the window
|
||||
|
||||
- xcb/X11:
|
||||
* QTBUG-76147, QTBUG-76354, QTBUG-68864: Fix handling of minimized state
|
||||
|
||||
- QNX:
|
||||
* QTBUG-81701: QLockFile: Disable flock() on QNX
|
||||
|
||||
|
||||
|
@ -197,7 +197,7 @@ macx-xcode {
|
||||
-isysroot$$xcodeSDKInfo(Path, $$sdk)
|
||||
QMAKE_XARCH_LFLAGS_$${arch} = $$version_min_flags \
|
||||
-Xarch_$${arch} \
|
||||
-Wl,-syslibroot,$$xcodeSDKInfo(Path, $$sdk)
|
||||
-isysroot$$xcodeSDKInfo(Path, $$sdk)
|
||||
|
||||
QMAKE_XARCH_CFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS_$${arch})
|
||||
QMAKE_XARCH_LFLAGS += $(EXPORT_QMAKE_XARCH_LFLAGS_$${arch})
|
||||
@ -218,7 +218,7 @@ macx-xcode {
|
||||
version_min_flag = -m$${version_identifier}-version-min=$$deployment_target
|
||||
QMAKE_CFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag
|
||||
QMAKE_CXXFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag
|
||||
QMAKE_LFLAGS += -Wl,-syslibroot,$$QMAKE_MAC_SDK_PATH $$version_min_flag
|
||||
QMAKE_LFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag
|
||||
}
|
||||
|
||||
# Enable precompiled headers for multiple architectures
|
||||
|
@ -724,54 +724,66 @@ public class QtNative
|
||||
|
||||
public static boolean hasClipboardText()
|
||||
{
|
||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||
if (primaryClip.getItemAt(i).getText() != null)
|
||||
return true;
|
||||
try {
|
||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||
if (primaryClip.getItemAt(i).getText() != null)
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(QtTAG, "Failed to get clipboard data", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String getClipboardText()
|
||||
{
|
||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||
if (primaryClip.getItemAt(i).getText() != null)
|
||||
return primaryClip.getItemAt(i).getText().toString();
|
||||
try {
|
||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||
if (primaryClip.getItemAt(i).getText() != null)
|
||||
return primaryClip.getItemAt(i).getText().toString();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(QtTAG, "Failed to get clipboard data", e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static void updatePrimaryClip(ClipData clipData)
|
||||
{
|
||||
if (m_usePrimaryClip) {
|
||||
ClipData clip = m_clipboardManager.getPrimaryClip();
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
if (m_addItemMethod == null) {
|
||||
Class[] cArg = new Class[2];
|
||||
cArg[0] = ContentResolver.class;
|
||||
cArg[1] = ClipData.Item.class;
|
||||
try {
|
||||
m_addItemMethod = m_clipboardManager.getClass().getMethod("addItem", cArg);
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
if (m_usePrimaryClip) {
|
||||
ClipData clip = m_clipboardManager.getPrimaryClip();
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
if (m_addItemMethod == null) {
|
||||
Class[] cArg = new Class[2];
|
||||
cArg[0] = ContentResolver.class;
|
||||
cArg[1] = ClipData.Item.class;
|
||||
try {
|
||||
m_addItemMethod = m_clipboardManager.getClass().getMethod("addItem", cArg);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_addItemMethod != null) {
|
||||
try {
|
||||
m_addItemMethod.invoke(m_activity.getContentResolver(), clipData.getItemAt(0));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (m_addItemMethod != null) {
|
||||
try {
|
||||
m_addItemMethod.invoke(m_activity.getContentResolver(), clipData.getItemAt(0));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
clip.addItem(clipData.getItemAt(0));
|
||||
}
|
||||
m_clipboardManager.setPrimaryClip(clip);
|
||||
} else {
|
||||
clip.addItem(clipData.getItemAt(0));
|
||||
m_clipboardManager.setPrimaryClip(clipData);
|
||||
m_usePrimaryClip = true;
|
||||
}
|
||||
m_clipboardManager.setPrimaryClip(clip);
|
||||
} else {
|
||||
m_clipboardManager.setPrimaryClip(clipData);
|
||||
m_usePrimaryClip = true;
|
||||
} catch (Exception e) {
|
||||
Log.e(QtTAG, "Failed to set clipboard data", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -785,22 +797,30 @@ public class QtNative
|
||||
|
||||
public static boolean hasClipboardHtml()
|
||||
{
|
||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||
if (primaryClip.getItemAt(i).getHtmlText() != null)
|
||||
return true;
|
||||
try {
|
||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||
if (primaryClip.getItemAt(i).getHtmlText() != null)
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(QtTAG, "Failed to get clipboard data", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String getClipboardHtml()
|
||||
{
|
||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||
if (primaryClip.getItemAt(i).getHtmlText() != null)
|
||||
return primaryClip.getItemAt(i).getHtmlText().toString();
|
||||
try {
|
||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||
if (primaryClip.getItemAt(i).getHtmlText() != null)
|
||||
return primaryClip.getItemAt(i).getHtmlText().toString();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(QtTAG, "Failed to get clipboard data", e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@ -816,11 +836,15 @@ public class QtNative
|
||||
|
||||
public static boolean hasClipboardUri()
|
||||
{
|
||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||
if (primaryClip.getItemAt(i).getUri() != null)
|
||||
return true;
|
||||
try {
|
||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||
if (primaryClip.getItemAt(i).getUri() != null)
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(QtTAG, "Failed to get clipboard data", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -828,11 +852,15 @@ public class QtNative
|
||||
private static String[] getClipboardUris()
|
||||
{
|
||||
ArrayList<String> uris = new ArrayList<String>();
|
||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||
if (primaryClip.getItemAt(i).getUri() != null)
|
||||
uris.add(primaryClip.getItemAt(i).getUri().toString());
|
||||
try {
|
||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||
if (primaryClip.getItemAt(i).getUri() != null)
|
||||
uris.add(primaryClip.getItemAt(i).getUri().toString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(QtTAG, "Failed to get clipboard data", e);
|
||||
}
|
||||
String[] strings = new String[uris.size()];
|
||||
strings = uris.toArray(strings);
|
||||
|
@ -277,9 +277,19 @@ public:
|
||||
QHash<QStringView, Entity> entityHash;
|
||||
QHash<QStringView, Entity> parameterEntityHash;
|
||||
QXmlStreamSimpleStack<Entity *>entityReferenceStack;
|
||||
int entityExpansionLimit = 4096;
|
||||
int entityLength = 0;
|
||||
inline bool referenceEntity(Entity &entity) {
|
||||
if (entity.isCurrentlyReferenced) {
|
||||
raiseWellFormedError(QXmlStream::tr("Recursive entity detected."));
|
||||
raiseWellFormedError(QXmlStream::tr("Self-referencing entity detected."));
|
||||
return false;
|
||||
}
|
||||
// entityLength represents the amount of additional characters the
|
||||
// entity expands into (can be negative for e.g. &). It's used to
|
||||
// avoid DoS attacks through recursive entity expansions
|
||||
entityLength += entity.value.size() - entity.name.size() - 2;
|
||||
if (entityLength > entityExpansionLimit) {
|
||||
raiseWellFormedError(QXmlStream::tr("Entity expands to more characters than the entity expansion limit."));
|
||||
return false;
|
||||
}
|
||||
entity.isCurrentlyReferenced = true;
|
||||
@ -830,6 +840,8 @@ entity_done ::= ENTITY_DONE;
|
||||
/.
|
||||
case $rule_number:
|
||||
entityReferenceStack.pop()->isCurrentlyReferenced = false;
|
||||
if (entityReferenceStack.isEmpty())
|
||||
entityLength = 0;
|
||||
clearSym();
|
||||
break;
|
||||
./
|
||||
|
@ -774,9 +774,19 @@ public:
|
||||
QHash<QStringView, Entity> entityHash;
|
||||
QHash<QStringView, Entity> parameterEntityHash;
|
||||
QXmlStreamSimpleStack<Entity *>entityReferenceStack;
|
||||
int entityExpansionLimit = 4096;
|
||||
int entityLength = 0;
|
||||
inline bool referenceEntity(Entity &entity) {
|
||||
if (entity.isCurrentlyReferenced) {
|
||||
raiseWellFormedError(QXmlStream::tr("Recursive entity detected."));
|
||||
raiseWellFormedError(QXmlStream::tr("Self-referencing entity detected."));
|
||||
return false;
|
||||
}
|
||||
// entityLength represents the amount of additional characters the
|
||||
// entity expands into (can be negative for e.g. &). It's used to
|
||||
// avoid DoS attacks through recursive entity expansions
|
||||
entityLength += entity.value.size() - entity.name.size() - 2;
|
||||
if (entityLength > entityExpansionLimit) {
|
||||
raiseWellFormedError(QXmlStream::tr("Entity expands to more characters than the entity expansion limit."));
|
||||
return false;
|
||||
}
|
||||
entity.isCurrentlyReferenced = true;
|
||||
@ -1308,6 +1318,8 @@ bool QXmlStreamReaderPrivate::parse()
|
||||
|
||||
case 10:
|
||||
entityReferenceStack.pop()->isCurrentlyReferenced = false;
|
||||
if (entityReferenceStack.isEmpty())
|
||||
entityLength = 0;
|
||||
clearSym();
|
||||
break;
|
||||
|
||||
|
@ -47,6 +47,8 @@
|
||||
#include <QScopedPointer>
|
||||
#include "qiosurfacegraphicsbuffer.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QCocoaBackingStore : public QRasterBackingStore
|
||||
@ -71,8 +73,9 @@ private:
|
||||
void redrawRoundedBottomCorners(CGRect) const;
|
||||
};
|
||||
|
||||
class QCALayerBackingStore : public QCocoaBackingStore
|
||||
class QCALayerBackingStore : public QObject, public QCocoaBackingStore
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QCALayerBackingStore(QWindow *window);
|
||||
~QCALayerBackingStore();
|
||||
@ -119,6 +122,11 @@ private:
|
||||
QMacNotificationObserver m_backingPropertiesObserver;
|
||||
|
||||
std::list<std::unique_ptr<GraphicsBuffer>> m_buffers;
|
||||
|
||||
void flushSubWindow(QWindow *window);
|
||||
std::unordered_map<QWindow*, std::unique_ptr<QCALayerBackingStore>> m_subWindowBackingstores;
|
||||
void windowDestroyed(QObject *object);
|
||||
bool m_clearSurfaceOnPaint = true;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -394,7 +394,7 @@ void QCALayerBackingStore::beginPaint(const QRegion ®ion)
|
||||
// Although undocumented, QBackingStore::beginPaint expects the painted region
|
||||
// to be cleared before use if the window has a surface format with an alpha.
|
||||
// Fresh IOSurfaces are already cleared, so we don't need to clear those.
|
||||
if (!bufferWasRecreated && window()->format().hasAlpha()) {
|
||||
if (m_clearSurfaceOnPaint && !bufferWasRecreated && window()->format().hasAlpha()) {
|
||||
qCDebug(lcQpaBackingStore) << "Clearing" << region << "before use";
|
||||
QPainter painter(m_buffers.back()->asImage());
|
||||
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
@ -523,9 +523,13 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion,
|
||||
if (!prepareForFlush())
|
||||
return;
|
||||
|
||||
if (flushedWindow != window()) {
|
||||
flushSubWindow(flushedWindow);
|
||||
return;
|
||||
}
|
||||
|
||||
QMacAutoReleasePool pool;
|
||||
|
||||
NSView *backingStoreView = static_cast<QCocoaWindow *>(window()->handle())->view();
|
||||
NSView *flushedView = static_cast<QCocoaWindow *>(flushedWindow->handle())->view();
|
||||
|
||||
// If the backingstore is just flushed, without being painted to first, then we may
|
||||
@ -560,7 +564,7 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion,
|
||||
// are committed as part of a display-cycle instead of on the next runloop pass. This
|
||||
// means CA won't try to throttle us if we flush too fast, and we'll coalesce our flush
|
||||
// with other pending view and layer updates.
|
||||
backingStoreView.window.viewsNeedDisplay = YES;
|
||||
flushedView.window.viewsNeedDisplay = YES;
|
||||
|
||||
if (window()->format().swapBehavior() == QSurfaceFormat::SingleBuffer) {
|
||||
// The private API [CALayer reloadValueForKeyPath:@"contents"] would be preferable,
|
||||
@ -568,28 +572,10 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion,
|
||||
flushedView.layer.contents = nil;
|
||||
}
|
||||
|
||||
if (flushedView == backingStoreView) {
|
||||
qCInfo(lcQpaBackingStore) << "Flushing" << backBufferSurface
|
||||
<< "to" << flushedView.layer << "of" << flushedView;
|
||||
flushedView.layer.contents = backBufferSurface;
|
||||
} else {
|
||||
auto subviewRect = [flushedView convertRect:flushedView.bounds toView:backingStoreView];
|
||||
auto scale = flushedView.layer.contentsScale;
|
||||
subviewRect = CGRectApplyAffineTransform(subviewRect, CGAffineTransformMakeScale(scale, scale));
|
||||
qCInfo(lcQpaBackingStore) << "Flushing" << backBufferSurface
|
||||
<< "to" << flushedView.layer << "of" << flushedView;
|
||||
|
||||
// We make a copy of the image data up front, which means we don't
|
||||
// need to mark the IOSurface as being in use. FIXME: Investigate
|
||||
// if there's a cheaper way to get sub-image data to a layer.
|
||||
m_buffers.back()->lock(QPlatformGraphicsBuffer::SWReadAccess);
|
||||
QImage subImage = m_buffers.back()->asImage()->copy(QRectF::fromCGRect(subviewRect).toRect());
|
||||
m_buffers.back()->unlock();
|
||||
|
||||
qCInfo(lcQpaBackingStore) << "Flushing" << subImage
|
||||
<< "to" << flushedView.layer << "of subview" << flushedView;
|
||||
QCFType<CGImageRef> cgImage = CGImageCreateCopyWithColorSpace(
|
||||
QCFType<CGImageRef>(subImage.toCGImage()), colorSpace());
|
||||
flushedView.layer.contents = (__bridge id)static_cast<CGImageRef>(cgImage);
|
||||
}
|
||||
flushedView.layer.contents = backBufferSurface;
|
||||
|
||||
// Since we may receive multiple flushes before a new frame is started, we do not
|
||||
// swap any buffers just yet. Instead we check in the next beginPaint if the layer's
|
||||
@ -601,6 +587,53 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion,
|
||||
// the window server.
|
||||
}
|
||||
|
||||
void QCALayerBackingStore::flushSubWindow(QWindow *subWindow)
|
||||
{
|
||||
qCInfo(lcQpaBackingStore) << "Flushing sub-window" << subWindow
|
||||
<< "via its own backingstore";
|
||||
|
||||
auto &subWindowBackingStore = m_subWindowBackingstores[subWindow];
|
||||
if (!subWindowBackingStore) {
|
||||
subWindowBackingStore.reset(new QCALayerBackingStore(subWindow));
|
||||
QObject::connect(subWindow, &QObject::destroyed, this, &QCALayerBackingStore::windowDestroyed);
|
||||
subWindowBackingStore->m_clearSurfaceOnPaint = false;
|
||||
}
|
||||
|
||||
auto subWindowSize = subWindow->size();
|
||||
static const auto kNoStaticContents = QRegion();
|
||||
subWindowBackingStore->resize(subWindowSize, kNoStaticContents);
|
||||
|
||||
auto subWindowLocalRect = QRect(QPoint(), subWindowSize);
|
||||
subWindowBackingStore->beginPaint(subWindowLocalRect);
|
||||
|
||||
QPainter painter(subWindowBackingStore->m_buffers.back()->asImage());
|
||||
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
|
||||
NSView *backingStoreView = static_cast<QCocoaWindow *>(window()->handle())->view();
|
||||
NSView *flushedView = static_cast<QCocoaWindow *>(subWindow->handle())->view();
|
||||
auto subviewRect = [flushedView convertRect:flushedView.bounds toView:backingStoreView];
|
||||
auto scale = flushedView.layer.contentsScale;
|
||||
subviewRect = CGRectApplyAffineTransform(subviewRect, CGAffineTransformMakeScale(scale, scale));
|
||||
|
||||
m_buffers.back()->lock(QPlatformGraphicsBuffer::SWReadAccess);
|
||||
const QImage *backingStoreImage = m_buffers.back()->asImage();
|
||||
painter.drawImage(subWindowLocalRect, *backingStoreImage, QRectF::fromCGRect(subviewRect));
|
||||
m_buffers.back()->unlock();
|
||||
|
||||
painter.end();
|
||||
subWindowBackingStore->endPaint();
|
||||
subWindowBackingStore->flush(subWindow, subWindowLocalRect, QPoint());
|
||||
|
||||
qCInfo(lcQpaBackingStore) << "Done flushing sub-window" << subWindow;
|
||||
}
|
||||
|
||||
void QCALayerBackingStore::windowDestroyed(QObject *object)
|
||||
{
|
||||
auto *window = static_cast<QWindow*>(object);
|
||||
qCInfo(lcQpaBackingStore) << "Removing backingstore for sub-window" << window;
|
||||
m_subWindowBackingstores.erase(window);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_OPENGL
|
||||
void QCALayerBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset,
|
||||
QPlatformTextureList *textures, bool translucentBackground)
|
||||
@ -734,4 +767,6 @@ QImage *QCALayerBackingStore::GraphicsBuffer::asImage()
|
||||
return &m_image;
|
||||
}
|
||||
|
||||
#include "moc_qcocoabackingstore.cpp"
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -332,11 +332,8 @@ bool QIOSContext::verifyGraphicsHardwareAvailability()
|
||||
);
|
||||
});
|
||||
|
||||
if (applicationBackgrounded) {
|
||||
static const char warning[] = "OpenGL ES calls are not allowed while an application is backgrounded";
|
||||
Q_ASSERT_X(!applicationBackgrounded, "QIOSContext", warning);
|
||||
qCWarning(lcQpaGLContext, warning);
|
||||
}
|
||||
if (applicationBackgrounded)
|
||||
qCWarning(lcQpaGLContext, "OpenGL ES calls are not allowed while an application is backgrounded");
|
||||
|
||||
return !applicationBackgrounded;
|
||||
}
|
||||
|
@ -393,8 +393,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
QXmlStreamReader reader(&inputFile);
|
||||
|
||||
/* See testcases.dtd which reads: 'Nonvalidating parsers
|
||||
* must also accept "invalid" testcases, but validating ones must reject them.' */
|
||||
if(type == QLatin1String("invalid") || type == QLatin1String("valid"))
|
||||
@ -580,6 +578,8 @@ private slots:
|
||||
void roundTrip() const;
|
||||
void roundTrip_data() const;
|
||||
|
||||
void entityExpansionLimit() const;
|
||||
|
||||
private:
|
||||
static QByteArray readFile(const QString &filename);
|
||||
|
||||
@ -1756,6 +1756,25 @@ void tst_QXmlStream::roundTrip_data() const
|
||||
"</root>\n";
|
||||
}
|
||||
|
||||
void tst_QXmlStream::entityExpansionLimit() const
|
||||
{
|
||||
QString xml = QStringLiteral("<?xml version=\"1.0\"?>"
|
||||
"<!DOCTYPE foo ["
|
||||
"<!ENTITY a \"0123456789\" >"
|
||||
"<!ENTITY b \"&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;\" >"
|
||||
"<!ENTITY c \"&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;\" >"
|
||||
"<!ENTITY d \"&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;\" >"
|
||||
"]>"
|
||||
"<foo>&d;&d;&d;</foo>");
|
||||
{
|
||||
QXmlStreamReader reader(xml);
|
||||
do {
|
||||
reader.readNext();
|
||||
} while (!reader.atEnd());
|
||||
QCOMPARE(reader.error(), QXmlStreamReader::NotWellFormedError);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QXmlStream::roundTrip() const
|
||||
{
|
||||
QFETCH(QString, in);
|
||||
|
Loading…
x
Reference in New Issue
Block a user