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-))
|
val=$(echo $sdk_val $(echo $val | cut -s -d ' ' -f 2-))
|
||||||
echo "$var=$val"
|
echo "$var=$val"
|
||||||
;;
|
;;
|
||||||
QMAKE_CFLAGS=*|QMAKE_CXXFLAGS=*)
|
QMAKE_CFLAGS=*|QMAKE_CXXFLAGS=*|QMAKE_LFLAGS=*)
|
||||||
echo "$line -isysroot $sysroot $version_min_flag"
|
echo "$line -isysroot $sysroot $version_min_flag"
|
||||||
;;
|
;;
|
||||||
QMAKE_LFLAGS=*)
|
|
||||||
echo "$line -Wl,-syslibroot,$sysroot $version_min_flag"
|
|
||||||
;;
|
|
||||||
*)
|
*)
|
||||||
echo "$line"
|
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)
|
-isysroot$$xcodeSDKInfo(Path, $$sdk)
|
||||||
QMAKE_XARCH_LFLAGS_$${arch} = $$version_min_flags \
|
QMAKE_XARCH_LFLAGS_$${arch} = $$version_min_flags \
|
||||||
-Xarch_$${arch} \
|
-Xarch_$${arch} \
|
||||||
-Wl,-syslibroot,$$xcodeSDKInfo(Path, $$sdk)
|
-isysroot$$xcodeSDKInfo(Path, $$sdk)
|
||||||
|
|
||||||
QMAKE_XARCH_CFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS_$${arch})
|
QMAKE_XARCH_CFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS_$${arch})
|
||||||
QMAKE_XARCH_LFLAGS += $(EXPORT_QMAKE_XARCH_LFLAGS_$${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
|
version_min_flag = -m$${version_identifier}-version-min=$$deployment_target
|
||||||
QMAKE_CFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag
|
QMAKE_CFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag
|
||||||
QMAKE_CXXFLAGS += -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
|
# Enable precompiled headers for multiple architectures
|
||||||
|
@ -724,54 +724,66 @@ public class QtNative
|
|||||||
|
|
||||||
public static boolean hasClipboardText()
|
public static boolean hasClipboardText()
|
||||||
{
|
{
|
||||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
try {
|
||||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||||
if (primaryClip.getItemAt(i).getText() != null)
|
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||||
return true;
|
if (primaryClip.getItemAt(i).getText() != null)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(QtTAG, "Failed to get clipboard data", e);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getClipboardText()
|
private static String getClipboardText()
|
||||||
{
|
{
|
||||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
try {
|
||||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||||
if (primaryClip.getItemAt(i).getText() != null)
|
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||||
return primaryClip.getItemAt(i).getText().toString();
|
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 "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void updatePrimaryClip(ClipData clipData)
|
private static void updatePrimaryClip(ClipData clipData)
|
||||||
{
|
{
|
||||||
if (m_usePrimaryClip) {
|
try {
|
||||||
ClipData clip = m_clipboardManager.getPrimaryClip();
|
if (m_usePrimaryClip) {
|
||||||
if (Build.VERSION.SDK_INT >= 26) {
|
ClipData clip = m_clipboardManager.getPrimaryClip();
|
||||||
if (m_addItemMethod == null) {
|
if (Build.VERSION.SDK_INT >= 26) {
|
||||||
Class[] cArg = new Class[2];
|
if (m_addItemMethod == null) {
|
||||||
cArg[0] = ContentResolver.class;
|
Class[] cArg = new Class[2];
|
||||||
cArg[1] = ClipData.Item.class;
|
cArg[0] = ContentResolver.class;
|
||||||
try {
|
cArg[1] = ClipData.Item.class;
|
||||||
m_addItemMethod = m_clipboardManager.getClass().getMethod("addItem", cArg);
|
try {
|
||||||
} catch (Exception e) {
|
m_addItemMethod = m_clipboardManager.getClass().getMethod("addItem", cArg);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (m_addItemMethod != null) {
|
||||||
if (m_addItemMethod != null) {
|
try {
|
||||||
try {
|
m_addItemMethod.invoke(m_activity.getContentResolver(), clipData.getItemAt(0));
|
||||||
m_addItemMethod.invoke(m_activity.getContentResolver(), clipData.getItemAt(0));
|
} catch (Exception e) {
|
||||||
} catch (Exception e) {
|
e.printStackTrace();
|
||||||
e.printStackTrace();
|
}
|
||||||
|
} else {
|
||||||
|
clip.addItem(clipData.getItemAt(0));
|
||||||
}
|
}
|
||||||
|
m_clipboardManager.setPrimaryClip(clip);
|
||||||
} else {
|
} else {
|
||||||
clip.addItem(clipData.getItemAt(0));
|
m_clipboardManager.setPrimaryClip(clipData);
|
||||||
|
m_usePrimaryClip = true;
|
||||||
}
|
}
|
||||||
m_clipboardManager.setPrimaryClip(clip);
|
} catch (Exception e) {
|
||||||
} else {
|
Log.e(QtTAG, "Failed to set clipboard data", e);
|
||||||
m_clipboardManager.setPrimaryClip(clipData);
|
|
||||||
m_usePrimaryClip = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -785,22 +797,30 @@ public class QtNative
|
|||||||
|
|
||||||
public static boolean hasClipboardHtml()
|
public static boolean hasClipboardHtml()
|
||||||
{
|
{
|
||||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
try {
|
||||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||||
if (primaryClip.getItemAt(i).getHtmlText() != null)
|
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||||
return true;
|
if (primaryClip.getItemAt(i).getHtmlText() != null)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(QtTAG, "Failed to get clipboard data", e);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getClipboardHtml()
|
private static String getClipboardHtml()
|
||||||
{
|
{
|
||||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
try {
|
||||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||||
if (primaryClip.getItemAt(i).getHtmlText() != null)
|
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||||
return primaryClip.getItemAt(i).getHtmlText().toString();
|
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 "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -816,11 +836,15 @@ public class QtNative
|
|||||||
|
|
||||||
public static boolean hasClipboardUri()
|
public static boolean hasClipboardUri()
|
||||||
{
|
{
|
||||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
try {
|
||||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||||
if (primaryClip.getItemAt(i).getUri() != null)
|
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||||
return true;
|
if (primaryClip.getItemAt(i).getUri() != null)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(QtTAG, "Failed to get clipboard data", e);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -828,11 +852,15 @@ public class QtNative
|
|||||||
private static String[] getClipboardUris()
|
private static String[] getClipboardUris()
|
||||||
{
|
{
|
||||||
ArrayList<String> uris = new ArrayList<String>();
|
ArrayList<String> uris = new ArrayList<String>();
|
||||||
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
try {
|
||||||
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
|
||||||
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
ClipData primaryClip = m_clipboardManager.getPrimaryClip();
|
||||||
if (primaryClip.getItemAt(i).getUri() != null)
|
for (int i = 0; i < primaryClip.getItemCount(); ++i)
|
||||||
uris.add(primaryClip.getItemAt(i).getUri().toString());
|
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()];
|
String[] strings = new String[uris.size()];
|
||||||
strings = uris.toArray(strings);
|
strings = uris.toArray(strings);
|
||||||
|
@ -277,9 +277,19 @@ public:
|
|||||||
QHash<QStringView, Entity> entityHash;
|
QHash<QStringView, Entity> entityHash;
|
||||||
QHash<QStringView, Entity> parameterEntityHash;
|
QHash<QStringView, Entity> parameterEntityHash;
|
||||||
QXmlStreamSimpleStack<Entity *>entityReferenceStack;
|
QXmlStreamSimpleStack<Entity *>entityReferenceStack;
|
||||||
|
int entityExpansionLimit = 4096;
|
||||||
|
int entityLength = 0;
|
||||||
inline bool referenceEntity(Entity &entity) {
|
inline bool referenceEntity(Entity &entity) {
|
||||||
if (entity.isCurrentlyReferenced) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
entity.isCurrentlyReferenced = true;
|
entity.isCurrentlyReferenced = true;
|
||||||
@ -830,6 +840,8 @@ entity_done ::= ENTITY_DONE;
|
|||||||
/.
|
/.
|
||||||
case $rule_number:
|
case $rule_number:
|
||||||
entityReferenceStack.pop()->isCurrentlyReferenced = false;
|
entityReferenceStack.pop()->isCurrentlyReferenced = false;
|
||||||
|
if (entityReferenceStack.isEmpty())
|
||||||
|
entityLength = 0;
|
||||||
clearSym();
|
clearSym();
|
||||||
break;
|
break;
|
||||||
./
|
./
|
||||||
|
@ -774,9 +774,19 @@ public:
|
|||||||
QHash<QStringView, Entity> entityHash;
|
QHash<QStringView, Entity> entityHash;
|
||||||
QHash<QStringView, Entity> parameterEntityHash;
|
QHash<QStringView, Entity> parameterEntityHash;
|
||||||
QXmlStreamSimpleStack<Entity *>entityReferenceStack;
|
QXmlStreamSimpleStack<Entity *>entityReferenceStack;
|
||||||
|
int entityExpansionLimit = 4096;
|
||||||
|
int entityLength = 0;
|
||||||
inline bool referenceEntity(Entity &entity) {
|
inline bool referenceEntity(Entity &entity) {
|
||||||
if (entity.isCurrentlyReferenced) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
entity.isCurrentlyReferenced = true;
|
entity.isCurrentlyReferenced = true;
|
||||||
@ -1308,6 +1318,8 @@ bool QXmlStreamReaderPrivate::parse()
|
|||||||
|
|
||||||
case 10:
|
case 10:
|
||||||
entityReferenceStack.pop()->isCurrentlyReferenced = false;
|
entityReferenceStack.pop()->isCurrentlyReferenced = false;
|
||||||
|
if (entityReferenceStack.isEmpty())
|
||||||
|
entityLength = 0;
|
||||||
clearSym();
|
clearSym();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -47,6 +47,8 @@
|
|||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
#include "qiosurfacegraphicsbuffer.h"
|
#include "qiosurfacegraphicsbuffer.h"
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QCocoaBackingStore : public QRasterBackingStore
|
class QCocoaBackingStore : public QRasterBackingStore
|
||||||
@ -71,8 +73,9 @@ private:
|
|||||||
void redrawRoundedBottomCorners(CGRect) const;
|
void redrawRoundedBottomCorners(CGRect) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QCALayerBackingStore : public QCocoaBackingStore
|
class QCALayerBackingStore : public QObject, public QCocoaBackingStore
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
QCALayerBackingStore(QWindow *window);
|
QCALayerBackingStore(QWindow *window);
|
||||||
~QCALayerBackingStore();
|
~QCALayerBackingStore();
|
||||||
@ -119,6 +122,11 @@ private:
|
|||||||
QMacNotificationObserver m_backingPropertiesObserver;
|
QMacNotificationObserver m_backingPropertiesObserver;
|
||||||
|
|
||||||
std::list<std::unique_ptr<GraphicsBuffer>> m_buffers;
|
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
|
QT_END_NAMESPACE
|
||||||
|
@ -394,7 +394,7 @@ void QCALayerBackingStore::beginPaint(const QRegion ®ion)
|
|||||||
// Although undocumented, QBackingStore::beginPaint expects the painted region
|
// Although undocumented, QBackingStore::beginPaint expects the painted region
|
||||||
// to be cleared before use if the window has a surface format with an alpha.
|
// 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.
|
// 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";
|
qCDebug(lcQpaBackingStore) << "Clearing" << region << "before use";
|
||||||
QPainter painter(m_buffers.back()->asImage());
|
QPainter painter(m_buffers.back()->asImage());
|
||||||
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
@ -523,9 +523,13 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion,
|
|||||||
if (!prepareForFlush())
|
if (!prepareForFlush())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (flushedWindow != window()) {
|
||||||
|
flushSubWindow(flushedWindow);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QMacAutoReleasePool pool;
|
QMacAutoReleasePool pool;
|
||||||
|
|
||||||
NSView *backingStoreView = static_cast<QCocoaWindow *>(window()->handle())->view();
|
|
||||||
NSView *flushedView = static_cast<QCocoaWindow *>(flushedWindow->handle())->view();
|
NSView *flushedView = static_cast<QCocoaWindow *>(flushedWindow->handle())->view();
|
||||||
|
|
||||||
// If the backingstore is just flushed, without being painted to first, then we may
|
// 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
|
// 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
|
// 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.
|
// with other pending view and layer updates.
|
||||||
backingStoreView.window.viewsNeedDisplay = YES;
|
flushedView.window.viewsNeedDisplay = YES;
|
||||||
|
|
||||||
if (window()->format().swapBehavior() == QSurfaceFormat::SingleBuffer) {
|
if (window()->format().swapBehavior() == QSurfaceFormat::SingleBuffer) {
|
||||||
// The private API [CALayer reloadValueForKeyPath:@"contents"] would be preferable,
|
// 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;
|
flushedView.layer.contents = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flushedView == backingStoreView) {
|
qCInfo(lcQpaBackingStore) << "Flushing" << backBufferSurface
|
||||||
qCInfo(lcQpaBackingStore) << "Flushing" << backBufferSurface
|
<< "to" << flushedView.layer << "of" << flushedView;
|
||||||
<< "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));
|
|
||||||
|
|
||||||
// We make a copy of the image data up front, which means we don't
|
flushedView.layer.contents = backBufferSurface;
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since we may receive multiple flushes before a new frame is started, we do not
|
// 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
|
// 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.
|
// 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
|
#ifndef QT_NO_OPENGL
|
||||||
void QCALayerBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset,
|
void QCALayerBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset,
|
||||||
QPlatformTextureList *textures, bool translucentBackground)
|
QPlatformTextureList *textures, bool translucentBackground)
|
||||||
@ -734,4 +767,6 @@ QImage *QCALayerBackingStore::GraphicsBuffer::asImage()
|
|||||||
return &m_image;
|
return &m_image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "moc_qcocoabackingstore.cpp"
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -332,11 +332,8 @@ bool QIOSContext::verifyGraphicsHardwareAvailability()
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (applicationBackgrounded) {
|
if (applicationBackgrounded)
|
||||||
static const char warning[] = "OpenGL ES calls are not allowed while an application is backgrounded";
|
qCWarning(lcQpaGLContext, "OpenGL ES calls are not allowed while an application is backgrounded");
|
||||||
Q_ASSERT_X(!applicationBackgrounded, "QIOSContext", warning);
|
|
||||||
qCWarning(lcQpaGLContext, warning);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !applicationBackgrounded;
|
return !applicationBackgrounded;
|
||||||
}
|
}
|
||||||
|
@ -393,8 +393,6 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QXmlStreamReader reader(&inputFile);
|
|
||||||
|
|
||||||
/* See testcases.dtd which reads: 'Nonvalidating parsers
|
/* See testcases.dtd which reads: 'Nonvalidating parsers
|
||||||
* must also accept "invalid" testcases, but validating ones must reject them.' */
|
* must also accept "invalid" testcases, but validating ones must reject them.' */
|
||||||
if(type == QLatin1String("invalid") || type == QLatin1String("valid"))
|
if(type == QLatin1String("invalid") || type == QLatin1String("valid"))
|
||||||
@ -580,6 +578,8 @@ private slots:
|
|||||||
void roundTrip() const;
|
void roundTrip() const;
|
||||||
void roundTrip_data() const;
|
void roundTrip_data() const;
|
||||||
|
|
||||||
|
void entityExpansionLimit() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QByteArray readFile(const QString &filename);
|
static QByteArray readFile(const QString &filename);
|
||||||
|
|
||||||
@ -1756,6 +1756,25 @@ void tst_QXmlStream::roundTrip_data() const
|
|||||||
"</root>\n";
|
"</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
|
void tst_QXmlStream::roundTrip() const
|
||||||
{
|
{
|
||||||
QFETCH(QString, in);
|
QFETCH(QString, in);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user