From 30fdd71b630066aa246102842b032051b5b6a7c5 Mon Sep 17 00:00:00 2001 From: Benjamin Summerton Date: Tue, 9 Dec 2014 23:15:31 -0500 Subject: Removed redundancy in QGraphicsItem documentation. Snippets [1] and [QGraphicsItem type] are the exact same, each referenced once, and only in the same file. Removed the later snippet. Change-Id: I4f35a8322034b00e9b5f5d6c6d96e652f11f8384 Reviewed-by: Thiago Macieira --- .../snippets/code/src_gui_graphicsview_qgraphicsitem.cpp | 15 --------------- src/widgets/graphicsview/qgraphicsitem.cpp | 2 +- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp b/src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp index cef2552e75..d7e2a3f465 100644 --- a/src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp +++ b/src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp @@ -245,21 +245,6 @@ scene->destroyItemGroup(group); //! [17] -//! [QGraphicsItem type] -class CustomItem : public QGraphicsItem -{ - ... - enum { Type = UserType + 1 }; - - int type() const - { - // Enable the use of qgraphicsitem_cast with this item. - return Type; - } - ... -}; -//! [QGraphicsItem type] - //! [18] class QGraphicsPathItem : public QAbstractGraphicsShapeItem { diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp index 03f22a270f..a543445244 100644 --- a/src/widgets/graphicsview/qgraphicsitem.cpp +++ b/src/widgets/graphicsview/qgraphicsitem.cpp @@ -6592,7 +6592,7 @@ void QGraphicsItem::setData(int key, const QVariant &value) For example: - \snippet code/src_gui_graphicsview_qgraphicsitem.cpp QGraphicsItem type + \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 1 \sa UserType */ -- cgit v1.2.3 From 7d2357b0a8911191451fd89279ba30e5fd6ccb84 Mon Sep 17 00:00:00 2001 From: Benjamin Summerton Date: Tue, 9 Dec 2014 23:17:19 -0500 Subject: Fixed small bug in code snippet for QGraphicsItem If the enumeration "Type" isn't declared in the public scope, it will cause an issue upon compilation. Previously, it was ambiguous on which access level this should be in. Snippet [18] though has the enumeration in the correct access level. Change-Id: If699df80def3e1b09d8d82df74c4ca85eba003d2 Reviewed-by: Thiago Macieira --- src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp b/src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp index d7e2a3f465..37b4a00e8e 100644 --- a/src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp +++ b/src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp @@ -61,7 +61,7 @@ public: //! [1] class CustomItem : public QGraphicsItem { - ... +public: enum { Type = UserType + 1 }; int type() const -- cgit v1.2.3 From f17d7a124f0fa817a7e1a2dda6f48098432c0dc0 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 8 Dec 2014 13:35:47 +0100 Subject: Use categorized logging for ssl code Place all debug output into the 'qt.network.ssl' category. This allows people to disable certain warnings at runtime. Task-number: QTBUG-43173 Change-Id: Ide731fae3109f9cd7730cc096ee069a5b99d35f1 Reviewed-by: Richard J. Moore --- src/network/ssl/qssl.cpp | 3 + src/network/ssl/qssl_p.h | 58 ++++++++++++++++ src/network/ssl/qsslcertificate.cpp | 3 +- src/network/ssl/qsslcertificate_openssl.cpp | 9 +-- src/network/ssl/qsslcertificate_qt.cpp | 7 +- src/network/ssl/qsslconfiguration.cpp | 4 +- src/network/ssl/qsslcontext_openssl.cpp | 11 ++-- src/network/ssl/qsslkey_winrt.cpp | 3 +- src/network/ssl/qsslsocket.cpp | 73 +++++++++++---------- src/network/ssl/qsslsocket_openssl.cpp | 91 +++++++++++++------------- src/network/ssl/qsslsocket_openssl_symbols.cpp | 17 ++--- src/network/ssl/qsslsocket_winrt.cpp | 11 ++-- src/network/ssl/ssl.pri | 1 + 13 files changed, 185 insertions(+), 106 deletions(-) create mode 100644 src/network/ssl/qssl_p.h diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp index 740131797c..98be348e19 100644 --- a/src/network/ssl/qssl.cpp +++ b/src/network/ssl/qssl.cpp @@ -33,9 +33,12 @@ #include "qsslkey.h" +#include "qssl_p.h" QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl"); + /*! \namespace QSsl \brief The QSsl namespace declares enums common to all SSL classes in Qt Network. diff --git a/src/network/ssl/qssl_p.h b/src/network/ssl/qssl_p.h new file mode 100644 index 0000000000..91bd8c8e6f --- /dev/null +++ b/src/network/ssl/qssl_p.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QSSL_P_H +#define QSSL_P_H + + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qsslcertificate.cpp. This header file may change from version to version +// without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(lcSsl) + +QT_END_NAMESPACE + +#endif // QSSL_P_H diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 125a7a0250..c34d16a37a 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -112,6 +112,7 @@ #include "qsslsocket_winrt_p.h" #endif +#include "qssl_p.h" #include "qsslcertificate.h" #include "qsslcertificate_p.h" #include "qsslkey_p.h" @@ -524,7 +525,7 @@ QList QSslCertificate::fromPath(const QString &path, QList QSslCertificate::fromDevice(QIODevice *device, QSsl::EncodingFormat format) { if (!device) { - qWarning("QSslCertificate::fromDevice: cannot read from a null device"); + qCWarning(lcSsl, "QSslCertificate::fromDevice: cannot read from a null device"); return QList(); } return fromData(device->readAll(), format); diff --git a/src/network/ssl/qsslcertificate_openssl.cpp b/src/network/ssl/qsslcertificate_openssl.cpp index 1906c72ff8..065f0bfd04 100644 --- a/src/network/ssl/qsslcertificate_openssl.cpp +++ b/src/network/ssl/qsslcertificate_openssl.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "qssl_p.h" #include "qsslsocket_openssl_symbols_p.h" #include "qsslcertificate_p.h" #include "qsslkey_p.h" @@ -303,7 +304,7 @@ static QVariant x509UnknownExtensionToValue(X509_EXTENSION *ext) else return list; } else if (meth->i2s && ext_internal) { - //qDebug() << meth->i2s(meth, ext_internal); + //qCDebug(lcSsl) << meth->i2s(meth, ext_internal); QVariant result(QString::fromUtf8(meth->i2s(meth, ext_internal))); return result; } else if (meth->i2r && ext_internal) { @@ -371,7 +372,7 @@ static QVariant x509ExtensionToValue(X509_EXTENSION *ext) result[QString::fromUtf8(QSslCertificatePrivate::asn1ObjectName(ad->method))] = uri; } else { - qWarning() << "Strange location type" << name->type; + qCWarning(lcSsl) << "Strange location type" << name->type; } } @@ -516,7 +517,7 @@ void QSslCertificatePrivate::init(const QByteArray &data, QSsl::EncodingFormat f QByteArray QSslCertificatePrivate::QByteArray_from_X509(X509 *x509, QSsl::EncodingFormat format) { if (!x509) { - qWarning("QSslSocketBackendPrivate::X509_to_QByteArray: null X509"); + qCWarning(lcSsl, "QSslSocketBackendPrivate::X509_to_QByteArray: null X509"); return QByteArray(); } @@ -551,7 +552,7 @@ QByteArray QSslCertificatePrivate::QByteArray_from_X509(X509 *x509, QSsl::Encodi QString QSslCertificatePrivate::text_from_X509(X509 *x509) { if (!x509) { - qWarning("QSslSocketBackendPrivate::text_from_X509: null X509"); + qCWarning(lcSsl, "QSslSocketBackendPrivate::text_from_X509: null X509"); return QString(); } diff --git a/src/network/ssl/qsslcertificate_qt.cpp b/src/network/ssl/qsslcertificate_qt.cpp index d74042a95f..cf99e77314 100644 --- a/src/network/ssl/qsslcertificate_qt.cpp +++ b/src/network/ssl/qsslcertificate_qt.cpp @@ -40,7 +40,7 @@ ****************************************************************************/ - +#include "qssl_p.h" #include "qsslcertificate.h" #include "qsslcertificate_p.h" #include "qsslkey.h" @@ -83,8 +83,9 @@ bool QSslCertificate::isSelfSigned() const if (d->null) return false; - qWarning("QSslCertificate::isSelfSigned: This function does not check, whether the certificate " - "is actually signed. It just checks whether issuer and subject are identical"); + qCWarning(lcSsl, + "QSslCertificate::isSelfSigned: This function does not check, whether the certificate " + "is actually signed. It just checks whether issuer and subject are identical"); return d->subjectMatchesIssuer; } diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp index 2aa59e5d18..7bb6e02b7e 100644 --- a/src/network/ssl/qsslconfiguration.cpp +++ b/src/network/ssl/qsslconfiguration.cpp @@ -32,6 +32,7 @@ ** ****************************************************************************/ +#include "qssl_p.h" #include "qsslconfiguration.h" #include "qsslconfiguration_p.h" #include "qsslsocket.h" @@ -341,7 +342,8 @@ int QSslConfiguration::peerVerifyDepth() const void QSslConfiguration::setPeerVerifyDepth(int depth) { if (depth < 0) { - qWarning("QSslConfiguration::setPeerVerifyDepth: cannot set negative depth of %d", depth); + qCWarning(lcSsl, + "QSslConfiguration::setPeerVerifyDepth: cannot set negative depth of %d", depth); return; } d->peerVerifyDepth = depth; diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp index c042d98056..92e726bc01 100644 --- a/src/network/ssl/qsslcontext_openssl.cpp +++ b/src/network/ssl/qsslcontext_openssl.cpp @@ -36,6 +36,7 @@ #include #include +#include "private/qssl_p.h" #include "private/qsslcontext_openssl_p.h" #include "private/qsslsocket_p.h" #include "private/qsslsocket_openssl_p.h" @@ -357,7 +358,7 @@ static int next_proto_cb(SSL *, unsigned char **out, unsigned char *outlen, ctx->status = QSslConfiguration::NextProtocolNegotiationUnsupported; break; default: - qWarning("OpenSSL sent unknown NPN status"); + qCWarning(lcSsl, "OpenSSL sent unknown NPN status"); } return SSL_TLSEXT_ERR_OK; @@ -384,7 +385,7 @@ SSL* QSslContext::createSsl() if (session) { // Try to resume the last session we cached if (!q_SSL_set_session(ssl, session)) { - qWarning("could not set SSL session"); + qCWarning(lcSsl, "could not set SSL session"); q_SSL_SESSION_free(session); session = 0; } @@ -396,8 +397,8 @@ SSL* QSslContext::createSsl() m_supportedNPNVersions.clear(); for (int a = 0; a < protocols.count(); ++a) { if (protocols.at(a).size() > 255) { - qWarning() << "TLS NPN extension" << protocols.at(a) - << "is too long and will be truncated to 255 characters."; + qCWarning(lcSsl) << "TLS NPN extension" << protocols.at(a) + << "is too long and will be truncated to 255 characters."; protocols[a] = protocols.at(a).left(255); } m_supportedNPNVersions.append(protocols.at(a).size()).append(protocols.at(a)); @@ -433,7 +434,7 @@ bool QSslContext::cacheSession(SSL* ssl) m_sessionASN1.resize(sessionSize); unsigned char *data = reinterpret_cast(m_sessionASN1.data()); if (!q_i2d_SSL_SESSION(session, &data)) - qWarning("could not store persistent version of SSL session"); + qCWarning(lcSsl, "could not store persistent version of SSL session"); m_sessionTicketLifeTimeHint = session->tlsext_tick_lifetime_hint; } } diff --git a/src/network/ssl/qsslkey_winrt.cpp b/src/network/ssl/qsslkey_winrt.cpp index c5b4146ee9..2ec75caefe 100644 --- a/src/network/ssl/qsslkey_winrt.cpp +++ b/src/network/ssl/qsslkey_winrt.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "qssl_p.h" #include "qsslkey.h" #include "qsslkey_p.h" #include "qsslcertificate_p.h" @@ -144,7 +145,7 @@ static QByteArray doCrypt(QSslKeyPrivate::Cipher cipher, QByteArray data, const if (padding > 0 && padding <= blockLength) resultLength -= padding; else - qWarning("Invalid padding length of %u; decryption likely failed.", padding); + qCWarning(lcSsl, "Invalid padding length of %u; decryption likely failed.", padding); } return QByteArray(reinterpret_cast(resultData), resultLength); diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 8887f478dd..31c7b3087e 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -281,6 +281,7 @@ \sa peerVerifyError() */ +#include "qssl_p.h" #include "qsslsocket.h" #include "qsslcipher.h" #ifndef QT_NO_OPENSSL @@ -334,7 +335,7 @@ QSslSocket::QSslSocket(QObject *parent) { Q_D(QSslSocket); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::QSslSocket(" << parent << "), this =" << (void *)this; + qCDebug(lcSsl) << "QSslSocket::QSslSocket(" << parent << "), this =" << (void *)this; #endif d->q_ptr = this; d->init(); @@ -347,7 +348,7 @@ QSslSocket::~QSslSocket() { Q_D(QSslSocket); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::~QSslSocket(), this =" << (void *)this; + qCDebug(lcSsl) << "QSslSocket::~QSslSocket(), this =" << (void *)this; #endif delete d->plainSocket; d->plainSocket = 0; @@ -416,7 +417,8 @@ void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port, O { Q_D(QSslSocket); if (d->state == ConnectedState || d->state == ConnectingState) { - qWarning("QSslSocket::connectToHostEncrypted() called when already connecting/connected"); + qCWarning(lcSsl, + "QSslSocket::connectToHostEncrypted() called when already connecting/connected"); return; } @@ -446,7 +448,8 @@ void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port, { Q_D(QSslSocket); if (d->state == ConnectedState || d->state == ConnectingState) { - qWarning("QSslSocket::connectToHostEncrypted() called when already connecting/connected"); + qCWarning(lcSsl, + "QSslSocket::connectToHostEncrypted() called when already connecting/connected"); return; } @@ -476,7 +479,7 @@ bool QSslSocket::setSocketDescriptor(qintptr socketDescriptor, SocketState state { Q_D(QSslSocket); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::setSocketDescriptor(" << socketDescriptor << ',' + qCDebug(lcSsl) << "QSslSocket::setSocketDescriptor(" << socketDescriptor << ',' << state << ',' << openMode << ')'; #endif if (!d->plainSocket) @@ -660,7 +663,7 @@ void QSslSocket::setPeerVerifyDepth(int depth) { Q_D(QSslSocket); if (depth < 0) { - qWarning("QSslSocket::setPeerVerifyDepth: cannot set negative depth of %d", depth); + qCWarning(lcSsl, "QSslSocket::setPeerVerifyDepth: cannot set negative depth of %d", depth); return; } d->configuration.peerVerifyDepth = depth; @@ -771,7 +774,7 @@ bool QSslSocket::canReadLine() const void QSslSocket::close() { #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::close()"; + qCDebug(lcSsl) << "QSslSocket::close()"; #endif Q_D(QSslSocket); if (encryptedBytesToWrite()) @@ -815,7 +818,7 @@ bool QSslSocket::flush() { Q_D(QSslSocket); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::flush()"; + qCDebug(lcSsl) << "QSslSocket::flush()"; #endif if (d->mode != UnencryptedMode) // encrypt any unencrypted bytes in our buffer @@ -849,7 +852,7 @@ void QSslSocket::abort() { Q_D(QSslSocket); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::abort()"; + qCDebug(lcSsl) << "QSslSocket::abort()"; #endif if (d->plainSocket) d->plainSocket->abort(); @@ -1605,7 +1608,7 @@ bool QSslSocket::waitForDisconnected(int msecs) // require calling connectToHost() before waitForDisconnected() if (state() == UnconnectedState) { - qWarning("QSslSocket::waitForDisconnected() is not allowed in UnconnectedState"); + qCWarning(lcSsl, "QSslSocket::waitForDisconnected() is not allowed in UnconnectedState"); return false; } @@ -1721,15 +1724,17 @@ void QSslSocket::startClientEncryption() { Q_D(QSslSocket); if (d->mode != UnencryptedMode) { - qWarning("QSslSocket::startClientEncryption: cannot start handshake on non-plain connection"); + qCWarning(lcSsl, + "QSslSocket::startClientEncryption: cannot start handshake on non-plain connection"); return; } if (state() != ConnectedState) { - qWarning("QSslSocket::startClientEncryption: cannot start handshake when not connected"); + qCWarning(lcSsl, + "QSslSocket::startClientEncryption: cannot start handshake when not connected"); return; } #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::startClientEncryption()"; + qCDebug(lcSsl) << "QSslSocket::startClientEncryption()"; #endif d->mode = SslClientMode; emit modeChanged(d->mode); @@ -1760,11 +1765,11 @@ void QSslSocket::startServerEncryption() { Q_D(QSslSocket); if (d->mode != UnencryptedMode) { - qWarning("QSslSocket::startServerEncryption: cannot start handshake on non-plain connection"); + qCWarning(lcSsl, "QSslSocket::startServerEncryption: cannot start handshake on non-plain connection"); return; } #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::startServerEncryption()"; + qCDebug(lcSsl) << "QSslSocket::startServerEncryption()"; #endif d->mode = SslServerMode; emit modeChanged(d->mode); @@ -1841,12 +1846,12 @@ void QSslSocket::connectToHost(const QString &hostName, quint16 port, OpenMode o d->initialized = false; #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::connectToHost(" + qCDebug(lcSsl) << "QSslSocket::connectToHost(" << hostName << ',' << port << ',' << openMode << ')'; #endif if (!d->plainSocket) { #ifdef QSSLSOCKET_DEBUG - qDebug() << "\tcreating internal plain socket"; + qCDebug(lcSsl) << "\tcreating internal plain socket"; #endif d->createPlainSocket(openMode); } @@ -1865,7 +1870,7 @@ void QSslSocket::disconnectFromHost() { Q_D(QSslSocket); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::disconnectFromHost()"; + qCDebug(lcSsl) << "QSslSocket::disconnectFromHost()"; #endif if (!d->plainSocket) return; @@ -1909,7 +1914,7 @@ qint64 QSslSocket::readData(char *data, qint64 maxlen) if (d->mode == UnencryptedMode && !d->autoStartHandshake) { readBytes = d->plainSocket->read(data, maxlen); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::readData(" << (void *)data << ',' << maxlen << ") ==" + qCDebug(lcSsl) << "QSslSocket::readData(" << (void *)data << ',' << maxlen << ") ==" << readBytes; #endif } else { @@ -1928,7 +1933,7 @@ qint64 QSslSocket::writeData(const char *data, qint64 len) { Q_D(QSslSocket); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::writeData(" << (void *)data << ',' << len << ')'; + qCDebug(lcSsl) << "QSslSocket::writeData(" << (void *)data << ',' << len << ')'; #endif if (d->mode == UnencryptedMode && !d->autoStartHandshake) return d->plainSocket->write(data, len); @@ -2231,10 +2236,10 @@ void QSslSocketPrivate::_q_connectedSlot() cachedSocketDescriptor = plainSocket->socketDescriptor(); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::_q_connectedSlot()"; - qDebug() << "\tstate =" << q->state(); - qDebug() << "\tpeer =" << q->peerName() << q->peerAddress() << q->peerPort(); - qDebug() << "\tlocal =" << QHostInfo::fromName(q->localAddress().toString()).hostName() + qCDebug(lcSsl) << "QSslSocket::_q_connectedSlot()"; + qCDebug(lcSsl) << "\tstate =" << q->state(); + qCDebug(lcSsl) << "\tpeer =" << q->peerName() << q->peerAddress() << q->peerPort(); + qCDebug(lcSsl) << "\tlocal =" << QHostInfo::fromName(q->localAddress().toString()).hostName() << q->localAddress() << q->localPort(); #endif @@ -2256,8 +2261,8 @@ void QSslSocketPrivate::_q_hostFoundSlot() { Q_Q(QSslSocket); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::_q_hostFoundSlot()"; - qDebug() << "\tstate =" << q->state(); + qCDebug(lcSsl) << "QSslSocket::_q_hostFoundSlot()"; + qCDebug(lcSsl) << "\tstate =" << q->state(); #endif emit q->hostFound(); } @@ -2269,8 +2274,8 @@ void QSslSocketPrivate::_q_disconnectedSlot() { Q_Q(QSslSocket); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::_q_disconnectedSlot()"; - qDebug() << "\tstate =" << q->state(); + qCDebug(lcSsl) << "QSslSocket::_q_disconnectedSlot()"; + qCDebug(lcSsl) << "\tstate =" << q->state(); #endif disconnected(); emit q->disconnected(); @@ -2283,7 +2288,7 @@ void QSslSocketPrivate::_q_stateChangedSlot(QAbstractSocket::SocketState state) { Q_Q(QSslSocket); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::_q_stateChangedSlot(" << state << ')'; + qCDebug(lcSsl) << "QSslSocket::_q_stateChangedSlot(" << state << ')'; #endif q->setSocketState(state); emit q->stateChanged(state); @@ -2296,9 +2301,9 @@ void QSslSocketPrivate::_q_errorSlot(QAbstractSocket::SocketError error) { Q_Q(QSslSocket); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::_q_errorSlot(" << error << ')'; - qDebug() << "\tstate =" << q->state(); - qDebug() << "\terrorString =" << q->errorString(); + qCDebug(lcSsl) << "QSslSocket::_q_errorSlot(" << error << ')'; + qCDebug(lcSsl) << "\tstate =" << q->state(); + qCDebug(lcSsl) << "\terrorString =" << q->errorString(); #endif q->setSocketError(plainSocket->error()); q->setErrorString(plainSocket->errorString()); @@ -2312,7 +2317,7 @@ void QSslSocketPrivate::_q_readyReadSlot() { Q_Q(QSslSocket); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::_q_readyReadSlot() -" << plainSocket->bytesAvailable() << "bytes available"; + qCDebug(lcSsl) << "QSslSocket::_q_readyReadSlot() -" << plainSocket->bytesAvailable() << "bytes available"; #endif if (mode == QSslSocket::UnencryptedMode) { if (readyReadEmittedPointer) @@ -2331,7 +2336,7 @@ void QSslSocketPrivate::_q_bytesWrittenSlot(qint64 written) { Q_Q(QSslSocket); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocket::_q_bytesWrittenSlot(" << written << ')'; + qCDebug(lcSsl) << "QSslSocket::_q_bytesWrittenSlot(" << written << ')'; #endif if (mode == QSslSocket::UnencryptedMode) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 13fc534259..8833e3fdd8 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -49,6 +49,7 @@ //#define QSSLSOCKET_DEBUG //#define QT_DECRYPT_SSL_TRAFFIC +#include "qssl_p.h" #include "qsslsocket_openssl_p.h" #include "qsslsocket_openssl_symbols_p.h" #include "qsslsocket.h" @@ -250,24 +251,24 @@ int q_X509Callback(int ok, X509_STORE_CTX *ctx) // Store the error and at which depth the error was detected. _q_sslErrorList()->errors << qMakePair(q_X509_STORE_CTX_get_error(ctx), q_X509_STORE_CTX_get_error_depth(ctx)); #ifdef QSSLSOCKET_DEBUG - qDebug() << "verification error: dumping bad certificate"; - qDebug() << QSslCertificatePrivate::QSslCertificate_from_X509(q_X509_STORE_CTX_get_current_cert(ctx)).toPem(); - qDebug() << "dumping chain"; + qCDebug(lcSsl) << "verification error: dumping bad certificate"; + qCDebug(lcSsl) << QSslCertificatePrivate::QSslCertificate_from_X509(q_X509_STORE_CTX_get_current_cert(ctx)).toPem(); + qCDebug(lcSsl) << "dumping chain"; foreach (QSslCertificate cert, QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(q_X509_STORE_CTX_get_chain(ctx))) { QString certFormat(QStringLiteral("O=%1 CN=%2 L=%3 OU=%4 C=%5 ST=%6")); - qDebug() << "Issuer:" << "O=" << cert.issuerInfo(QSslCertificate::Organization) + qCDebug(lcSsl) << "Issuer:" << "O=" << cert.issuerInfo(QSslCertificate::Organization) << "CN=" << cert.issuerInfo(QSslCertificate::CommonName) << "L=" << cert.issuerInfo(QSslCertificate::LocalityName) << "OU=" << cert.issuerInfo(QSslCertificate::OrganizationalUnitName) << "C=" << cert.issuerInfo(QSslCertificate::CountryName) << "ST=" << cert.issuerInfo(QSslCertificate::StateOrProvinceName); - qDebug() << "Subject:" << "O=" << cert.subjectInfo(QSslCertificate::Organization) + qCDebug(lcSsl) << "Subject:" << "O=" << cert.subjectInfo(QSslCertificate::Organization) << "CN=" << cert.subjectInfo(QSslCertificate::CommonName) << "L=" << cert.subjectInfo(QSslCertificate::LocalityName) << "OU=" << cert.subjectInfo(QSslCertificate::OrganizationalUnitName) << "C=" << cert.subjectInfo(QSslCertificate::CountryName) << "ST=" << cert.subjectInfo(QSslCertificate::StateOrProvinceName); - qDebug() << "Valid:" << cert.effectiveDate() << "-" << cert.expiryDate(); + qCDebug(lcSsl) << "Valid:" << cert.effectiveDate() << "-" << cert.expiryDate(); } #endif } @@ -361,7 +362,7 @@ bool QSslSocketBackendPrivate::initSslContext() && !QHostAddress().setAddress(tlsHostName) && !(configuration.sslOptions & QSsl::SslOptionDisableServerNameIndication)) { if (!q_SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, ace.data())) - qWarning("could not set SSL_CTRL_SET_TLSEXT_HOSTNAME, Server Name Indication disabled"); + qCWarning(lcSsl, "could not set SSL_CTRL_SET_TLSEXT_HOSTNAME, Server Name Indication disabled"); } } #endif @@ -487,16 +488,16 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded() if (securityLib.load()) { ptrSecCertificateCopyData = (PtrSecCertificateCopyData) securityLib.resolve("SecCertificateCopyData"); if (!ptrSecCertificateCopyData) - qWarning("could not resolve symbols in security library"); // should never happen + qCWarning(lcSsl, "could not resolve symbols in security library"); // should never happen ptrSecTrustSettingsCopyCertificates = (PtrSecTrustSettingsCopyCertificates) securityLib.resolve("SecTrustSettingsCopyCertificates"); if (!ptrSecTrustSettingsCopyCertificates) { // method was introduced in Leopard, use legacy method if it's not there ptrSecTrustCopyAnchorCertificates = (PtrSecTrustCopyAnchorCertificates) securityLib.resolve("SecTrustCopyAnchorCertificates"); if (!ptrSecTrustCopyAnchorCertificates) - qWarning("could not resolve symbols in security library"); // should never happen + qCWarning(lcSsl, "could not resolve symbols in security library"); // should never happen } } else { - qWarning("could not load security library"); + qCWarning(lcSsl, "could not load security library"); } #elif defined(Q_OS_WIN) HINSTANCE hLib = LoadLibraryW(L"Crypt32"); @@ -511,9 +512,9 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded() ptrCertCloseStore = (PtrCertCloseStore)GetProcAddress(hLib, "CertCloseStore"); #endif if (!ptrCertOpenSystemStoreW || !ptrCertFindCertificateInStore || !ptrCertCloseStore) - qWarning("could not resolve symbols in crypt32 library"); // should never happen + qCWarning(lcSsl, "could not resolve symbols in crypt32 library"); // should never happen } else { - qWarning("could not load crypt32 library"); // should never happen + qCWarning(lcSsl, "could not load crypt32 library"); // should never happen } #elif defined(Q_OS_QNX) s_loadRootCertsOnDemand = true; @@ -657,7 +658,7 @@ QList QSslSocketPrivate::systemCaCertificates() data = ptrSecCertificateCopyData(cfCert); if (data == NULL) { - qWarning("error retrieving a CA certificate from the system store"); + qCWarning(lcSsl, "error retrieving a CA certificate from the system store"); } else { QByteArray rawCert = QByteArray::fromRawData((const char *)CFDataGetBytePtr(data), CFDataGetLength(data)); systemCerts.append(QSslCertificate::fromData(rawCert, QSsl::Der)); @@ -668,7 +669,7 @@ QList QSslSocketPrivate::systemCaCertificates() } else { // no detailed error handling here - qWarning("could not retrieve system CA certificates"); + qCWarning(lcSsl, "could not retrieve system CA certificates"); } } #elif defined(Q_OS_WIN) @@ -742,8 +743,8 @@ QList QSslSocketPrivate::systemCaCertificates() } #endif #ifdef QSSLSOCKET_DEBUG - qDebug() << "systemCaCertificates retrieval time " << timer.elapsed() << "ms"; - qDebug() << "imported " << systemCerts.count() << " certificates"; + qCDebug(lcSsl) << "systemCaCertificates retrieval time " << timer.elapsed() << "ms"; + qCDebug(lcSsl) << "imported " << systemCerts.count() << " certificates"; #endif return systemCerts; @@ -824,7 +825,7 @@ void QSslSocketBackendPrivate::transmit() } } #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocketBackendPrivate::transmit: encrypted" << writtenBytes << "bytes"; + qCDebug(lcSsl) << "QSslSocketBackendPrivate::transmit: encrypted" << writtenBytes << "bytes"; #endif writeBuffer.free(writtenBytes); totalBytesWritten += writtenBytes; @@ -857,7 +858,7 @@ void QSslSocketBackendPrivate::transmit() // Write encrypted data from the buffer to the socket. qint64 actualWritten = plainSocket->write(data.constData(), encryptedBytesRead); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocketBackendPrivate::transmit: wrote" << encryptedBytesRead << "encrypted bytes to the socket" << actualWritten << "actual."; + qCDebug(lcSsl) << "QSslSocketBackendPrivate::transmit: wrote" << encryptedBytesRead << "encrypted bytes to the socket" << actualWritten << "actual."; #endif if (actualWritten < 0) { //plain socket write fails if it was in the pending close state. @@ -878,7 +879,7 @@ void QSslSocketBackendPrivate::transmit() int encryptedBytesRead = plainSocket->peek(data.data(), pendingBytes); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocketBackendPrivate::transmit: read" << encryptedBytesRead << "encrypted bytes from the socket"; + qCDebug(lcSsl) << "QSslSocketBackendPrivate::transmit: read" << encryptedBytesRead << "encrypted bytes from the socket"; #endif // Write encrypted data from the buffer into the read BIO. int writtenToBio = q_BIO_write(readBio, data.constData(), encryptedBytesRead); @@ -902,17 +903,17 @@ void QSslSocketBackendPrivate::transmit() // connect / accept. if (!connectionEncrypted) { #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocketBackendPrivate::transmit: testing encryption"; + qCDebug(lcSsl) << "QSslSocketBackendPrivate::transmit: testing encryption"; #endif if (startHandshake()) { #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocketBackendPrivate::transmit: encryption established"; + qCDebug(lcSsl) << "QSslSocketBackendPrivate::transmit: encryption established"; #endif connectionEncrypted = true; transmitting = true; } else if (plainSocket->state() != QAbstractSocket::ConnectedState) { #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocketBackendPrivate::transmit: connection lost"; + qCDebug(lcSsl) << "QSslSocketBackendPrivate::transmit: connection lost"; #endif break; } else if (paused) { @@ -920,7 +921,7 @@ void QSslSocketBackendPrivate::transmit() return; } else { #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocketBackendPrivate::transmit: encryption not done yet"; + qCDebug(lcSsl) << "QSslSocketBackendPrivate::transmit: encryption not done yet"; #endif } } @@ -941,7 +942,7 @@ void QSslSocketBackendPrivate::transmit() // Don't use SSL_pending(). It's very unreliable. if ((readBytes = q_SSL_read(ssl, data.data(), data.size())) > 0) { #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocketBackendPrivate::transmit: decrypted" << readBytes << "bytes"; + qCDebug(lcSsl) << "QSslSocketBackendPrivate::transmit: decrypted" << readBytes << "bytes"; #endif char *ptr = buffer.reserve(readBytes); ::memcpy(ptr, data.data(), readBytes); @@ -962,7 +963,7 @@ void QSslSocketBackendPrivate::transmit() case SSL_ERROR_ZERO_RETURN: // The remote host closed the connection. #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocketBackendPrivate::transmit: remote disconnect"; + qCDebug(lcSsl) << "QSslSocketBackendPrivate::transmit: remote disconnect"; #endif shutdown = true; // the other side shut down, make sure we do not send shutdown ourselves q->setErrorString(QSslSocket::tr("The TLS/SSL connection has been closed")); @@ -1081,7 +1082,7 @@ bool QSslSocketBackendPrivate::startHandshake() q->setErrorString(QSslSocket::tr("Error during SSL handshake: %1").arg(getErrorsFromOpenSsl())); q->setSocketError(QAbstractSocket::SslHandshakeFailedError); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QSslSocketBackendPrivate::startHandshake: error!" << q->errorString(); + qCDebug(lcSsl) << "QSslSocketBackendPrivate::startHandshake: error!" << q->errorString(); #endif emit q->error(QAbstractSocket::SslHandshakeFailedError); q->abort(); @@ -1184,7 +1185,7 @@ bool QSslSocketBackendPrivate::startHandshake() break; default: #ifdef QSSLSOCKET_DEBUG - qDebug() << sslErrors.at(i).errorString(); + qCDebug(lcSsl) << sslErrors.at(i).errorString(); #endif break; } @@ -1318,7 +1319,7 @@ void QWindowsCaRootFetcher::start() PCCERT_CONTEXT wincert = CertCreateCertificateContext(X509_ASN_ENCODING, (const BYTE *)der.constData(), der.length()); if (!wincert) { #ifdef QSSLSOCKET_DEBUG - qDebug("QWindowsCaRootFetcher failed to convert certificate to windows form"); + qCDebug(lcSsl, "QWindowsCaRootFetcher failed to convert certificate to windows form"); #endif emit finished(cert, QSslCertificate()); deleteLater(); @@ -1349,32 +1350,32 @@ void QWindowsCaRootFetcher::start() 0, //reserved &chain); #ifdef QSSLSOCKET_DEBUG - qDebug() << "QWindowsCaRootFetcher" << stopwatch.elapsed() << "ms to get chain"; + qCDebug(lcSsl) << "QWindowsCaRootFetcher" << stopwatch.elapsed() << "ms to get chain"; #endif QSslCertificate trustedRoot; if (result) { #ifdef QSSLSOCKET_DEBUG - qDebug() << "QWindowsCaRootFetcher - examining windows chains"; + qCDebug(lcSsl) << "QWindowsCaRootFetcher - examining windows chains"; if (chain->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR) - qDebug() << " - TRUSTED"; + qCDebug(lcSsl) << " - TRUSTED"; else - qDebug() << " - NOT TRUSTED" << chain->TrustStatus.dwErrorStatus; + qCDebug(lcSsl) << " - NOT TRUSTED" << chain->TrustStatus.dwErrorStatus; if (chain->TrustStatus.dwInfoStatus & CERT_TRUST_IS_SELF_SIGNED) - qDebug() << " - SELF SIGNED"; - qDebug() << "QSslSocketBackendPrivate::fetchCaRootForCert - dumping simple chains"; + qCDebug(lcSsl) << " - SELF SIGNED"; + qCDebug(lcSsl) << "QSslSocketBackendPrivate::fetchCaRootForCert - dumping simple chains"; for (unsigned int i = 0; i < chain->cChain; i++) { if (chain->rgpChain[i]->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR) - qDebug() << " - TRUSTED SIMPLE CHAIN" << i; + qCDebug(lcSsl) << " - TRUSTED SIMPLE CHAIN" << i; else - qDebug() << " - UNTRUSTED SIMPLE CHAIN" << i << "reason:" << chain->rgpChain[i]->TrustStatus.dwErrorStatus; + qCDebug(lcSsl) << " - UNTRUSTED SIMPLE CHAIN" << i << "reason:" << chain->rgpChain[i]->TrustStatus.dwErrorStatus; for (unsigned int j = 0; j < chain->rgpChain[i]->cElement; j++) { QSslCertificate foundCert(QByteArray((const char *)chain->rgpChain[i]->rgpElement[j]->pCertContext->pbCertEncoded , chain->rgpChain[i]->rgpElement[j]->pCertContext->cbCertEncoded), QSsl::Der); - qDebug() << " - " << foundCert; + qCDebug(lcSsl) << " - " << foundCert; } } - qDebug() << " - and" << chain->cLowerQualityChainContext << "low quality chains"; //expect 0, we haven't asked for them + qCDebug(lcSsl) << " - and" << chain->cLowerQualityChainContext << "low quality chains"; //expect 0, we haven't asked for them #endif //based on http://msdn.microsoft.com/en-us/library/windows/desktop/aa377182%28v=vs.85%29.aspx @@ -1493,12 +1494,12 @@ void QSslSocketBackendPrivate::continueHandshake() QString sslKeyFile = QDir::tempPath() + QLatin1String("/qt-ssl-keys"); QFile file(sslKeyFile); if (!file.open(QIODevice::Append)) - qWarning() << "could not open file" << sslKeyFile << "for appending"; + qCWarning(lcSsl) << "could not open file" << sslKeyFile << "for appending"; if (!file.write(debugLineClientRandom)) - qWarning() << "could not write to file" << sslKeyFile; + qCWarning(lcSsl) << "could not write to file" << sslKeyFile; file.close(); } else { - qWarning("could not decrypt SSL traffic"); + qCWarning(lcSsl, "could not decrypt SSL traffic"); } #endif @@ -1557,7 +1558,7 @@ QList QSslSocketBackendPrivate::verify(QList certifi // Setup the store with the default CA certificates X509_STORE *certStore = q_X509_STORE_new(); if (!certStore) { - qWarning() << "Unable to create certificate store"; + qCWarning(lcSsl) << "Unable to create certificate store"; errors << QSslError(QSslError::UnspecifiedError); return errors; } @@ -1694,7 +1695,7 @@ bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device, // Create the PKCS#12 object PKCS12 *p12 = q_d2i_PKCS12_bio(bio, 0); if (!p12) { - qWarning("Unable to read PKCS#12 structure, %s", q_ERR_error_string(q_ERR_get_error(), 0)); + qCWarning(lcSsl, "Unable to read PKCS#12 structure, %s", q_ERR_error_string(q_ERR_get_error(), 0)); q_BIO_free(bio); return false; } @@ -1705,7 +1706,7 @@ bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device, STACK_OF(X509) *ca = 0; if (!q_PKCS12_parse(p12, passPhrase.constData(), &pkey, &x509, &ca)) { - qWarning("Unable to parse PKCS#12 structure, %s", q_ERR_error_string(q_ERR_get_error(), 0)); + qCWarning(lcSsl, "Unable to parse PKCS#12 structure, %s", q_ERR_error_string(q_ERR_get_error(), 0)); q_PKCS12_free(p12); q_BIO_free(bio); return false; @@ -1713,7 +1714,7 @@ bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device, // Convert to Qt types if (!key->d->fromEVP_PKEY(pkey)) { - qWarning("Unable to convert private key"); + qCWarning(lcSsl, "Unable to convert private key"); q_sk_pop_free(reinterpret_cast(ca), reinterpret_cast(q_sk_free)); q_X509_free(x509); q_EVP_PKEY_free(pkey); diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 71b8237e03..ea6e84adef 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -47,6 +47,7 @@ ** ****************************************************************************/ +#include "qssl_p.h" #include "qsslsocket_openssl_symbols_p.h" #ifdef Q_OS_WIN @@ -115,12 +116,12 @@ QT_BEGIN_NAMESPACE namespace { void qsslSocketUnresolvedSymbolWarning(const char *functionName) { - qWarning("QSslSocket: cannot call unresolved function %s", functionName); + qCWarning(lcSsl, "QSslSocket: cannot call unresolved function %s", functionName); } void qsslSocketCannotResolveSymbolWarning(const char *functionName) { - qWarning("QSslSocket: cannot resolve %s", functionName); + qCWarning(lcSsl, "QSslSocket: cannot resolve %s", functionName); } } @@ -388,11 +389,11 @@ DEFINEFUNC(void, PKCS12_free, PKCS12 *pkcs12, pkcs12, return, DUMMYARG) #ifdef QT_NO_LIBRARY bool q_resolveOpenSslSymbols() { - qWarning("QSslSocket: unable to resolve symbols. " - "QT_NO_LIBRARY is defined which means runtime resolving of " - "libraries won't work."); - qWarning("Either compile Qt statically or with support for runtime resolving " - "of libraries."); + qCWarning(lcSsl, "QSslSocket: unable to resolve symbols. " + "QT_NO_LIBRARY is defined which means runtime resolving of " + "libraries won't work."); + qCWarning(lcSsl, "Either compile Qt statically or with support for runtime resolving " + "of libraries."); return false; } #else @@ -992,7 +993,7 @@ QDateTime q_getTimeFromASN1(const ASN1_TIME *aTime) return result; } else { - qWarning("unsupported date format detected"); + qCWarning(lcSsl, "unsupported date format detected"); return QDateTime(); } diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp index 418a7416e4..7527422f75 100644 --- a/src/network/ssl/qsslsocket_winrt.cpp +++ b/src/network/ssl/qsslsocket_winrt.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "qssl_p.h" #include "qsslsocket_winrt_p.h" #include "qsslsocket.h" #include "qsslcertificate_p.h" @@ -455,8 +456,9 @@ HRESULT QSslSocketBackendPrivate::onSslUpgrade(IAsyncAction *action, AsyncStatus Q_Q(QSslSocket); if (wasDeleted) { - qWarning("SSL upgrade callback received after the delegate was deleted. " - "This may be indicative of an internal bug in the WinRT SSL implementation."); + qCWarning(lcSsl, + "SSL upgrade callback received after the delegate was deleted. " + "This may be indicative of an internal bug in the WinRT SSL implementation."); return S_OK; } @@ -477,8 +479,9 @@ HRESULT QSslSocketBackendPrivate::onSslUpgrade(IAsyncAction *action, AsyncStatus IStreamSocket *socket = reinterpret_cast(plainSocket->socketDescriptor()); if (qintptr(socket) == -1) { - qWarning("The underlying TCP socket used by the SSL socket is invalid. " - "This may be indicative of an internal bug in the WinRT SSL implementation."); + qCWarning(lcSsl, + "The underlying TCP socket used by the SSL socket is invalid. " + "This may be indicative of an internal bug in the WinRT SSL implementation."); return S_OK; } diff --git a/src/network/ssl/ssl.pri b/src/network/ssl/ssl.pri index 384e149241..d0ba93b53f 100644 --- a/src/network/ssl/ssl.pri +++ b/src/network/ssl/ssl.pri @@ -2,6 +2,7 @@ contains(QT_CONFIG, ssl) | contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) { HEADERS += ssl/qasn1element_p.h \ ssl/qssl.h \ + ssl/qssl_p.h \ ssl/qsslcertificate.h \ ssl/qsslcertificate_p.h \ ssl/qsslconfiguration.h \ -- cgit v1.2.3 From dd670a2f3dfaff00016c24468f1f6e66efbcd2c3 Mon Sep 17 00:00:00 2001 From: Alejandro Exojo Date: Tue, 9 Dec 2014 18:21:07 +0100 Subject: doc: Clarify NOTIFY emission with MEMBER variables Document that NOTIFY signals should be emitted only when really needed, and that such is the case with MEMBER variables. Change-Id: Icc38a0790aa43ffe8f24d124da966b4240a41a6f Reviewed-by: Olivier Goffart --- src/corelib/doc/src/objectmodel/properties.qdoc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/doc/src/objectmodel/properties.qdoc b/src/corelib/doc/src/objectmodel/properties.qdoc index 8a6c7f53d9..dbdc080dff 100644 --- a/src/corelib/doc/src/objectmodel/properties.qdoc +++ b/src/corelib/doc/src/objectmodel/properties.qdoc @@ -97,7 +97,10 @@ of the property changes. \c NOTIFY signals for \c MEMBER variables must take zero or one parameter, which must be of the same type as the property. The parameter will take the - new value of the property. + new value of the property. The \c NOTIFY signal should only be emitted when + the property has really been changed, to avoid bindings being unnecessarily + re-evaluated in QML, for example. Qt emits automatically that signal when + needed for MEMBER properties that do not have an explicit setter. \li A \c REVISION number is optional. If included, it defines the property and its notifier signal to be used in a particular -- cgit v1.2.3 From 6a7ee92b3958e3a3ebc16be15f8bd34217ec7bd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Wed, 10 Dec 2014 07:27:23 +0100 Subject: Handle SelectionClientClose in QXcbClipboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QXcbClipboard listens for subtype SelectionClientClose of Xfixes SelectionNotify event, but doesn't handle it. When the client holding the clipboard selection closes the Clipboard becomes empty and thus the change should be emitted. This fixes downstream KDE Bug #329174. Change-Id: I19fb8cfd7bd3b249c0bc6ca2a724a9aeeb05ac7e Reviewed-by: Jørgen Lind Reviewed-by: Aleix Pol Gonzalez --- src/plugins/platforms/xcb/qxcbclipboard.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp index 8b3893ec2f..f56a29d985 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -742,7 +742,8 @@ void QXcbClipboard::handleXFixesSelectionRequest(xcb_xfixes_selection_notify_eve m_xClipboard[mode]->reset(); } emitChanged(mode); - } + } else if (event->subtype == XCB_XFIXES_SELECTION_EVENT_SELECTION_CLIENT_CLOSE) + emitChanged(mode); } -- cgit v1.2.3 From e79cdd0e6df7dec2edaea13b6cff45965c3e7456 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 10 Dec 2014 15:07:00 +0100 Subject: Enable input methods for QQuickWidget MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make it possible for widgets to have non-widget focus objects. Since we cannot add new virtual functions due to binary compatibility, we have to do it in QWidgetPrivate. Task-number: QTBUG-42677 Change-Id: I5f74daed2793c1c149bbe02e54ff2f7e2ad1af9e Reviewed-by: Jørgen Lind --- src/widgets/kernel/qwidget_p.h | 2 ++ src/widgets/kernel/qwidgetwindow.cpp | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index bbdbabc14b..b3552cba68 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -619,6 +619,8 @@ public: QOpenGLContext *shareContext() const; + virtual QObject *focusObject() { return 0; } + #ifndef QT_NO_OPENGL virtual GLuint textureId() const { return 0; } virtual QImage grabFramebuffer() { return QImage(); } diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 463eea4ddc..b31f9a51dd 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -147,6 +147,12 @@ QObject *QWidgetWindow::focusObject() const if (!widget) widget = m_widget; + if (widget) { + QObject *focusObj = QWidgetPrivate::get(widget)->focusObject(); + if (focusObj) + return focusObj; + } + return widget; } -- cgit v1.2.3 From e9222e199d587f48bd1d0e597aa295ebbe0531e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 9 Dec 2014 16:50:05 +0100 Subject: GL2PaintEngine: Prevent fillInPendingGlyphs from breaking gradients MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The glyph cache internally uses the image texture unit when blitting, but doesn't always activate the unit before binding its texture, resulting in sometimes binding the glyph cache texture to the wrong unit. The image texture unit is also the same as the brush texture unit, so any time we fill in pending glyphs we need to re-bind the brush texture, otherwise drawing text with eg. gradients will fail after the new glyphs have been filled. The new hasPendingGlyphs() member function of the glyph cache is an optimization so that we don't need to activate and rebind unless there are glyphs that need to be filled. Change-Id: Iac74130145d2d6d7bf95206b5e8a2fc760743cb5 Reviewed-by: Laszlo Agocs Reviewed-by: Tor Arne Vestbø --- src/gui/opengl/qopenglpaintengine.cpp | 20 +++++++++++++++++++- src/gui/painting/qtextureglyphcache.cpp | 2 +- src/gui/painting/qtextureglyphcache_p.h | 1 + 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index 834aed9142..ff1a26c914 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -1639,7 +1639,25 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly cache->populate(fe, staticTextItem->numGlyphs, staticTextItem->glyphs, staticTextItem->glyphPositions); } - cache->fillInPendingGlyphs(); + + if (cache->hasPendingGlyphs()) { + // Filling in the glyphs binds and sets parameters, so we need to + // ensure that the glyph cache doesn't mess with whatever unit + // is currently active. Note that the glyph cache internally + // uses the image texture unit for blitting to the cache, while + // we switch between image and mask units when drawing. + static const GLenum glypchCacheTextureUnit = QT_IMAGE_TEXTURE_UNIT; + funcs.glActiveTexture(GL_TEXTURE0 + glypchCacheTextureUnit); + + cache->fillInPendingGlyphs(); + + // We assume the cache can be trusted on which texture was bound + lastTextureUsed = cache->texture(); + + // But since the brush and image texture units are possibly shared + // we may have to re-bind brush textures after filling in the cache. + brushTextureDirty = (QT_BRUSH_TEXTURE_UNIT == glypchCacheTextureUnit); + } } if (cache->width() == 0 || cache->height() == 0) diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index e12d61bbf4..be46a0fba3 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -222,7 +222,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const void QTextureGlyphCache::fillInPendingGlyphs() { - if (m_pendingGlyphs.isEmpty()) + if (!hasPendingGlyphs()) return; int requiredHeight = m_h; diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h index 50c2c9dcc6..2d2fcdfc93 100644 --- a/src/gui/painting/qtextureglyphcache_p.h +++ b/src/gui/painting/qtextureglyphcache_p.h @@ -104,6 +104,7 @@ public: bool populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions); + bool hasPendingGlyphs() const { return !m_pendingGlyphs.isEmpty(); }; void fillInPendingGlyphs(); virtual void createTextureData(int width, int height) = 0; -- cgit v1.2.3 From 47326b9c5c38fea39f8539f50f32667d2c391b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 2 Dec 2014 20:16:23 +0100 Subject: GL2PaintEngine: centralize logic for updating/preparing textures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrite of updateTextureFilter to include activating and binding as well, so that we can maintain a single view of which texture was the last one to be used from within the engine itself. The behavior should be the same as before. Change-Id: I41781d00458b0176c614266f4360db3c68b120a1 Reviewed-by: Laszlo Agocs Reviewed-by: Tor Arne Vestbø --- src/gui/opengl/qopenglpaintengine.cpp | 121 ++++++++++++++++++++-------------- src/gui/opengl/qopenglpaintengine_p.h | 7 +- 2 files changed, 78 insertions(+), 50 deletions(-) diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index ff1a26c914..6570d49279 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -107,29 +107,6 @@ QOpenGL2PaintEngineExPrivate::~QOpenGL2PaintEngineExPrivate() } } -void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum wrapMode, bool smoothPixmapTransform, GLuint id) -{ -// funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); //### Is it always this texture unit? - if (id != GLuint(-1) && id == lastTextureUsed) - return; - - lastTextureUsed = id; - - static const GLenum target = GL_TEXTURE_2D; - - if (smoothPixmapTransform) { - funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } else { - funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - - funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, wrapMode); - funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, wrapMode); -} - - inline QColor qt_premultiplyColor(QColor c, GLfloat opacity) { qreal alpha = c.alphaF() * opacity; @@ -176,19 +153,74 @@ void QOpenGL2PaintEngineExPrivate::useSimpleShader() updateMatrix(); } +template +void QOpenGL2PaintEngineExPrivate::updateTexture(GLenum textureUnit, const T &texture, GLenum wrapMode, GLenum filterMode, TextureUpdateMode updateMode) +{ + static const GLenum target = GL_TEXTURE_2D; + + funcs.glActiveTexture(GL_TEXTURE0 + textureUnit); + + GLuint textureId = bindTexture(texture); + + if (updateMode == UpdateIfNeeded && textureId == lastTextureUsed) + return; + + lastTextureUsed = textureId; + + funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, wrapMode); + funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, wrapMode); + + funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filterMode); + funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filterMode); +} + +template<> +GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const GLuint &textureId) +{ + if (textureId != lastTextureUsed) + funcs.glBindTexture(GL_TEXTURE_2D, textureId); + + return textureId; +} + +template<> +GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QImage &image) +{ + return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, image); +} + +template<> +GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QPixmap &pixmap) +{ + return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap); +} + +struct ImageWithBindOptions +{ + const QImage ℑ + QOpenGLTextureCache::BindOptions options; +}; + +template<> +GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const ImageWithBindOptions &imageWithOptions) +{ + return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, imageWithOptions.image, imageWithOptions.options); +} + void QOpenGL2PaintEngineExPrivate::updateBrushTexture() { Q_Q(QOpenGL2PaintEngineEx); // qDebug("QOpenGL2PaintEngineExPrivate::updateBrushTexture()"); Qt::BrushStyle style = currentBrush.style(); + bool smoothPixmapTransform = q->state()->renderHints & QPainter::SmoothPixmapTransform; + GLenum filterMode = smoothPixmapTransform ? GL_LINEAR : GL_NEAREST; + if ( (style >= Qt::Dense1Pattern) && (style <= Qt::DiagCrossPattern) ) { // Get the image data for the pattern - QImage texImage = qt_imageForBrush(style, false); + QImage textureImage = qt_imageForBrush(style, false); - funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); - QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, texImage); - updateTextureFilter(GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); + updateTexture(QT_BRUSH_TEXTURE_UNIT, textureImage, GL_REPEAT, filterMode, ForceUpdate); } else if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) { // Gradiant brush: All the gradiants use the same texture @@ -197,7 +229,7 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture() // We apply global opacity in the fragment shaders, so we always pass 1.0 // for opacity to the cache. - GLuint texId = QOpenGL2GradientCache::cacheForContext(ctx)->getBuffer(*g, 1.0); + GLuint textureId = QOpenGL2GradientCache::cacheForContext(ctx)->getBuffer(*g, 1.0); GLenum wrapMode = GL_CLAMP_TO_EDGE; if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient) @@ -205,9 +237,7 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture() else if (g->spread() == QGradient::ReflectSpread) wrapMode = GL_MIRRORED_REPEAT; - funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); - funcs.glBindTexture(GL_TEXTURE_2D, texId); - updateTextureFilter(wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform); + updateTexture(QT_BRUSH_TEXTURE_UNIT, textureId, wrapMode, filterMode, ForceUpdate); } else if (style == Qt::TexturePattern) { currentBrushImage = currentBrush.textureImage(); @@ -224,9 +254,7 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture() wrapMode = GL_CLAMP_TO_EDGE; } - funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); - QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, currentBrushImage); - updateTextureFilter(wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform); + updateTexture(QT_BRUSH_TEXTURE_UNIT, currentBrushImage, wrapMode, filterMode, ForceUpdate); textureInvertedY = false; } @@ -1382,9 +1410,8 @@ void QOpenGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixma ensureActive(); d->transferMode(ImageDrawingMode); - d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap); - d->updateTextureFilter(GL_CLAMP_TO_EDGE, state()->renderHints & QPainter::SmoothPixmapTransform, id); + GLenum filterMode = state()->renderHints & QPainter::SmoothPixmapTransform ? GL_LINEAR : GL_NEAREST; + d->updateTexture(QT_IMAGE_TEXTURE_UNIT, pixmap, GL_CLAMP_TO_EDGE, filterMode); bool isBitmap = pixmap.isQBitmap(); bool isOpaque = !isBitmap && !pixmap.hasAlpha(); @@ -1428,9 +1455,9 @@ void QOpenGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, c break; } - d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, image, bindOption); - d->updateTextureFilter(GL_CLAMP_TO_EDGE, state()->renderHints & QPainter::SmoothPixmapTransform, id); + ImageWithBindOptions imageWithOptions = { image, bindOption }; + GLenum filterMode = state()->renderHints & QPainter::SmoothPixmapTransform ? GL_LINEAR : GL_NEAREST; + d->updateTexture(QT_IMAGE_TEXTURE_UNIT, imageWithOptions, GL_CLAMP_TO_EDGE, filterMode); d->drawTexture(dest, src, image.size(), !image.hasAlphaChannel()); } @@ -1471,9 +1498,8 @@ bool QOpenGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, co ensureActive(); d->transferMode(ImageDrawingMode); - d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - d->funcs.glBindTexture(GL_TEXTURE_2D, textureId); - d->updateTextureFilter(GL_CLAMP_TO_EDGE, state()->renderHints & QPainter::SmoothPixmapTransform, textureId); + GLenum filterMode = state()->renderHints & QPainter::SmoothPixmapTransform ? GL_LINEAR : GL_NEAREST; + d->updateTexture(QT_IMAGE_TEXTURE_UNIT, textureId, GL_CLAMP_TO_EDGE, filterMode); d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc); @@ -1823,9 +1849,7 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly funcs.glEnable(GL_BLEND); funcs.glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); - funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); - funcs.glBindTexture(GL_TEXTURE_2D, cache->texture()); - updateTextureFilter(GL_REPEAT, false); + updateTexture(QT_MASK_TEXTURE_UNIT, cache->texture(), GL_REPEAT, GL_NEAREST, ForceUpdate); #if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0); @@ -1970,9 +1994,8 @@ void QOpenGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFra transferMode(ImageOpacityArrayDrawingMode); - funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap); - updateTextureFilter(GL_CLAMP_TO_EDGE, q->state()->renderHints & QPainter::SmoothPixmapTransform, id); + GLenum filterMode = q->state()->renderHints & QPainter::SmoothPixmapTransform ? GL_LINEAR : GL_NEAREST; + updateTexture(QT_IMAGE_TEXTURE_UNIT, pixmap, GL_CLAMP_TO_EDGE, filterMode); bool isBitmap = pixmap.isQBitmap(); bool isOpaque = !isBitmap && (!pixmap.hasAlpha() || (hints & QPainter::OpaqueHint)) && allOpaque; diff --git a/src/gui/opengl/qopenglpaintengine_p.h b/src/gui/opengl/qopenglpaintengine_p.h index a5f3cc2894..209cd3d7b5 100644 --- a/src/gui/opengl/qopenglpaintengine_p.h +++ b/src/gui/opengl/qopenglpaintengine_p.h @@ -193,7 +193,12 @@ public: void updateBrushUniforms(); void updateMatrix(); void updateCompositionMode(); - void updateTextureFilter(GLenum wrapMode, bool smoothPixmapTransform, GLuint id = GLuint(-1)); + + enum TextureUpdateMode { UpdateIfNeeded, ForceUpdate }; + template + void updateTexture(GLenum textureUnit, const T &texture, GLenum wrapMode, GLenum filterMode, TextureUpdateMode updateMode = UpdateIfNeeded); + template + GLuint bindTexture(const T &texture); void resetGLState(); -- cgit v1.2.3 From e415ed83af3b90be76c63b21ee281eb48995c2ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 10 Dec 2014 16:45:45 +0100 Subject: iOS: Don't scroll screen on changes to input item transform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We auto-scroll the screen to reveal the cursor whenever the cursor rect changes or other properties of the input methods are updated, but the expected behavior when explicitly moving an item under the keyboard, such as when scrolling a view or moving an item using drag, is to not scroll the screen until typing commences. This matches how eg. Safari or the Notes app handles the same use-case. Change-Id: I6b6932d9bcbdccd8df26db982246c162f1574d86 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosinputcontext.h | 1 - src/plugins/platforms/ios/qiosinputcontext.mm | 22 +++------------------- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index 863e503c3b..498db45ef2 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -96,7 +96,6 @@ public: void setFocusObject(QObject *object) Q_DECL_OVERRIDE; void focusWindowChanged(QWindow *focusWindow); - void cursorRectangleChanged(); void scrollToCursor(); void scroll(int y); diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index fe9ee18155..aebf8fff8f 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -281,8 +281,6 @@ QIOSInputContext::QIOSInputContext() if (isQtApplication()) { QIOSScreen *iosScreen = static_cast(QGuiApplication::primaryScreen()->handle()); [iosScreen->uiWindow() addGestureRecognizer:m_keyboardHideGesture]; - - connect(qGuiApp->inputMethod(), &QInputMethod::cursorRectangleChanged, this, &QIOSInputContext::cursorRectangleChanged); } connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &QIOSInputContext::focusWindowChanged); @@ -400,23 +398,6 @@ QRectF QIOSInputContext::keyboardRect() const // ------------------------------------------------------------------------- -void QIOSInputContext::cursorRectangleChanged() -{ - if (!isInputPanelVisible() || !qApp->focusObject()) - return; - - // Check if the cursor has changed position inside the input item. Since - // qApp->inputMethod()->cursorRectangle() will also change when the input item - // itself moves, we need to ask the focus object for ImCursorRectangle: - static QPoint prevCursor; - QInputMethodQueryEvent queryEvent(Qt::ImCursorRectangle); - QCoreApplication::sendEvent(qApp->focusObject(), &queryEvent); - QPoint cursor = queryEvent.value(Qt::ImCursorRectangle).toRect().topLeft(); - if (cursor != prevCursor) - scrollToCursor(); - prevCursor = cursor; -} - UIView *QIOSInputContext::scrollableRootView() { if (!m_keyboardHideGesture.view) @@ -598,6 +579,9 @@ void QIOSInputContext::update(Qt::InputMethodQueries updatedProperties) } else { [m_textResponder notifyInputDelegate:changedProperties]; } + + if (changedProperties & Qt::ImCursorRectangle) + scrollToCursor(); } bool QIOSInputContext::inputMethodAccepted() const -- cgit v1.2.3 From 8aa663e1393fcd2fa78eccc92b1acd7ba7c9cde2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 10 Dec 2014 16:44:48 +0100 Subject: iOS: Only scroll to cursor on keyboard hide gesture reset if requested MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I15b313b5f0d57358e405f16e941fc5061028c6a7 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosinputcontext.mm | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index aebf8fff8f..69bdf4aa87 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -68,6 +68,7 @@ static QUIView *focusView() @private QIOSInputContext *m_context; } +@property BOOL hasDeferredScrollToCursor; @end @implementation QIOSKeyboardListener @@ -80,6 +81,8 @@ static QUIView *focusView() m_context = context; + self.hasDeferredScrollToCursor = NO; + // UIGestureRecognizer self.enabled = NO; self.cancelsTouchesInView = NO; @@ -231,9 +234,14 @@ static QUIView *focusView() qImDebug() << "keyboard was hidden, disabling hide-keyboard gesture"; self.enabled = NO; } else { - qImDebug() << "gesture completed without triggering, scrolling view to cursor"; - m_context->scrollToCursor(); + qImDebug() << "gesture completed without triggering"; + if (self.hasDeferredScrollToCursor) { + qImDebug() << "applying deferred scroll to cursor"; + m_context->scrollToCursor(); + } } + + self.hasDeferredScrollToCursor = NO; } @end @@ -418,7 +426,8 @@ void QIOSInputContext::scrollToCursor() if (m_keyboardHideGesture.state == UIGestureRecognizerStatePossible && m_keyboardHideGesture.numberOfTouches == 1) { // Don't scroll to the cursor if the user is touching the screen and possibly // trying to trigger the hide-keyboard gesture. - qImDebug() << "preventing scrolling to cursor as we're still waiting for a possible gesture"; + qImDebug() << "deferring scrolling to cursor as we're still waiting for a possible gesture"; + m_keyboardHideGesture.hasDeferredScrollToCursor = YES; return; } -- cgit v1.2.3 From 87e9e76d976e67624b7661b5e2f887943d4c1567 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 11 Dec 2014 13:54:23 +0100 Subject: ANGLE: Do not use std::strlen This is a cherry-pick from upstream change e7cfb3dd2029c1bfe5c175ad994c03cac221ad4d Change-Id: Iefe01545319f9ad268c0c6bf8e8b2181e09d8a84 Reviewed-by: Andrew Knight Reviewed-by: Friedemann Kleint --- src/3rdparty/angle/src/libGLESv2/Shader.cpp | 2 +- .../patches/0020-ANGLE-Do-not-use-std-strlen.patch | 30 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 src/angle/patches/0020-ANGLE-Do-not-use-std-strlen.patch diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.cpp b/src/3rdparty/angle/src/libGLESv2/Shader.cpp index 5bca746094..024ef8fb7c 100644 --- a/src/3rdparty/angle/src/libGLESv2/Shader.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Shader.cpp @@ -53,7 +53,7 @@ void Shader::setSource(GLsizei count, const char *const *string, const GLint *le { if (length == nullptr || length[i] < 0) { - stream.write(string[i], std::strlen(string[i])); + stream.write(string[i], strlen(string[i])); } else { diff --git a/src/angle/patches/0020-ANGLE-Do-not-use-std-strlen.patch b/src/angle/patches/0020-ANGLE-Do-not-use-std-strlen.patch new file mode 100644 index 0000000000..324244f6eb --- /dev/null +++ b/src/angle/patches/0020-ANGLE-Do-not-use-std-strlen.patch @@ -0,0 +1,30 @@ +From 071b8936386b0b44475c91511d85479e5c633bc5 Mon Sep 17 00:00:00 2001 +From: Kai Koehne +Date: Thu, 11 Dec 2014 13:54:23 +0100 +Subject: [PATCH] ANGLE: Do not use std::strlen + +This is a cherry-pick from upstream change + +e7cfb3dd2029c1bfe5c175ad994c03cac221ad4d + +Change-Id: Iefe01545319f9ad268c0c6bf8e8b2181e09d8a84 +--- + src/3rdparty/angle/src/libGLESv2/Shader.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.cpp b/src/3rdparty/angle/src/libGLESv2/Shader.cpp +index 5bca746..024ef8f 100644 +--- a/src/3rdparty/angle/src/libGLESv2/Shader.cpp ++++ b/src/3rdparty/angle/src/libGLESv2/Shader.cpp +@@ -53,7 +53,7 @@ void Shader::setSource(GLsizei count, const char *const *string, const GLint *le + { + if (length == nullptr || length[i] < 0) + { +- stream.write(string[i], std::strlen(string[i])); ++ stream.write(string[i], strlen(string[i])); + } + else + { +-- +1.9.4.msysgit.0 + -- cgit v1.2.3 From de04841e19feb1ce1ba010c5026c06978ee03433 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 4 Dec 2014 14:57:53 +0100 Subject: iOS: only clear focus object if it supports IM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We try to keep a on-to-one relationship between UI controls with text input and keyboard visibility. But if the control does not use text input, then there is no reason for us to clear focus when the keyboard hides. In fact, we should avoid doing so, since that will stop e.g buttons from working correctly. The typical flow is: - a touch release targeting a button is sendt to QApplication. - QApplication transfers focus to the button. - qiosinputcontext gets notified, we refuse, and clear focus again. - QApplication enters a propagation loop where it tried to find out the receiver of the event. Since the button is now unfocused, the event will propagate up to a grandparent instead. - the button will as such not trigger. Change-Id: I70baa38299f40defc4a77f62790502e2d6ebbba9 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosinputcontext.mm | 3 ++- src/plugins/platforms/ios/qiostextresponder.mm | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 69bdf4aa87..e8b16a0ed8 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -514,7 +514,8 @@ void QIOSInputContext::setFocusObject(QObject *focusObject) qImDebug() << "new focus object =" << focusObject; - if (m_keyboardHideGesture.state == UIGestureRecognizerStateChanged) { + if (QPlatformInputContext::inputMethodAccepted() + && m_keyboardHideGesture.state == UIGestureRecognizerStateChanged) { // A new focus object may be set as part of delivering touch events to // application during the hide-keyboard gesture, but we don't want that // to result in a new object getting focus and bringing the keyboard up diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index 2fcc7258f7..bebc7577f8 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -263,10 +263,14 @@ // will set the new first-responder to our next-responder, and in the latter // case we'll have an active responder candidate. if ([UIResponder currentFirstResponder] == [self nextResponder]) { - // We have resigned the keyboard, and transferred back to the parent view, so unset focus object + // We have resigned the keyboard, and transferred first responder back to the parent view Q_ASSERT(!FirstResponderCandidate::currentCandidate()); - qImDebug() << "keyboard was closed, clearing focus object"; - m_inputContext->clearCurrentFocusObject(); + if ([self imValue:Qt::ImEnabled].toBool()) { + // The current focus object expects text input, but there + // is no keyboard to get input from. So we clear focus. + qImDebug() << "no keyboard available, clearing focus object"; + m_inputContext->clearCurrentFocusObject(); + } } else { // We've lost responder status because another Qt window was made active, // another QIOSTextResponder was made first-responder, another UIView was -- cgit v1.2.3 From fb9eca8c9c7c88673cc991f978a264a493652796 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 2 Dec 2014 15:33:55 +0100 Subject: iOS: let keyboard gesture work better with other gestures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let the keyboard gesture work better alongside other gestures by reporting that it should: 1. not prevent other gestures from triggering. This means that even if our gesture triggers (we close the keyboard), gestures attached to sub-views will still continue tracking. 2. not be prevented by other gestures. This means that if a gesture in a sub-view triggeres before our gesture, our gesture will still continue to track. In short it means that regardless of other gestures, we always close the keyboard if our text responder is first responder and the user flicks down. And we do so as "silently" as possible. Change-Id: I22386b5ef5dedbc498a2899929ddd07424e514d8 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosinputcontext.mm | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index e8b16a0ed8..76c02d939f 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -162,6 +162,18 @@ static QUIView *focusView() // ------------------------------------------------------------------------- +- (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)other +{ + Q_UNUSED(other); + return NO; +} + +- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)other +{ + Q_UNUSED(other); + return NO; +} + - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesBegan:touches withEvent:event]; -- cgit v1.2.3 From 7b8aaf04f6fa6b8de17908b7c81ca53643cace70 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Wed, 29 Oct 2014 17:59:42 +0400 Subject: Propagate the source of mouse events Set the source for mouse events which were caused by other mouse events. Change-Id: Ifca1648883ef2b94bb317ed9340759475d350146 Reviewed-by: Friedemann Kleint Reviewed-by: Laszlo Agocs --- src/widgets/graphicsview/qgraphicsproxywidget.cpp | 1 + src/widgets/itemviews/qabstractitemview.cpp | 2 ++ src/widgets/util/qflickgesture.cpp | 14 ++++++++++++-- src/widgets/widgets/qmenu.cpp | 1 + 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp index 68bc2ae1fa..a56c671180 100644 --- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp +++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp @@ -270,6 +270,7 @@ void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneMouseEvent QMouseEvent mouseEvent(type, pos, receiver->mapTo(receiver->topLevelWidget(), pos.toPoint()), receiver->mapToGlobal(pos.toPoint()), event->button(), event->buttons(), event->modifiers()); + QGuiApplicationPrivate::setMouseEventSource(&mouseEvent, event->source()); QWidget *embeddedMouseGrabberPtr = (QWidget *)embeddedMouseGrabber; QApplicationPrivate::sendMouseEvent(receiver, &mouseEvent, alienWidget, widget, diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 71404c9792..0f346a9682 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #ifndef QT_NO_ACCESSIBILITY #include #endif @@ -1884,6 +1885,7 @@ void QAbstractItemView::mouseDoubleClickEvent(QMouseEvent *event) QMouseEvent me(QEvent::MouseButtonPress, event->localPos(), event->windowPos(), event->screenPos(), event->button(), event->buttons(), event->modifiers()); + QGuiApplicationPrivate::setMouseEventSource(&me, event->source()); mousePressEvent(&me); return; } diff --git a/src/widgets/util/qflickgesture.cpp b/src/widgets/util/qflickgesture.cpp index a5f2cf2e66..42ead263f8 100644 --- a/src/widgets/util/qflickgesture.cpp +++ b/src/widgets/util/qflickgesture.cpp @@ -40,6 +40,7 @@ #include "qgraphicssceneevent.h" #include "qgraphicsview.h" #include "qscroller.h" +#include "private/qapplication_p.h" #include "private/qevent_p.h" #include "private/qflickgesture_p.h" #include "qdebug.h" @@ -65,7 +66,9 @@ static QMouseEvent *copyMouseEvent(QEvent *e) case QEvent::MouseButtonRelease: case QEvent::MouseMove: { QMouseEvent *me = static_cast(e); - return new QMouseEvent(me->type(), QPoint(0, 0), me->windowPos(), me->screenPos(), me->button(), me->buttons(), me->modifiers()); + QMouseEvent *cme = new QMouseEvent(me->type(), QPoint(0, 0), me->windowPos(), me->screenPos(), me->button(), me->buttons(), me->modifiers()); + QGuiApplicationPrivate::setMouseEventSource(cme, me->source()); + return cme; } #ifndef QT_NO_GRAPHICSVIEW case QEvent::GraphicsSceneMousePress: @@ -75,7 +78,9 @@ static QMouseEvent *copyMouseEvent(QEvent *e) #if 1 QEvent::Type met = me->type() == QEvent::GraphicsSceneMousePress ? QEvent::MouseButtonPress : (me->type() == QEvent::GraphicsSceneMouseRelease ? QEvent::MouseButtonRelease : QEvent::MouseMove); - return new QMouseEvent(met, QPoint(0, 0), QPoint(0, 0), me->screenPos(), me->button(), me->buttons(), me->modifiers()); + QMouseEvent *cme = new QMouseEvent(met, QPoint(0, 0), QPoint(0, 0), me->screenPos(), me->button(), me->buttons(), me->modifiers()); + QGuiApplicationPrivate::setMouseEventSource(cme, me->source()); + return cme; #else QGraphicsSceneMouseEvent *copy = new QGraphicsSceneMouseEvent(me->type()); copy->setPos(me->pos()); @@ -113,6 +118,7 @@ private: , sendingEvent(false) , mouseButton(Qt::NoButton) , mouseTarget(0) + , mouseEventSource(Qt::MouseEventNotSynthesized) { } static PressDelayHandler *inst; @@ -148,6 +154,7 @@ public: pressDelayTimer = startTimer(delay); mouseTarget = QApplication::widgetAt(pressDelayEvent->globalPos()); mouseButton = pressDelayEvent->button(); + mouseEventSource = pressDelayEvent->source(); qFGDebug() << "QFG: consuming/delaying mouse press"; } else { qFGDebug() << "QFG: NOT consuming/delaying mouse press"; @@ -234,6 +241,7 @@ public: QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway, farFarAway, mouseButton, QApplication::mouseButtons() & ~mouseButton, QApplication::keyboardModifiers()); + QGuiApplicationPrivate::setMouseEventSource(&re, mouseEventSource); sendMouseEvent(&re, RegrabMouseAfterwards); // don't clear the mouseTarget just yet, since we need to explicitly ungrab the mouse on release! } @@ -284,6 +292,7 @@ protected: QMouseEvent copy(me->type(), mouseTarget->mapFromGlobal(me->globalPos()), mouseTarget->topLevelWidget()->mapFromGlobal(me->globalPos()), me->screenPos(), me->button(), me->buttons(), me->modifiers()); + QGuiApplicationPrivate::setMouseEventSource(©, me->source()); qt_sendSpontaneousEvent(mouseTarget, ©); } @@ -309,6 +318,7 @@ private: bool sendingEvent; Qt::MouseButton mouseButton; QPointer mouseTarget; + Qt::MouseEventSource mouseEventSource; }; diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index acfccc8e19..5e5126e1e8 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -984,6 +984,7 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) if(e->type() != QEvent::MouseButtonRelease || mouseDown == caused) { QMouseEvent new_e(e->type(), cpos, caused->mapTo(caused->topLevelWidget(), cpos), e->screenPos(), e->button(), e->buttons(), e->modifiers()); + QGuiApplicationPrivate::setMouseEventSource(&new_e, e->source()); QApplication::sendEvent(caused, &new_e); return true; } -- cgit v1.2.3 From 3740fb41fe122c062408bf49de85a3977b6ae4ed Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 11 Dec 2014 10:44:50 +0100 Subject: DiagLib: Add Wheel event to mouse event category of the event filter.. Task-number: QTBUG-42731 Change-Id: Ib0293a245ed430bd86a1ceb221628b3044ad305e Reviewed-by: Andy Shaw --- tests/manual/diaglib/eventfilter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/manual/diaglib/eventfilter.cpp b/tests/manual/diaglib/eventfilter.cpp index 4968780e82..23a6d44fef 100644 --- a/tests/manual/diaglib/eventfilter.cpp +++ b/tests/manual/diaglib/eventfilter.cpp @@ -59,7 +59,7 @@ void EventFilter::init(EventCategories eventCategories) << QEvent::MouseButtonDblClick << QEvent::NonClientAreaMouseButtonPress << QEvent::NonClientAreaMouseButtonRelease << QEvent::NonClientAreaMouseButtonDblClick - << QEvent::Enter << QEvent::Leave; + << QEvent::Wheel << QEvent::Enter << QEvent::Leave; } if (eventCategories & MouseMoveEvents) m_eventTypes << QEvent::MouseMove << QEvent::NonClientAreaMouseMove; -- cgit v1.2.3 From 994bbcf1df83ecd6ed273926128d55088bd7ef5e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 11 Dec 2014 13:16:56 +0100 Subject: Windows: Fix window geometry when using QWindow::fromWinId(). Take margins into account. Task-number: QTBUG-43252 Change-Id: I816115d2bbbcee3e8663f42bf07b1a140a049e69 Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowswindow.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 5768800947..05ed6aed53 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -559,10 +559,11 @@ QWindowsWindowData Q_ASSERT(result.hwnd); const LONG_PTR style = GetWindowLongPtr(result.hwnd, GWL_STYLE); const LONG_PTR exStyle = GetWindowLongPtr(result.hwnd, GWL_EXSTYLE); - result.geometry = frameGeometry(result.hwnd, !GetParent(result.hwnd)); - result.frame = QWindowsGeometryHint::frame(style, exStyle); result.embedded = false; - qCDebug(lcQpaWindows) << "Foreign window: " << w << result.hwnd << result.geometry << result.frame; + result.frame = QWindowsGeometryHint::frame(style, exStyle); + result.geometry = frameGeometry(result.hwnd, !GetParent(result.hwnd)) + .marginsRemoved(result.frame); + qCDebug(lcQpaWindows) << "Foreign window: " << w << result.hwnd << result.geometry; return result; } -- cgit v1.2.3 From d61ee49df4d540d08782c9fac1c42541d2f4f9b6 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 11 Dec 2014 13:18:07 +0100 Subject: Windows: Do not register windows obtained by QWindow::fromWinId() for touch. Fixes a warning: RegisterTouchWindow() failed for window ''. (Access is denied.) Task-number: QTBUG-43252 Change-Id: I92a565f3a5e2e8815eb709b5c6d0ccdba7330e31 Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowswindow.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 05ed6aed53..7d67aa0d09 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -890,7 +890,8 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) updateDropSite(); #ifndef Q_OS_WINCE - if (QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch) { + if ((QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch) + && aWindow->type() != Qt::ForeignWindow) { if (QWindowsContext::user32dll.registerTouchWindow(m_data.hwnd, 0)) { setFlag(TouchRegistered); } else { -- cgit v1.2.3 From d47b9ace50d47a4472dc9fb029bbf6e8dd810c01 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 11 Dec 2014 10:56:01 -0800 Subject: Fix the Apple build version numbers for Clang MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A bunch of zeroes were missing. And not to the left. Task-number: QTBUG-43279 Change-Id: I1a710cf572099547b2ade7b2574a7e0a61649758 Reviewed-by: Tor Arne Vestbø --- src/corelib/global/qcompilerdetection.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 4c84daae13..5f8ca5c7cc 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -154,17 +154,17 @@ /* Clang also masquerades as GCC */ # if defined(__apple_build_version__) # /* http://en.wikipedia.org/wiki/Xcode#Toolchain_Versions */ -# if __apple_build_version__ >= 600051 +# if __apple_build_version__ >= 6000051 # define Q_CC_CLANG 305 -# elif __apple_build_version__ >= 503038 +# elif __apple_build_version__ >= 5030038 # define Q_CC_CLANG 304 -# elif __apple_build_version__ >= 500275 +# elif __apple_build_version__ >= 5000275 # define Q_CC_CLANG 303 -# elif __apple_build_version__ >= 425024 +# elif __apple_build_version__ >= 4250024 # define Q_CC_CLANG 302 -# elif __apple_build_version__ >= 318045 +# elif __apple_build_version__ >= 3180045 # define Q_CC_CLANG 301 -# elif __apple_build_version__ >= 211101 +# elif __apple_build_version__ >= 2111001 # define Q_CC_CLANG 300 # else # error "Unknown Apple Clang version" -- cgit v1.2.3 From dc583a0576343cfcd5544a21b8625af61e299e6f Mon Sep 17 00:00:00 2001 From: MihailNaydenov Date: Fri, 26 Sep 2014 12:23:55 +0300 Subject: Fix incorrect QImage transformation when its devicePixelRatio != 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QImage::transformed compensates for unwanted translation. This compensation is performed in "pixel space". However, a possible code path to perform the transformation uses QPainter which is devicePixelRatio-aware and expects the transformation matrix to be in logical coordinates. For example, image.transformed(QTransform().rotate(45)) will result in cropped out image if devicePixelRatio == 2. Change-Id: I830ff3ffa25531d842dc9c77f1d0e8d4bd502c9d Reviewed-by: Tor Arne Vestbø --- src/gui/image/qimage.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 4e10b4cb4b..ea23954a49 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -4480,7 +4480,6 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode dImage.d->dpmx = dotsPerMeterX(); dImage.d->dpmy = dotsPerMeterY(); - dImage.d->devicePixelRatio = devicePixelRatio(); switch (bpp) { // initizialize the data @@ -4502,13 +4501,19 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode } if (target_format >= QImage::Format_RGB32) { + // Prevent QPainter from applying devicePixelRatio corrections + const QImage sImage = (devicePixelRatio() != 1) ? QImage(constBits(), width(), height(), format()) : *this; + + Q_ASSERT(sImage.devicePixelRatio() == 1); + Q_ASSERT(sImage.devicePixelRatio() == dImage.devicePixelRatio()); + QPainter p(&dImage); if (mode == Qt::SmoothTransformation) { p.setRenderHint(QPainter::Antialiasing); p.setRenderHint(QPainter::SmoothPixmapTransform); } p.setTransform(mat); - p.drawImage(QPoint(0, 0), *this); + p.drawImage(QPoint(0, 0), sImage); } else { bool invertible; mat = mat.inverted(&invertible); // invert matrix @@ -4520,6 +4525,8 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode int dbpl = dImage.bytesPerLine(); qt_xForm_helper(mat, 0, type, bpp, dImage.bits(), dbpl, 0, hd, sptr, sbpl, ws, hs); } + + dImage.d->devicePixelRatio = devicePixelRatio(); return dImage; } -- cgit v1.2.3 From fff996e8ad39ff2d32dc2214b3af7fba401f1eda Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Fri, 12 Dec 2014 10:38:07 +0100 Subject: Doc: corrected documentation addOptions() Task-number: QTBUG-43259 Change-Id: If27c0658f7abaa4ce01de343ce90c14bd911212f Reviewed-by: Martin Smith --- src/corelib/tools/qcommandlineparser.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp index c3edba0514..01772b2ad5 100644 --- a/src/corelib/tools/qcommandlineparser.cpp +++ b/src/corelib/tools/qcommandlineparser.cpp @@ -340,11 +340,13 @@ bool QCommandLineParser::addOption(const QCommandLineOption &option) /*! \since 5.4 - Adds the options \a options to look for while parsing. + Adds the options to look for while parsing. The options are specified by + the parameter \a options. - Returns \c false if adding any of the options failed; otherwise returns \c false. + Returns \c true if adding all of the options was successful; otherwise + returns \c false. - Cf. addOption() for when it may fail. + See the documentation for addOption() for when this function may fail. */ bool QCommandLineParser::addOptions(const QList &options) { -- cgit v1.2.3 From 71a63836ed5d21feacbfcdbfdbd4b405f635282f Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Fri, 12 Dec 2014 15:18:53 +0100 Subject: Make ImhNoPredictiveText work on Samsung devices Samsung does not support TYPE_TEXT_FLAG_NO_SUGGESTIONS, even though that flag was introduced in API level 5. Therefore, we have to use TYPE_TEXT_VARIATION_VISIBLE_PASSWORD. This effectively makes ImhNoPredictiveText a synonym for ImhSensitiveData on Android. Task-number: QTBUG-43297 Change-Id: I3e7139d144276462e46512445ad7b8e7114d8e32 Reviewed-by: Christian Stromme --- src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 4d16d7e13f..8e93b5b1f2 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -292,7 +292,7 @@ public class QtActivityDelegate } } else if ((inputHints & ImhHiddenText) != 0) { inputType |= android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD; - } else if ((inputHints & ImhSensitiveData) != 0) { + } else if ((inputHints & ImhSensitiveData) != 0 || (inputHints & ImhNoPredictiveText) != 0) { inputType |= android.text.InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD; } -- cgit v1.2.3 From 2e2de5e4820a928e017d3b92e826e23d95805fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 4 Dec 2014 13:30:40 +0100 Subject: Fix xcb backend not grabbing the server as default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The xcb backend relies on grabbing the x server in a few situations like popuphandling. For Qt 5.4.0 the logic enabling this code path was moved into the plugin. However it defaults to never grabbing the server Change-Id: I82489a0727affbce62587b3d7470085cf716a0cc Task-number: QTBUG-43049 Reviewed-by: Martin Gräßlin Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbintegration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 3818494d99..f0c4a7f691 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -165,7 +165,7 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char "\t Use the -dograb option to enforce grabbing."); } #endif - m_canGrab = (!underDebugger && noGrabArg) || (underDebugger && doGrabArg); + m_canGrab = (!underDebugger && !noGrabArg) || (underDebugger && doGrabArg); static bool canNotGrabEnv = qEnvironmentVariableIsSet("QT_XCB_NO_GRAB_SERVER"); if (canNotGrabEnv) -- cgit v1.2.3 From adfeb9e44479c16945409bb9d45d5720524a8c98 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 7 Nov 2014 12:09:08 +0100 Subject: Doc: fix copy & paste error Task-number: QTBUG-8536 Change-Id: I381690b9c25750cbc72de3a36f70879936482e11 Reviewed-by: Andy Shaw --- qmake/doc/src/qmake-manual.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index ed76e9cc61..7bfd7c66ab 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -1019,7 +1019,7 @@ on the directory they reside. This is turned on by default. \row \li embed_manifest_dll \li Embeds a manifest file in the DLL created as part of a library project. - \row \li embed_manifest_exe \li Embeds a manifest file in the DLL created + \row \li embed_manifest_exe \li Embeds a manifest file in the EXE created as part of an application project. \endtable -- cgit v1.2.3 From 37490d465b203ac109f422b482eda9704f4e8593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 8 Dec 2014 15:31:37 +0100 Subject: GL: Make updateTexture invalidate texture on change of texture unit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switching texture units means the value of lastTextureUsed could be invalid, meaning we need to unconditionally re-bind and update parameters. A future optimization would be to keep a per-texture-unit cache, so that we wouldn't have to re-bind and set parameters when switching units back and forth, but this complicates the current code somewhat, so it's left for another patch. Change-Id: Icb2a5d03457a907f3c25bbb437feeb7c5f155716 Reviewed-by: Laszlo Agocs Reviewed-by: Tor Arne Vestbø --- src/gui/opengl/qopenglpaintengine.cpp | 52 ++++++++++++++++++++++++++++++++--- src/gui/opengl/qopenglpaintengine_p.h | 5 ++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index 6570d49279..48a2ceaa55 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -153,12 +153,26 @@ void QOpenGL2PaintEngineExPrivate::useSimpleShader() updateMatrix(); } +/* + Single entry-point for activating, binding, and setting properties. + + Allows keeping track of (caching) the latest texture unit and bound + texture in a central place, so that we can skip re-binding unless + needed. + + \note Any code or Qt API that internally activates or binds will + not affect the cache used by this function, which means they will + lead to inconsisent state. QPainter::beginNativePainting() takes + care of resetting the cache, so for user–code this is fine, but + internally in the paint engine care must be taken to not call + functions that may activate or bind under our feet. +*/ template void QOpenGL2PaintEngineExPrivate::updateTexture(GLenum textureUnit, const T &texture, GLenum wrapMode, GLenum filterMode, TextureUpdateMode updateMode) { static const GLenum target = GL_TEXTURE_2D; - funcs.glActiveTexture(GL_TEXTURE0 + textureUnit); + activateTextureUnit(textureUnit); GLuint textureId = bindTexture(texture); @@ -174,6 +188,20 @@ void QOpenGL2PaintEngineExPrivate::updateTexture(GLenum textureUnit, const T &te funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filterMode); } +void QOpenGL2PaintEngineExPrivate::activateTextureUnit(GLenum textureUnit) +{ + if (textureUnit != lastTextureUnitUsed) { + funcs.glActiveTexture(GL_TEXTURE0 + textureUnit); + lastTextureUnitUsed = textureUnit; + + // We simplify things by keeping a single cached value of the last + // texture that was bound, instead of one per texture unit. This + // means that switching texture units could potentially mean we + // need a re-bind and corresponding parameter updates. + lastTextureUsed = GLuint(-1); + } +} + template<> GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const GLuint &textureId) { @@ -597,9 +625,15 @@ void QOpenGL2PaintEngineEx::beginNativePainting() } #endif // QT_OPENGL_ES_2 + d->resetGLState(); + + // We don't know what texture units and textures the native painting + // will activate and bind, so we can't assume anything when we return + // from the native painting. + d->lastTextureUnitUsed = QT_UNKNOWN_TEXTURE_UNIT; d->lastTextureUsed = GLuint(-1); + d->dirtyStencilRegion = QRect(0, 0, d->width, d->height); - d->resetGLState(); d->shaderManager->setDirty(); @@ -608,8 +642,9 @@ void QOpenGL2PaintEngineEx::beginNativePainting() void QOpenGL2PaintEngineExPrivate::resetGLState() { + activateTextureUnit(QT_DEFAULT_TEXTURE_UNIT); + funcs.glDisable(GL_BLEND); - funcs.glActiveTexture(GL_TEXTURE0); funcs.glDisable(GL_STENCIL_TEST); funcs.glDisable(GL_DEPTH_TEST); funcs.glDisable(GL_SCISSOR_TEST); @@ -1368,7 +1403,12 @@ void QOpenGL2PaintEngineEx::renderHintsChanged() #endif // QT_OPENGL_ES_2 Q_D(QOpenGL2PaintEngineEx); + + // This is a somewhat sneaky way of conceptually making the next call to + // updateTexture() use FoceUpdate for the TextureUpdateMode. We need this + // as new render hints may require updating the filter mode. d->lastTextureUsed = GLuint(-1); + d->brushTextureDirty = true; // qDebug("QOpenGL2PaintEngineEx::renderHintsChanged() not implemented!"); } @@ -1673,7 +1713,7 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly // uses the image texture unit for blitting to the cache, while // we switch between image and mask units when drawing. static const GLenum glypchCacheTextureUnit = QT_IMAGE_TEXTURE_UNIT; - funcs.glActiveTexture(GL_TEXTURE0 + glypchCacheTextureUnit); + activateTextureUnit(glypchCacheTextureUnit); cache->fillInPendingGlyphs(); @@ -1892,6 +1932,10 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly else funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); + // Need to reset the unit here, until we've made drawCachedGlyphs + // use the shared code-path for activating and binding. + lastTextureUnitUsed = QT_UNKNOWN_TEXTURE_UNIT; + if (lastMaskTextureUsed != cache->texture()) { funcs.glBindTexture(GL_TEXTURE_2D, cache->texture()); lastMaskTextureUsed = cache->texture(); diff --git a/src/gui/opengl/qopenglpaintengine_p.h b/src/gui/opengl/qopenglpaintengine_p.h index 209cd3d7b5..297ac54640 100644 --- a/src/gui/opengl/qopenglpaintengine_p.h +++ b/src/gui/opengl/qopenglpaintengine_p.h @@ -69,6 +69,8 @@ enum EngineMode { QT_BEGIN_NAMESPACE #define GL_STENCIL_HIGH_BIT GLuint(0x80) +#define QT_UNKNOWN_TEXTURE_UNIT GLuint(-1) +#define QT_DEFAULT_TEXTURE_UNIT GLuint(0) #define QT_BRUSH_TEXTURE_UNIT GLuint(0) #define QT_IMAGE_TEXTURE_UNIT GLuint(0) //Can be the same as brush texture unit #define QT_MASK_TEXTURE_UNIT GLuint(1) @@ -184,6 +186,7 @@ public: snapToPixelGrid(false), nativePaintingActive(false), inverseScale(1), + lastTextureUnitUsed(QT_UNKNOWN_TEXTURE_UNIT), lastMaskTextureUsed(0) { } @@ -199,6 +202,7 @@ public: void updateTexture(GLenum textureUnit, const T &texture, GLenum wrapMode, GLenum filterMode, TextureUpdateMode updateMode = UpdateIfNeeded); template GLuint bindTexture(const T &texture); + void activateTextureUnit(GLenum textureUnit); void resetGLState(); @@ -300,6 +304,7 @@ public: GLfloat pmvMatrix[3][3]; GLfloat inverseScale; + GLenum lastTextureUnitUsed; GLuint lastTextureUsed; GLuint lastMaskTextureUsed; -- cgit v1.2.3 From 384388f2cd739fd1416e4016588c79fd9788e898 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 21 Nov 2014 10:34:22 +0400 Subject: Make QRawFont usage safer in a multi-threaded environment QFontEngine must be accessed amd deleted only in a thread in which it was instantiated, so we remember that thread and check if it hasn't been changed every time we access the engine. Change-Id: I28bc0394ced9cbd437dc950d35ffcbd99cfa7152 Reviewed-by: Pierre Rossi Reviewed-by: Lars Knoll --- src/gui/text/qrawfont.cpp | 31 +++++-------------------------- src/gui/text/qrawfont_p.h | 37 ++++++++++++++++++++++++++++++++----- src/gui/text/qtextlayout.cpp | 5 ++--- 3 files changed, 39 insertions(+), 34 deletions(-) diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 0c3c9bb493..d21138e7ac 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -247,7 +247,6 @@ void QRawFont::loadFromData(const QByteArray &fontData, d.detach(); d->cleanUp(); d->hintingPreference = hintingPreference; - d->thread = QThread::currentThread(); d->loadFromData(fontData, pixelSize, hintingPreference); } @@ -700,8 +699,7 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ } if (fe != 0) { - rawFont.d.data()->fontEngine = fe; - rawFont.d.data()->fontEngine->ref.ref(); + rawFont.d.data()->setFontEngine(fe); rawFont.d.data()->hintingPreference = font.hintingPreference(); } return rawFont; @@ -712,42 +710,23 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ */ void QRawFont::setPixelSize(qreal pixelSize) { - if (d->fontEngine == 0 || qFuzzyCompare(d->fontEngine->fontDef.pixelSize, pixelSize)) + if (!d->isValid() || qFuzzyCompare(d->fontEngine->fontDef.pixelSize, pixelSize)) return; d.detach(); - QFontEngine *oldFontEngine = d->fontEngine; - - d->fontEngine = d->fontEngine->cloneWithSize(pixelSize); - if (d->fontEngine != 0) - d->fontEngine->ref.ref(); - - if (!oldFontEngine->ref.deref()) - delete oldFontEngine; + d->setFontEngine(d->fontEngine->cloneWithSize(pixelSize)); } /*! \internal */ -void QRawFontPrivate::cleanUp() -{ - if (fontEngine != 0) { - if (!fontEngine->ref.deref()) - delete fontEngine; - fontEngine = 0; - } - hintingPreference = QFont::PreferDefaultHinting; -} - void QRawFontPrivate::loadFromData(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) { Q_ASSERT(fontEngine == 0); QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); - fontEngine = pfdb->fontEngine(fontData, pixelSize, hintingPreference); - if (fontEngine != 0) - fontEngine->ref.ref(); + setFontEngine(pfdb->fontEngine(fontData, pixelSize, hintingPreference)); } /*! @@ -757,7 +736,7 @@ void QRawFontPrivate::loadFromData(const QByteArray &fontData, qreal pixelSize, */ QRectF QRawFont::boundingRect(quint32 glyphIndex) const { - if (!isValid()) + if (!d->isValid()) return QRectF(); glyph_metrics_t gm = d->fontEngine->boundingBox(glyphIndex); diff --git a/src/gui/text/qrawfont_p.h b/src/gui/text/qrawfont_p.h index f7a951ec59..9b0846de9a 100644 --- a/src/gui/text/qrawfont_p.h +++ b/src/gui/text/qrawfont_p.h @@ -66,10 +66,11 @@ public: {} QRawFontPrivate(const QRawFontPrivate &other) - : hintingPreference(other.hintingPreference) + : fontEngine(other.fontEngine) + , hintingPreference(other.hintingPreference) , thread(other.thread) { - fontEngine = other.fontEngine; + Q_ASSERT(fontEngine == 0 || thread == QThread::currentThread()); if (fontEngine != 0) fontEngine->ref.ref(); } @@ -80,13 +81,38 @@ public: cleanUp(); } + inline void cleanUp() + { + setFontEngine(0); + hintingPreference = QFont::PreferDefaultHinting; + } + inline bool isValid() const { - Q_ASSERT(thread == 0 || thread == QThread::currentThread()); + Q_ASSERT(fontEngine == 0 || thread == QThread::currentThread()); return fontEngine != 0; } - void cleanUp(); + inline void setFontEngine(QFontEngine *engine) + { + Q_ASSERT(fontEngine == 0 || thread == QThread::currentThread()); + if (fontEngine == engine) + return; + + if (fontEngine != 0) { + if (!fontEngine->ref.deref()) + delete fontEngine; + thread = 0; + } + + fontEngine = engine; + + if (fontEngine != 0) { + fontEngine->ref.ref(); + Q_ASSERT(thread = QThread::currentThread()); // set only if assertions enabled + } + } + void loadFromData(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); @@ -95,9 +121,10 @@ public: QFontEngine *fontEngine; QFont::HintingPreference hintingPreference; - QThread *thread; QAtomicInt ref; +private: + QThread *thread; }; QT_END_NAMESPACE diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 1ac50d3e5c..733bb57928 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2063,9 +2063,8 @@ static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine, // Make a font for this particular engine QRawFont font; QRawFontPrivate *fontD = QRawFontPrivate::get(font); - fontD->fontEngine = fontEngine; - fontD->thread = QThread::currentThread(); - fontD->fontEngine->ref.ref(); + fontD->setFontEngine(fontEngine); + QVarLengthArray glyphsArray; QVarLengthArray positionsArray; -- cgit v1.2.3 From dfccd78aa671364346bc9c4d1203dcb54d008a07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 8 Dec 2014 16:41:33 +0100 Subject: Ensure that GL::updateBrushTexture() activates and binds properly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calling QOpenGL2GradientCache::getBuffer() will generate the texture the first time, calling glBindTexture in the process. We did this without first ensuring that the right texture unit was active, resulting in the generated gradient texture binding onto the glyph cache mask unit. We now provide a specialization of bindTexture for a QGradient, which ensures that the right unit is active before calling getBuffer(). Unfortunately we have no way of knowing if the result of getBuffer() was a texture that was already bound, or if we need to bind the result, which means we have to do an unconditional bindTexture of the resulting texture ID. This means double-bind for the initial texture generation, but this was already an issue in the original code. Task-number: QTBUG-43039 Task-number: QTBUG-41244 Change-Id: I20c9b795c8c14f8d58be2b60a284c5a060705ec0 Reviewed-by: Laszlo Agocs Reviewed-by: Tor Arne Vestbø --- src/gui/opengl/qopenglpaintengine.cpp | 26 ++++++++++++++++++-------- tests/auto/other/lancelot/scripts/text.qps | 20 ++++++++++++++++++++ 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index 48a2ceaa55..a854715f70 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -223,6 +223,20 @@ GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QPixmap &pixmap) return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap); } +template<> +GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QGradient &gradient) +{ + // We apply global opacity in the fragment shaders, so we always pass 1.0 + // for opacity to the cache. + GLuint textureId = QOpenGL2GradientCache::cacheForContext(ctx)->getBuffer(gradient, 1.0); + + // QOpenGL2GradientCache::getBuffer() may bind and generate a new texture if it + // hasn't been cached yet, but will otherwise return an unbound texture id. To + // be sure that the texture is bound, we unfortunately have to bind again, + // which results in the initial generation of the texture doing two binds. + return bindTexture(textureId); +} + struct ImageWithBindOptions { const QImage ℑ @@ -253,19 +267,15 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture() else if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) { // Gradiant brush: All the gradiants use the same texture - const QGradient* g = currentBrush.gradient(); - - // We apply global opacity in the fragment shaders, so we always pass 1.0 - // for opacity to the cache. - GLuint textureId = QOpenGL2GradientCache::cacheForContext(ctx)->getBuffer(*g, 1.0); + const QGradient *gradient = currentBrush.gradient(); GLenum wrapMode = GL_CLAMP_TO_EDGE; - if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient) + if (gradient->spread() == QGradient::RepeatSpread || gradient->type() == QGradient::ConicalGradient) wrapMode = GL_REPEAT; - else if (g->spread() == QGradient::ReflectSpread) + else if (gradient->spread() == QGradient::ReflectSpread) wrapMode = GL_MIRRORED_REPEAT; - updateTexture(QT_BRUSH_TEXTURE_UNIT, textureId, wrapMode, filterMode, ForceUpdate); + updateTexture(QT_BRUSH_TEXTURE_UNIT, *gradient, wrapMode, filterMode, ForceUpdate); } else if (style == Qt::TexturePattern) { currentBrushImage = currentBrush.textureImage(); diff --git a/tests/auto/other/lancelot/scripts/text.qps b/tests/auto/other/lancelot/scripts/text.qps index b3d8475411..344c7a813d 100644 --- a/tests/auto/other/lancelot/scripts/text.qps +++ b/tests/auto/other/lancelot/scripts/text.qps @@ -139,4 +139,24 @@ save setClipPath clip setPen black repeat_block text_drawing +restore + +translate 150 0 +save + setPen black + setFont "sansserif" 10 normal + drawText 0 20 "testing glyph cache textures" + + # Important that this gradient doesn't match any earlier + # gradients, so that it's not cached from before. + gradient_clearStops + gradient_appendStop 0 blue + gradient_appendStop 0.5 #00ff00 + gradient_appendStop 1 red + gradient_setLinear 0 0 100 0 + setPen nopen + drawRect 0 30 100 20 + + setPen black + drawText 0 70 "testing glyph cache textures" restore \ No newline at end of file -- cgit v1.2.3 From dc469691a95581553196c77c4b81cb4fb9b29f78 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 7 Dec 2014 11:01:05 -0800 Subject: Bump version number to 5.4.1 Change-Id: I54231de422ffc63162e49c587f371c56c3312210 Reviewed-by: Oswald Buddenhagen --- src/corelib/global/qglobal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index f17ff3dea0..cb8bd15d8d 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -37,11 +37,11 @@ #include -#define QT_VERSION_STR "5.4.0" +#define QT_VERSION_STR "5.4.1" /* QT_VERSION is (major << 16) + (minor << 8) + patch. */ -#define QT_VERSION 0x050400 +#define QT_VERSION 0x050401 /* can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) */ -- cgit v1.2.3 From 37fa842f41311e71d4c94eaa380ebfa0965fa25d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Thu, 11 Dec 2014 20:08:51 +0000 Subject: QColorDialog: Fix picking screen colors inside QColorPicker If you click "Pick screen color" and move mouse over QColorPicker (the square with gradients) unexpected things will happen: black will be picked half the times. This is because QColorPicker's black cross is painted under our mouse cursor. Although "pick screen color"'s use case is to pick colors in other windows, there's no reason to not make it work on QColorDialog itself too. Task-number: QTBUG-43288 Change-Id: I03ca02148cc15ad41d545723d4ac4f5a82842b4b Reviewed-by: Friedemann Kleint --- src/widgets/dialogs/qcolordialog.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index b92e1a24ad..33b374c1bc 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -627,6 +627,7 @@ public: QColorPicker(QWidget* parent); ~QColorPicker(); + void setCrossVisible(bool visible); public slots: void setCol(int h, int s); @@ -650,6 +651,7 @@ private: void setCol(const QPoint &pt); QPixmap pix; + bool crossVisible; }; static int pWidth = 220; @@ -805,6 +807,7 @@ void QColorPicker::setCol(const QPoint &pt) QColorPicker::QColorPicker(QWidget* parent) : QFrame(parent) + , crossVisible(true) { hue = 0; sat = 0; setCol(150, 255); @@ -817,6 +820,14 @@ QColorPicker::~QColorPicker() { } +void QColorPicker::setCrossVisible(bool visible) +{ + if (crossVisible != visible) { + crossVisible = visible; + update(); + } +} + QSize QColorPicker::sizeHint() const { return QSize(pWidth + 2*frameWidth(), pHeight + 2*frameWidth()); @@ -858,12 +869,13 @@ void QColorPicker::paintEvent(QPaintEvent* ) QRect r = contentsRect(); p.drawPixmap(r.topLeft(), pix); - QPoint pt = colPt() + r.topLeft(); - p.setPen(Qt::black); - - p.fillRect(pt.x()-9, pt.y(), 20, 2, Qt::black); - p.fillRect(pt.x(), pt.y()-9, 2, 20, Qt::black); + if (crossVisible) { + QPoint pt = colPt() + r.topLeft(); + p.setPen(Qt::black); + p.fillRect(pt.x()-9, pt.y(), 20, 2, Qt::black); + p.fillRect(pt.x(), pt.y()-9, 2, 20, Qt::black); + } } void QColorPicker::resizeEvent(QResizeEvent *ev) @@ -1578,6 +1590,7 @@ void QColorDialogPrivate::_q_pickScreenColor() void QColorDialogPrivate::releaseColorPicking() { Q_Q(QColorDialog); + cp->setCrossVisible(true); q->removeEventFilter(colorPickingEventFilter); q->releaseMouse(); q->releaseKeyboard(); @@ -2174,6 +2187,9 @@ void QColorDialog::changeEvent(QEvent *e) bool QColorDialogPrivate::handleColorPickingMouseMove(QMouseEvent *e) { + // If the cross is visible the grabbed color will be black most of the times + cp->setCrossVisible(!cp->geometry().contains(e->pos())); + const QPoint globalPos = e->globalPos(); const QColor color = grabScreenColor(globalPos); // QTBUG-39792, do not change standard, custom color selectors while moving as -- cgit v1.2.3 From 1cc83b575d2a79b771b4b536a554cd4869c3687c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 10 Dec 2014 15:26:36 +0100 Subject: Make GL2PaintEngine::drawCachedGlyphs use updateTexture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensures that we have a consistent view of what the last used texture was, which is critical when deciding whether or not we need to re-bind the texture or update texture properties. Change-Id: Ib47eb00abde98d148fc6e569ce3e359b340328fb Reviewed-by: Laszlo Agocs Reviewed-by: Tor Arne Vestbø --- src/gui/opengl/qopenglpaintengine.cpp | 41 ++++++++++------------------------- src/gui/opengl/qopenglpaintengine_p.h | 4 +--- 2 files changed, 13 insertions(+), 32 deletions(-) diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index a854715f70..8eeaa316d0 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -697,10 +697,6 @@ void QOpenGL2PaintEngineExPrivate::transferMode(EngineMode newMode) if (newMode == mode) return; - if (mode != BrushDrawingMode) { - lastTextureUsed = GLuint(-1); - } - if (newMode == TextDrawingMode) { shaderManager->setHasComplexGeometry(true); } else { @@ -1934,35 +1930,23 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly prepareForCachedGlyphDraw(*cache); } - QOpenGLTextureGlyphCache::FilterMode filterMode = (s->matrix.type() > QTransform::TxTranslate)?QOpenGLTextureGlyphCache::Linear:QOpenGLTextureGlyphCache::Nearest; - if (lastMaskTextureUsed != cache->texture() || cache->filterMode() != filterMode) { + GLenum textureUnit = QT_MASK_TEXTURE_UNIT; + if (glyphFormat == QFontEngine::Format_ARGB) + textureUnit = QT_IMAGE_TEXTURE_UNIT; - if (glyphFormat == QFontEngine::Format_ARGB) - funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - else - funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); + QOpenGLTextureGlyphCache::FilterMode filterMode = (s->matrix.type() > QTransform::TxTranslate) ? + QOpenGLTextureGlyphCache::Linear : QOpenGLTextureGlyphCache::Nearest; - // Need to reset the unit here, until we've made drawCachedGlyphs - // use the shared code-path for activating and binding. - lastTextureUnitUsed = QT_UNKNOWN_TEXTURE_UNIT; + GLenum glFilterMode = filterMode == QOpenGLTextureGlyphCache::Linear ? GL_LINEAR : GL_NEAREST; - if (lastMaskTextureUsed != cache->texture()) { - funcs.glBindTexture(GL_TEXTURE_2D, cache->texture()); - lastMaskTextureUsed = cache->texture(); - } - - if (cache->filterMode() != filterMode) { - if (filterMode == QOpenGLTextureGlyphCache::Linear) { - funcs.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - funcs.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } else { - funcs.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - funcs.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - cache->setFilterMode(filterMode); - } + TextureUpdateMode updateMode = UpdateIfNeeded; + if (cache->filterMode() != filterMode) { + updateMode = ForceUpdate; + cache->setFilterMode(filterMode); } + updateTexture(textureUnit, cache->texture(), GL_REPEAT, glFilterMode, updateMode); + #if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0); funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); @@ -2185,7 +2169,6 @@ void QOpenGL2PaintEngineEx::ensureActive() d->transferMode(BrushDrawingMode); d->funcs.glViewport(0, 0, d->width, d->height); d->needsSync = false; - d->lastMaskTextureUsed = 0; d->shaderManager->setDirty(); d->syncGlState(); for (int i = 0; i < 3; ++i) diff --git a/src/gui/opengl/qopenglpaintengine_p.h b/src/gui/opengl/qopenglpaintengine_p.h index 297ac54640..9722ea3196 100644 --- a/src/gui/opengl/qopenglpaintengine_p.h +++ b/src/gui/opengl/qopenglpaintengine_p.h @@ -186,8 +186,7 @@ public: snapToPixelGrid(false), nativePaintingActive(false), inverseScale(1), - lastTextureUnitUsed(QT_UNKNOWN_TEXTURE_UNIT), - lastMaskTextureUsed(0) + lastTextureUnitUsed(QT_UNKNOWN_TEXTURE_UNIT) { } ~QOpenGL2PaintEngineExPrivate(); @@ -306,7 +305,6 @@ public: GLenum lastTextureUnitUsed; GLuint lastTextureUsed; - GLuint lastMaskTextureUsed; bool needsSync; bool multisamplingAlwaysEnabled; -- cgit v1.2.3 From 3466950837e136e6032091491d0665823e4ac62f Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 11 Dec 2014 13:11:55 +0100 Subject: [ANGLE] Fix compilation with MSVC2013 Update4 Update4 provides a native Sleep implementation. Hence the wrapper needs to be disabled. Change-Id: I162da45934b02c262ac09b557c66c3363c276e54 Reviewed-by: Kai Koehne Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff --- src/3rdparty/angle/src/common/utilities.cpp | 2 +- src/3rdparty/angle/src/common/utilities.h | 2 +- ...GLE-Fix-compilation-with-MSVC2013-Update4.patch | 43 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 src/angle/patches/0020-ANGLE-Fix-compilation-with-MSVC2013-Update4.patch diff --git a/src/3rdparty/angle/src/common/utilities.cpp b/src/3rdparty/angle/src/common/utilities.cpp index 9d797a6612..0eae42cac2 100644 --- a/src/3rdparty/angle/src/common/utilities.cpp +++ b/src/3rdparty/angle/src/common/utilities.cpp @@ -486,7 +486,7 @@ void writeFile(const char* path, const void* content, size_t size) } #endif // !ANGLE_ENABLE_WINDOWS_STORE -#if defined(ANGLE_ENABLE_WINDOWS_STORE) +#if defined(ANGLE_ENABLE_WINDOWS_STORE) && _MSC_FULL_VER < 180031101 void Sleep(unsigned long dwMilliseconds) { diff --git a/src/3rdparty/angle/src/common/utilities.h b/src/3rdparty/angle/src/common/utilities.h index 2cf6bed176..7583d3e160 100644 --- a/src/3rdparty/angle/src/common/utilities.h +++ b/src/3rdparty/angle/src/common/utilities.h @@ -51,7 +51,7 @@ std::string getTempPath(); void writeFile(const char* path, const void* data, size_t size); #endif -#if defined(ANGLE_ENABLE_WINDOWS_STORE) +#if defined(ANGLE_ENABLE_WINDOWS_STORE) && _MSC_FULL_VER < 180031101 void Sleep(_In_ unsigned long dwMilliseconds); #endif diff --git a/src/angle/patches/0020-ANGLE-Fix-compilation-with-MSVC2013-Update4.patch b/src/angle/patches/0020-ANGLE-Fix-compilation-with-MSVC2013-Update4.patch new file mode 100644 index 0000000000..49b229d905 --- /dev/null +++ b/src/angle/patches/0020-ANGLE-Fix-compilation-with-MSVC2013-Update4.patch @@ -0,0 +1,43 @@ +From a48dfb3f1ecb57a59084c0e87155506586b73188 Mon Sep 17 00:00:00 2001 +From: Maurice Kalinowski +Date: Thu, 11 Dec 2014 13:11:55 +0100 +Subject: [PATCH] [ANGLE] Fix compilation with MSVC2013 Update4 + +Update4 provides a native Sleep implementation. Hence the wrapper +needs to be disabled. + +Change-Id: I162da45934b02c262ac09b557c66c3363c276e54 +--- + src/3rdparty/angle/src/common/utilities.cpp | 2 +- + src/3rdparty/angle/src/common/utilities.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/3rdparty/angle/src/common/utilities.cpp b/src/3rdparty/angle/src/common/utilities.cpp +index 9d797a6..924573e 100644 +--- a/src/3rdparty/angle/src/common/utilities.cpp ++++ b/src/3rdparty/angle/src/common/utilities.cpp +@@ -486,7 +486,7 @@ void writeFile(const char* path, const void* content, size_t size) + } + #endif // !ANGLE_ENABLE_WINDOWS_STORE + +-#if defined(ANGLE_ENABLE_WINDOWS_STORE) ++#if defined(ANGLE_ENABLE_WINDOWS_STORE) && _MSC_FULL_VER < 180031101 + + void Sleep(unsigned long dwMilliseconds) + { +diff --git a/src/3rdparty/angle/src/common/utilities.h b/src/3rdparty/angle/src/common/utilities.h +index 2cf6bed..7583d3e 100644 +--- a/src/3rdparty/angle/src/common/utilities.h ++++ b/src/3rdparty/angle/src/common/utilities.h +@@ -51,7 +51,7 @@ std::string getTempPath(); + void writeFile(const char* path, const void* data, size_t size); + #endif + +-#if defined(ANGLE_ENABLE_WINDOWS_STORE) ++#if defined(ANGLE_ENABLE_WINDOWS_STORE) && _MSC_FULL_VER < 180031101 + void Sleep(_In_ unsigned long dwMilliseconds); + #endif + +-- +1.9.4.msysgit.2 + -- cgit v1.2.3 From 21101d9c52d2b7c6471f9814c9bff5aa87e22afc Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 11 Dec 2014 13:51:48 +0200 Subject: Fix crash when Android Style is set more than once. Load again JSON document is it was freed. Task-number: QTBUG-43111 Change-Id: I22f1de221371b49fec8b3d66ad5f0bd2af9656fe Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../platforms/android/qandroidplatformintegration.cpp | 5 ++++- .../platforms/android/qandroidplatformtheme.cpp | 18 +++++++++++++----- src/plugins/platforms/android/qandroidplatformtheme.h | 2 +- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp index 07bdf95bf4..d94da65dde 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp @@ -79,8 +79,11 @@ void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteA if (resource == "QtActivity") return QtAndroid::activity(); if (resource == "AndroidStyleData") { - if (m_androidStyle) + if (m_androidStyle) { + if (m_androidStyle->m_styleData.isEmpty()) + m_androidStyle->m_styleData = AndroidStyle::loadStyleData(); return &m_androidStyle->m_styleData; + } else return Q_NULLPTR; } diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp index d9f062576b..35eb282994 100644 --- a/src/plugins/platforms/android/qandroidplatformtheme.cpp +++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp @@ -176,7 +176,7 @@ static void setPaletteColor(const QVariantMap &object, } } -static std::shared_ptr loadAndroidStyle(QPalette *defaultPalette) +QJsonObject AndroidStyle::loadStyleData() { QString stylePath(QLatin1String(qgetenv("MINISTRO_ANDROID_STYLE_PATH"))); const QLatin1Char slashChar('/'); @@ -198,21 +198,29 @@ static std::shared_ptr loadAndroidStyle(QPalette *defaultPalette) QFile f(stylePath + QLatin1String("style.json")); if (!f.open(QIODevice::ReadOnly)) - return std::shared_ptr(); + return QJsonObject(); QJsonParseError error; QJsonDocument document = QJsonDocument::fromJson(f.readAll(), &error); if (document.isNull()) { qCritical() << error.errorString(); - return std::shared_ptr(); + return QJsonObject(); } if (!document.isObject()) { qCritical() << "Style.json does not contain a valid style."; - return std::shared_ptr(); + return QJsonObject(); } + return document.object(); +} + +static std::shared_ptr loadAndroidStyle(QPalette *defaultPalette) +{ std::shared_ptr style(new AndroidStyle); - style->m_styleData = document.object(); + style->m_styleData = AndroidStyle::loadStyleData(); + if (style->m_styleData.isEmpty()) + return std::shared_ptr(); + for (QJsonObject::const_iterator objectIterator = style->m_styleData.constBegin(); objectIterator != style->m_styleData.constEnd(); ++objectIterator) { diff --git a/src/plugins/platforms/android/qandroidplatformtheme.h b/src/plugins/platforms/android/qandroidplatformtheme.h index e842e672d6..2069910136 100644 --- a/src/plugins/platforms/android/qandroidplatformtheme.h +++ b/src/plugins/platforms/android/qandroidplatformtheme.h @@ -46,12 +46,12 @@ QT_BEGIN_NAMESPACE struct AndroidStyle { + static QJsonObject loadStyleData(); QJsonObject m_styleData; QPalette m_standardPalette; QHash m_palettes; QHash m_fonts; QHash m_QWidgetsFonts; - QHash m_QWidgetsPalettes; }; class QAndroidPlatformNativeInterface; -- cgit v1.2.3 From 19bb9aa9e51e48043544fd7edf5abfda67955a4b Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 15 Dec 2014 13:50:11 +0100 Subject: Fix possibly corrupted log clusters when using custom tab stops The calculateTabWidth() can trigger shaping of the item, which can cause the layout data to be reallocated, so we need to update the local pointers to it, like we do when we explicitly invoke the shaper. [ChangeLog][Text] Fixed problems with text layout when using custom tab stops. Task-number: QTBUG-43126 Change-Id: Ifaeeeb4bfb1a55e6638b12b444f53d2679d3d1e6 Reviewed-by: Konstantin Ritt --- src/gui/text/qtextlayout.cpp | 5 ++++ .../auto/gui/text/qtextlayout/tst_qtextlayout.cpp | 34 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 733bb57928..52d2ba0d54 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1776,6 +1776,11 @@ void QTextLine::layout_helper(int maxGlyphs) QFixed x = line.x + line.textWidth + lbh.tmpData.textWidth + lbh.spaceData.textWidth; QFixed tabWidth = eng->calculateTabWidth(item, x); + attributes = eng->attributes(); + if (!attributes) + return; + lbh.logClusters = eng->layoutData->logClustersPtr; + lbh.glyphs = eng->shapedGlyphs(¤t); lbh.spaceData.textWidth += tabWidth; lbh.spaceData.length++; diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp index a9a358711b..4b2970cd17 100644 --- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp @@ -116,6 +116,7 @@ private slots: void boundingRectForSetLineWidth(); void glyphLessItems(); void justifyTrailingSpaces(); + void layoutWithCustomTabStops(); // QTextLine stuff void setNumColumnsWrapAtWordBoundaryOrAnywhere(); @@ -2050,5 +2051,38 @@ void tst_QTextLayout::nbsp() layout.endLayout(); } +void tst_QTextLayout::layoutWithCustomTabStops() +{ + QScopedPointer textLayout(new QTextLayout); + QList tabStops; + + const int tabWidth = 18; + const int maxTabPos = 2500; + for (int tabPos = tabWidth; tabPos < maxTabPos; tabPos += tabWidth) + tabStops << QTextOption::Tab(tabPos, QTextOption::LeftTab); + + QTextOption textOption; + textOption.setTabs(tabStops); + textLayout->setTextOption(textOption); + + textLayout->setText(QStringLiteral("\ta aa aa aa aa aa aa")); + + textLayout->beginLayout(); + textLayout->createLine(); + textLayout->endLayout(); + + qreal shortWidth = textLayout->maximumWidth(); + + textLayout->setText(QStringLiteral("\ta aa aa aa aa aa aa aa aa aa aa aa aa a")); + + textLayout->beginLayout(); + textLayout->createLine(); + textLayout->endLayout(); + + qreal longWidth = textLayout->maximumWidth(); + + QVERIFY(longWidth > shortWidth); +} + QTEST_MAIN(tst_QTextLayout) #include "tst_qtextlayout.moc" -- cgit v1.2.3 From 87ede1fc7a2b8f184733c8f09ccd8732b6b60353 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Klitzing?= Date: Tue, 25 Nov 2014 16:38:34 +0100 Subject: Fix constant "Qt" LOG_TAG in Android The LOG_TAG for Android can be set by QCoreApplication::applicationName instead of a constant "Qt" tag. This will avoid that multiple apps will use the same tag. Also it will be easier to filter the logs for different apps instead of "adb logcat -s Qt" for all Qt apps. Change-Id: I422cc3adf8b526634b5daa9a1bb1b90403de5618 Reviewed-by: Thiago Macieira --- src/corelib/global/qlogging.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 843ec6b0ca..0271573445 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1286,8 +1286,8 @@ static void android_default_message_handler(QtMsgType type, case QtFatalMsg: priority = ANDROID_LOG_FATAL; break; }; - __android_log_print(priority, "Qt", "%s:%d (%s): %s\n", - context.file, context.line, + __android_log_print(priority, qPrintable(QCoreApplication::applicationName()), + "%s:%d (%s): %s\n", context.file, context.line, context.function, qPrintable(message)); } #endif //Q_OS_ANDROID -- cgit v1.2.3 From 2746fe4243c03c4411f1f279df85db5cdd4c01b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Mon, 15 Dec 2014 21:02:39 +0000 Subject: QColorDialog: Fix matching against predefined colors. The grids are filled top to bottom, left to right, so use division to get the column. Task-number: QTBUG-43371 Change-Id: I02ad518512858ed71e0e3a0cae8c4e02d537a9b9 Reviewed-by: Friedemann Kleint --- src/widgets/dialogs/qcolordialog.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 33b374c1bc..ee3ece2d77 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -1489,8 +1489,8 @@ bool QColorDialogPrivate::selectColor(const QColor &col) const QRgb *match = std::find(standardColors, standardColorsEnd, color); if (match != standardColorsEnd) { const int index = int(match - standardColors); - const int row = index / standardColorRows; - const int column = index % standardColorRows; + const int column = index / standardColorRows; + const int row = index % standardColorRows; _q_newStandard(row, column); standard->setCurrent(row, column); standard->setSelected(row, column); @@ -1505,8 +1505,8 @@ bool QColorDialogPrivate::selectColor(const QColor &col) const QRgb *match = std::find(customColors, customColorsEnd, color); if (match != customColorsEnd) { const int index = int(match - customColors); - const int row = index / customColorRows; - const int column = index % customColorRows; + const int column = index / customColorRows; + const int row = index % customColorRows; _q_newCustom(row, column); custom->setCurrent(row, column); custom->setSelected(row, column); -- cgit v1.2.3 From dd91e1bc4df77dfda2efd717bb5cd2a8a7b79908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= Date: Tue, 16 Dec 2014 09:58:59 +0200 Subject: Blacklist ioGetFromHttpBrokenServer:no-newline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-43388 Change-Id: Ie589d72723520152a4cdb28b2fe40e3013b0dd50 Reviewed-by: Simo Fält --- tests/auto/network/access/qnetworkreply/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index 7792e05e0f..84ccb49e58 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -2,6 +2,8 @@ osx [ioGetFromBuiltinHttp:https+limited] osx +[ioGetFromHttpBrokenServer:no-newline] +osx [synchronousRequest:https] osx [SslHandshakeFailedError] -- cgit v1.2.3 From c07559bf5b352932dc4972a61c2c5f9b4ddc3c99 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 17 Dec 2014 08:54:11 +0100 Subject: QOpenGLContext: Use static invocation of QGuiApplication::platformNativeInterface(). Fix MSVC warning (release build): qopenglcontext.cpp(1116) : warning C4189: 'app' : local variable is initialized but not referenced Change-Id: I00fa5237bbac4c0e3bb63ea9d3e5096e05dbe1be Reviewed-by: Laszlo Agocs --- src/gui/kernel/qopenglcontext.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 1a8a534e11..c01e1c95dd 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -1113,9 +1113,9 @@ void QOpenGLContext::deleteQGLContext() void *QOpenGLContext::openGLModuleHandle() { #ifdef QT_OPENGL_DYNAMIC - QGuiApplication *app = qGuiApp; - Q_ASSERT(app); - return app->platformNativeInterface()->nativeResourceForIntegration(QByteArrayLiteral("glhandle")); + QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface(); + Q_ASSERT(ni); + return ni->nativeResourceForIntegration(QByteArrayLiteral("glhandle")); #else return 0; #endif -- cgit v1.2.3 From 7f6c4390ec98b644cc3c07cc5aa5f47da37c8dd3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 15 Dec 2014 14:18:13 +0100 Subject: Windows: Return false from event processing of unhandled multimedia keys. Otherwise, potentially active players no longer receive the keys when a Qt application is running. Task-number: QTBUG-43343 Change-Id: Iefa511a101734690305e3244fafec4a460a9212d Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowskeymapper.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index ff9ad1874a..d781cdbe9c 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -833,7 +833,10 @@ bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, con const int qtKey = CmdTbl[cmd]; sendExtendedPressRelease(receiver, qtKey, Qt::KeyboardModifier(state), 0, 0, 0); - return true; + // QTBUG-43343: Make sure to return false if Qt does not handle the key, otherwise, + // the keys are not passed to the active media player. + const QKeySequence sequence(Qt::Modifier(state) + qtKey); + return QGuiApplicationPrivate::instance()->shortcutMap.hasShortcutForKeySequence(sequence); #else Q_UNREACHABLE(); return false; -- cgit v1.2.3 From bfbb985ed5d283114dbe37e6a42a3c19a61cd0d2 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 17 Dec 2014 13:47:19 +0100 Subject: Add some debug information to tst_qwindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test still fails sporadically at a new place, so this adds some debug information when it fails to may help us identify what is going wrong. Change-Id: Ife0f171299ef7e800a2d808602e76ca2f3885964 Reviewed-by: Jørgen Lind --- tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index 2b28f0a1d4..a5442968c6 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -154,6 +154,7 @@ public: void reset() { m_received.clear(); + m_framePositionsOnMove.clear(); } bool event(QEvent *event) @@ -162,6 +163,8 @@ public: m_order << event->type(); if (event->type() == QEvent::Expose) m_exposeRegion = static_cast(event)->region(); + else if (event->type() == QEvent::Move) + m_framePositionsOnMove << framePosition(); return QWindow::event(event); } @@ -181,6 +184,7 @@ public: return m_exposeRegion; } + QVector m_framePositionsOnMove; private: QHash m_received; QVector m_order; @@ -304,9 +308,17 @@ void tst_QWindow::positioning() QPoint framePos = QPlatformScreen::platformScreenForWindow(&window)->availableGeometry().center(); window.reset(); + const QPoint oldFramePos = window.framePosition(); window.setFramePosition(framePos); QTRY_VERIFY(window.received(QEvent::Move)); + if (window.framePosition() != framePos) { + qDebug() << "About to fail auto-test. Here is some additional information:"; + qDebug() << "window.framePosition() == " << window.framePosition(); + qDebug() << "old frame position == " << oldFramePos; + qDebug() << "We received " << window.received(QEvent::Move) << " move events"; + qDebug() << "frame positions after each move event:" << window.m_framePositionsOnMove; + } QTRY_COMPARE(framePos, window.framePosition()); QTRY_COMPARE(originalMargins, window.frameMargins()); QCOMPARE(window.position(), window.framePosition() + QPoint(originalMargins.left(), originalMargins.top())); -- cgit v1.2.3 From 9f63e2dc0e57fc35683f1aec915f699647987408 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 16 Dec 2014 14:51:21 +0100 Subject: Fix PDF when embedding fonts with large internal leading Setting lfHeight to a positive value in LOGFONT requests the font with the given cell height, which is em square size + internal leading. When setting this to the em square size, it means we will get glyphs that are actually sized for an em square with sides that are (emSquareSize - internalLeading). For most fonts, this was not noticeable, but for some fonts with large internal leading, the resulting glyphs would be very small. When setting lfHeight to something < 0 instead, we are selecting the font with the given character height instead, which is not including the internal leading. [ChangeLog][PDF] Fix embedding glyphs from fonts with large internal leading. Task-number: QTBUG-43082 Change-Id: Id74cf2279df2062804e9431fe305d803cb0b19d2 Reviewed-by: Lars Knoll Reviewed-by: Konstantin Ritt --- src/plugins/platforms/windows/qwindowsfontengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index 38856a69de..e45ff5d744 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -1017,7 +1017,7 @@ QFontEngine::Properties QWindowsFontEngine::properties() const void QWindowsFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics) { LOGFONT lf = m_logfont; - lf.lfHeight = unitsPerEm; + lf.lfHeight = -unitsPerEm; int flags = synthesized(); if(flags & SynthesizedItalic) lf.lfItalic = false; -- cgit v1.2.3 From 2dbbff0364bd36bc25737cb31516f98e0546c9dc Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 16 Dec 2014 12:18:25 +0100 Subject: Build Android style on Windows host The Windows configure application was missing the logic to enable the Android style, so this was missing from the Windows packages. [ChangeLog][Android] Included Android style on Windows hosts. Task-number: QTBUG-43302 Change-Id: I6a1423d58d00e7b4d4fd0a3d1a12cce10aa2fc91 Reviewed-by: BogDan Vatra Reviewed-by: Oswald Buddenhagen --- tools/configure/configureapp.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 92422c2829..2bd94c199e 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -1700,6 +1700,7 @@ void Configure::applySpecSpecifics() dictionary[ "QT_GETIFADDRS" ] = "no"; dictionary[ "QT_XKBCOMMON" ] = "no"; dictionary["ANDROID_STYLE_ASSETS"] = "yes"; + dictionary[ "STYLE_ANDROID" ] = "yes"; } } @@ -2712,6 +2713,9 @@ void Configure::generateOutputVars() if (dictionary[ "STYLE_WINDOWSMOBILE" ] == "yes") qmakeStyles += "windowsmobile"; + if (dictionary[ "STYLE_ANDROID" ] == "yes") + qmakeStyles += "android"; + // Databases ---------------------------------------------------- if (dictionary[ "SQL_MYSQL" ] == "yes") qmakeSql += "mysql"; -- cgit v1.2.3 From 8eb4b281d9449ebf6d03e5460173719e68cce7d9 Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Thu, 11 Dec 2014 14:17:20 +0100 Subject: Change bugreports.qt-project.org -> bugreports.qt.io The Qt bug tracker URL changes as part of the qt.io transition Change-Id: Icb4ab198943b93639b5e3a8d99262303785c6459 Reviewed-by: Kai Koehne --- doc/global/externalsites/qt-webpages.qdoc | 2 +- doc/global/html-header-online.qdocconf | 2 +- examples/webkit/webkit-guide/_index.html | 2 +- src/corelib/global/qnamespace.qdoc | 2 +- src/corelib/tools/qlocale_mac.mm | 2 +- src/network/access/qhttpnetworkconnectionchannel.cpp | 2 +- src/network/access/qnetworkcookie.cpp | 2 +- src/platformsupport/eglconvenience/qxlibeglintegration.cpp | 2 +- tests/auto/gui/image/qimagereader/tst_qimagereader.cpp | 2 +- tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp | 2 +- .../tst_qnetworkconfigurationmanagerqappless.cpp | 2 +- tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp | 2 +- tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp | 2 +- tests/auto/widgets/util/qscroller/tst_qscroller.cpp | 6 +++--- tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp | 2 +- 15 files changed, 17 insertions(+), 17 deletions(-) diff --git a/doc/global/externalsites/qt-webpages.qdoc b/doc/global/externalsites/qt-webpages.qdoc index fabead9747..db946b41da 100644 --- a/doc/global/externalsites/qt-webpages.qdoc +++ b/doc/global/externalsites/qt-webpages.qdoc @@ -29,7 +29,7 @@ \title Qt Homepage */ /*! - \externalpage http://bugreports.qt-project.org + \externalpage http://bugreports.qt.io \title Qt Bug Tracker */ /*! diff --git a/doc/global/html-header-online.qdocconf b/doc/global/html-header-online.qdocconf index 7e9aae66f1..049b649b97 100644 --- a/doc/global/html-header-online.qdocconf +++ b/doc/global/html-header-online.qdocconf @@ -117,7 +117,7 @@ HTML.postheader = \ "
  • Wiki
  • \n" \ "
  • Documentation
  • \n" \ "
  • Forum
  • \n" \ - "
  • Bug Reports
  • \n" \ + "
  • Bug Reports
  • \n" \ "
  • Code Review
  • \n" \ " \n" \ "
    \n" \ diff --git a/examples/webkit/webkit-guide/_index.html b/examples/webkit/webkit-guide/_index.html index cd6cd88fa3..135d46e7dd 100644 --- a/examples/webkit/webkit-guide/_index.html +++ b/examples/webkit/webkit-guide/_index.html @@ -298,7 +298,7 @@ entered (localStorage), but credit-card data s/b absent
    X

    Thank you for giving your feedback.

    Make sure it is related to this specific page. For more general bugs and - requests, please use the Qt Bug Tracker.

    + requests, please use the Qt Bug Tracker.

    diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 53d2b7b58b..04055a3308 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2612,7 +2612,7 @@ \value ElideNone Ellipsis should NOT appear in the text. Qt::ElideMiddle is normally the most appropriate choice for URLs (e.g., - "\l{http://bugreports.qt-project.org/browse/QTWEBSITE-13}{http://bugreports.qt.../QTWEBSITE-13/}"), + "\l{http://bugreports.qt.io/browse/QTWEBSITE-13}{http://bugreports.qt.../QTWEBSITE-13/}"), whereas Qt::ElideRight is appropriate for other strings (e.g., "\l{http://doc.qt.digia.com/qq/qq09-mac-deployment.html}{Deploying Applications on Ma...}"). diff --git a/src/corelib/tools/qlocale_mac.mm b/src/corelib/tools/qlocale_mac.mm index 92dfba162c..612d1e7e15 100644 --- a/src/corelib/tools/qlocale_mac.mm +++ b/src/corelib/tools/qlocale_mac.mm @@ -502,7 +502,7 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const } else if (typeId == CFStringGetTypeID()) { result = QStringList(QCFString::toQString(languages.as())); } else { - qWarning("QLocale::uiLanguages(): CFPreferencesCopyValue returned unhandled type \"%s\"; please report to http://bugreports.qt-project.org", + qWarning("QLocale::uiLanguages(): CFPreferencesCopyValue returned unhandled type \"%s\"; please report to http://bugreports.qt.io", qPrintable(QCFString::toQString(CFCopyTypeIDDescription(typeId)))); } return QVariant(result); diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 49aaafe5e1..d24fb159e2 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -361,7 +361,7 @@ void QHttpNetworkConnectionChannel::allDone() Q_ASSERT(reply); if (!reply) { - qWarning() << "QHttpNetworkConnectionChannel::allDone() called without reply. Please report at http://bugreports.qt-project.org/"; + qWarning() << "QHttpNetworkConnectionChannel::allDone() called without reply. Please report at http://bugreports.qt.io/"; return; } diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 43d527e18d..91abd9dee6 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -1006,7 +1006,7 @@ QList QNetworkCookiePrivate::parseSetCookieHeaderLine(const QByt */ void QNetworkCookie::normalize(const QUrl &url) { - // don't do path checking. See http://bugreports.qt-project.org/browse/QTBUG-5815 + // don't do path checking. See QTBUG-5815 if (d->path.isEmpty()) { QString pathAndFileName = url.path(); QString defaultPath = pathAndFileName.left(pathAndFileName.lastIndexOf(QLatin1Char('/'))+1); diff --git a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp index ff7e6ce271..eb6e01c585 100644 --- a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp +++ b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp @@ -67,7 +67,7 @@ VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay chosenVisualInfo = XGetVisualInfo(display, VisualIDMask, &visualInfoTemplate, &matchingCount); if (chosenVisualInfo) { // Skip size checks if implementation supports non-matching visual - // and config (http://bugreports.qt-project.org/browse/QTBUG-9444). + // and config (QTBUG-9444). if (q_hasEglExtension(eglDisplay,"EGL_NV_post_convert_rounding")) { XFree(chosenVisualInfo); return visualId; diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp index 184cc872a1..f1c1012371 100644 --- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp @@ -791,7 +791,7 @@ void tst_QImageReader::animatedGif() } } -// http://bugreports.qt-project.org/browse/QTBUG-6696 +// QTBUG-6696 // Check the count of images in various call orders... void tst_QImageReader::gifImageCount() { diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 49cdeb71cf..3ccedf6248 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -7236,7 +7236,7 @@ void tst_QNetworkReply::synchronousRequest() // workaround for HTTPS requests: add self-signed server cert to list of CA certs, // since we cannot react to the sslErrors() signal // to fix this properly we would need to have an ignoreSslErrors() method in the - // QNetworkRequest, see http://bugreports.qt-project.org/browse/QTBUG-14774 + // QNetworkRequest, see QTBUG-14774 if (url.scheme() == "https") { QSslConfiguration sslConf; QList certs = QSslCertificate::fromPath(testDataDir + "/certs/qt-test-server-cacert.pem"); diff --git a/tests/auto/network/bearer/qnetworkconfigurationmanagerqappless/tst_qnetworkconfigurationmanagerqappless.cpp b/tests/auto/network/bearer/qnetworkconfigurationmanagerqappless/tst_qnetworkconfigurationmanagerqappless.cpp index 39d5a22dbe..00a63ff132 100644 --- a/tests/auto/network/bearer/qnetworkconfigurationmanagerqappless/tst_qnetworkconfigurationmanagerqappless.cpp +++ b/tests/auto/network/bearer/qnetworkconfigurationmanagerqappless/tst_qnetworkconfigurationmanagerqappless.cpp @@ -47,7 +47,7 @@ private slots: void tst_QNetworkConfigurationManager::staticsInitialization() { // This code should not crash. The test was introduced as - // a fix for https://bugreports.qt-project.org/browse/QTBUG-36897 + // a fix for QTBUG-36897 for (int i = 0; i < 2; i++) { int argc = 1; diff --git a/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp b/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp index 87342508df..a225bbdb1e 100644 --- a/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp +++ b/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp @@ -195,7 +195,7 @@ void tst_QGLBuffer::testBuffer(QGLBuffer::Type type) void tst_QGLBuffer::bufferSharing() { #if defined(Q_OS_WIN) - // Needs investigation on Windows: https://bugreports.qt-project.org/browse/QTBUG-29692 + // Needs investigation on Windows: QTBUG-29692 QSKIP("Unreproducible timeout on Windows (MSVC/MinGW) CI bots"); #endif diff --git a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp index e3a72f4ab4..78aa0af43d 100644 --- a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp +++ b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp @@ -735,7 +735,7 @@ void tst_QPrinter::customPaperNameSettingBySize() // Fail with the original values if (!paperNameFound) { qDebug() << "supportedPageSizes() = " << sizes; - QEXPECT_FAIL("", "Paper Name mismatch: please report this failure at bugreports.qt-project.org", Continue); + QEXPECT_FAIL("", "Paper Name mismatch: please report this failure at bugreports.qt.io", Continue); QCOMPARE(sizes.at(i).name(), printer.paperName()); } } diff --git a/tests/auto/widgets/util/qscroller/tst_qscroller.cpp b/tests/auto/widgets/util/qscroller/tst_qscroller.cpp index 5c299bab42..03b748c0dd 100644 --- a/tests/auto/widgets/util/qscroller/tst_qscroller.cpp +++ b/tests/auto/widgets/util/qscroller/tst_qscroller.cpp @@ -356,7 +356,7 @@ void tst_QScroller::scrollerProperties() void tst_QScroller::scrollTo() { #ifdef Q_OS_MAC - QSKIP("Flakey test - https://bugreports.qt-project.org/browse/QTBUG-29950"); + QSKIP("Flakey test - QTBUG-29950"); #endif { tst_QScrollerWidget *sw = new tst_QScrollerWidget(); @@ -385,7 +385,7 @@ void tst_QScroller::scrollTo() void tst_QScroller::scroll() { #ifdef Q_OS_MAC - QSKIP("Flakey test - https://bugreports.qt-project.org/browse/QTBUG-30133"); + QSKIP("Flakey test - QTBUG-30133"); #endif #ifndef QT_NO_GESTURES // -- good case. normal scroll @@ -430,7 +430,7 @@ void tst_QScroller::scroll() void tst_QScroller::overshoot() { #ifdef Q_OS_MAC - QSKIP("Flakey test - https://bugreports.qt-project.org/browse/QTBUG-29950"); + QSKIP("Flakey test - QTBUG-29950"); #endif #ifndef QT_NO_GESTURES tst_QScrollerWidget *sw = new tst_QScrollerWidget(); diff --git a/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp b/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp index 78f30f4e42..cb0383c398 100644 --- a/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp +++ b/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp @@ -151,7 +151,7 @@ void tst_QScrollBar::task_209492() #define WHEEL_DELTA 120 // copied from tst_QAbstractSlider / tst_QComboBox void tst_QScrollBar::QTBUG_27308() { - // https://bugreports.qt-project.org/browse/QTBUG-27308 + // QTBUG-27308 // Check that a disabled scrollbar doesn't react on wheel events anymore QScrollBar testWidget(Qt::Horizontal); -- cgit v1.2.3 From b8e71aa8477765008798d4bd7887244cb4cc2db7 Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Thu, 18 Dec 2014 08:58:59 +0100 Subject: Qt should not print warning unless we have an API miss-usage case This warning is always printed. Change-Id: I524011f251f7f7e0d76eb94b16e1511e72f26422 Reviewed-by: Lorn Potter --- src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp index fad94f069d..9f4ae55e78 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp @@ -146,7 +146,7 @@ QDBusInterface *QNetworkManagerInterface::connectionInterface() const QList QNetworkManagerInterface::getDevices() { if (devicesPathList.isEmpty()) { - qWarning() << "using blocking call!"; + //qWarning() << "using blocking call!"; QDBusReply > reply = d->connectionInterface->call(QLatin1String("GetDevices")); devicesPathList = reply.value(); } @@ -779,7 +779,7 @@ QDBusInterface *QNetworkManagerInterfaceDeviceWireless::connectionInterface() co QList QNetworkManagerInterfaceDeviceWireless::getAccessPoints() { if (accessPointsList.isEmpty()) { - qWarning() << "Using blocking call!"; + //qWarning() << "Using blocking call!"; QDBusReply > reply = d->connectionInterface->call(QLatin1String("GetAccessPoints")); accessPointsList = reply.value(); @@ -997,7 +997,7 @@ bool QNetworkManagerSettings::setConnections() QList QNetworkManagerSettings::listConnections() { if (connectionsList.isEmpty()) { - qWarning() << "Using blocking call!"; + //qWarning() << "Using blocking call!"; QDBusReply > reply = d->connectionInterface->call(QLatin1String("ListConnections")); connectionsList = reply.value(); @@ -1103,7 +1103,7 @@ QDBusInterface *QNetworkManagerSettingsConnection::connectionInterface() const QNmSettingsMap QNetworkManagerSettingsConnection::getSettings() { if (d->settingsMap.isEmpty()) { - qWarning() << "Using blocking call!"; + //qWarning() << "Using blocking call!"; QDBusReply reply = d->connectionInterface->call(QLatin1String("GetSettings")); d->settingsMap = reply.value(); } -- cgit v1.2.3 From 6c2da36c22e25e626a9812419332ad379e854133 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 12 Dec 2014 12:59:43 +0100 Subject: Prevent continuous painting with viewport QOpenGLWidget MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the source widget to the texture list (may be null for custom compositor implementations that add textures not belonging to actual widgets). This allows us to do proper checks with the dirtyRenderToTextureWidgets list. As a result paint events are only sent to a QOpenGLWidget if (1) there was an update() for it or (2) it was actually marked dirty. (2) was previously behaving differently: the widget got a paint event when anything in the window has changed. This is fine for naive animating OpenGL code but less ideal for QGraphicsView. Bool properties like stacksOnTop are now stored in a flags value to prevent future explosion of texture list fields and parameters. Task-number: QTBUG-43178 Change-Id: I48cbcf93df72ac682c9b5d64982a8b648fe21ef3 Reviewed-by: Jørgen Lind Reviewed-by: Paul Olav Tvete --- src/gui/painting/qplatformbackingstore.cpp | 22 ++++++--- src/gui/painting/qplatformbackingstore.h | 11 ++++- .../eglconvenience/qeglcompositor.cpp | 4 +- .../eglconvenience/qeglplatformbackingstore.cpp | 6 +-- src/widgets/kernel/qwidgetbackingstore.cpp | 31 ++++++------- .../widgets/qopenglwidget/tst_qopenglwidget.cpp | 52 ++++++++++++++++++++++ 6 files changed, 94 insertions(+), 32 deletions(-) diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index e87f796888..76269f6e65 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -82,9 +82,10 @@ public: struct QBackingstoreTextureInfo { + QWidget *widget; // may be null GLuint textureId; QRect rect; - bool stacksOnTop; + QPlatformTextureList::Flags flags; }; Q_DECLARE_TYPEINFO(QBackingstoreTextureInfo, Q_MOVABLE_TYPE); @@ -122,10 +123,16 @@ GLuint QPlatformTextureList::textureId(int index) const return d->textures.at(index).textureId; } -bool QPlatformTextureList::stacksOnTop(int index) const +QWidget *QPlatformTextureList::widget(int index) { Q_D(const QPlatformTextureList); - return d->textures.at(index).stacksOnTop; + return d->textures.at(index).widget; +} + +QPlatformTextureList::Flags QPlatformTextureList::flags(int index) const +{ + Q_D(const QPlatformTextureList); + return d->textures.at(index).flags; } QRect QPlatformTextureList::geometry(int index) const @@ -149,13 +156,14 @@ bool QPlatformTextureList::isLocked() const return d->locked; } -void QPlatformTextureList::appendTexture(GLuint textureId, const QRect &geometry, bool stacksOnTop) +void QPlatformTextureList::appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, Flags flags) { Q_D(QPlatformTextureList); QBackingstoreTextureInfo bi; + bi.widget = widget; bi.textureId = textureId; bi.rect = geometry; - bi.stacksOnTop = stacksOnTop; + bi.flags = flags; d->textures.append(bi); } @@ -245,7 +253,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i // Textures for renderToTexture widgets. for (int i = 0; i < textures->count(); ++i) { - if (!textures->stacksOnTop(i)) { + if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { QRect targetRect = deviceRect(textures->geometry(i), window); QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect); d_ptr->blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft); @@ -272,7 +280,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i // Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set. for (int i = 0; i < textures->count(); ++i) { - if (textures->stacksOnTop(i)) { + if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { QRect targetRect = deviceRect(textures->geometry(i), window); QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect); d_ptr->blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft); diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h index 52c263f05d..c69612ca44 100644 --- a/src/gui/painting/qplatformbackingstore.h +++ b/src/gui/painting/qplatformbackingstore.h @@ -69,6 +69,11 @@ class Q_GUI_EXPORT QPlatformTextureList : public QObject Q_OBJECT Q_DECLARE_PRIVATE(QPlatformTextureList) public: + enum Flag { + StacksOnTop = 0x01 + }; + Q_DECLARE_FLAGS(Flags, Flag) + explicit QPlatformTextureList(QObject *parent = 0); ~QPlatformTextureList(); @@ -76,16 +81,18 @@ public: bool isEmpty() const { return count() == 0; } GLuint textureId(int index) const; QRect geometry(int index) const; - bool stacksOnTop(int index) const; + QWidget *widget(int index); + Flags flags(int index) const; void lock(bool on); bool isLocked() const; - void appendTexture(GLuint textureId, const QRect &geometry, bool stacksOnTop = false); + void appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, Flags flags = 0); void clear(); Q_SIGNALS: void locked(bool); }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QPlatformTextureList::Flags) #endif class Q_GUI_EXPORT QPlatformBackingStore diff --git a/src/platformsupport/eglconvenience/qeglcompositor.cpp b/src/platformsupport/eglconvenience/qeglcompositor.cpp index 5866edc48d..a46e5698de 100644 --- a/src/platformsupport/eglconvenience/qeglcompositor.cpp +++ b/src/platformsupport/eglconvenience/qeglcompositor.cpp @@ -151,7 +151,7 @@ void QEGLCompositor::render(QEGLPlatformWindow *window) const bool translucent = window->window()->requestedFormat().alphaBufferSize() > 0; blend.set(translucent); m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft); - } else if (!textures->stacksOnTop(i)) { + } else if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { // Texture from an FBO belonging to a QOpenGLWidget blend.set(false); m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft); @@ -159,7 +159,7 @@ void QEGLCompositor::render(QEGLPlatformWindow *window) } for (int i = 0; i < textures->count(); ++i) { - if (textures->stacksOnTop(i)) { + if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); blend.set(true); m_blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft); diff --git a/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp b/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp index 43c18573f2..d7d95ea97d 100644 --- a/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp @@ -152,7 +152,7 @@ void QEGLPlatformBackingStore::flush(QWindow *window, const QRegion ®ion, con screen->compositingContext()->makeCurrent(dstWin->window()); updateTexture(); m_textures->clear(); - m_textures->appendTexture(m_bsTexture, window->geometry()); + m_textures->appendTexture(Q_NULLPTR, m_bsTexture, window->geometry()); composite(screen->compositingContext(), dstWin); } @@ -176,10 +176,10 @@ void QEGLPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &r m_textures->clear(); for (int i = 0; i < textures->count(); ++i) - m_textures->appendTexture(textures->textureId(i), textures->geometry(i), textures->stacksOnTop(i)); + m_textures->appendTexture(textures->widget(i), textures->textureId(i), textures->geometry(i), textures->flags(i)); updateTexture(); - m_textures->appendTexture(m_bsTexture, window->geometry()); + m_textures->appendTexture(Q_NULLPTR, m_bsTexture, window->geometry()); textures->lock(true); m_lockedWidgetTextures = textures; diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 9f014aa4fe..cd01869af2 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -963,9 +963,12 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg static void findTextureWidgetsRecursively(QWidget *tlw, QWidget *widget, QPlatformTextureList *widgetTextures) { QWidgetPrivate *wd = QWidgetPrivate::get(widget); - if (wd->renderToTexture) - widgetTextures->appendTexture(wd->textureId(), QRect(widget->mapTo(tlw, QPoint()), widget->size()), - widget->testAttribute(Qt::WA_AlwaysStackOnTop)); + if (wd->renderToTexture) { + QPlatformTextureList::Flags flags = 0; + if (widget->testAttribute(Qt::WA_AlwaysStackOnTop)) + flags |= QPlatformTextureList::StacksOnTop; + widgetTextures->appendTexture(widget, wd->textureId(), QRect(widget->mapTo(tlw, QPoint()), widget->size()), flags); + } for (int i = 0; i < wd->children.size(); ++i) { QWidget *w = qobject_cast(wd->children.at(i)); @@ -1156,28 +1159,20 @@ void QWidgetBackingStore::doSync() } #ifndef QT_NO_OPENGL - // There is something other dirty than the renderToTexture widgets. - // Now it is time to include the renderToTexture ones among the others. if (widgetTextures && widgetTextures->count()) { for (int i = 0; i < widgetTextures->count(); ++i) { - const QRect rect = widgetTextures->geometry(i); // mapped to the tlw already - dirty += rect; - toClean += rect; + QWidget *w = widgetTextures->widget(i); + if (dirtyRenderToTextureWidgets.contains(w)) { + const QRect rect = widgetTextures->geometry(i); // mapped to the tlw already + dirty += rect; + toClean += rect; + } } } -#endif - - // The dirtyRenderToTextureWidgets list is useless here, so just reset. As - // unintuitive as it is, we need to send paint events to renderToTexture - // widgets always when something (any widget) needs to be updated, even if - // the renderToTexture widget itself is clean, i.e. there was no update() - // call for it. This is because changing any widget will cause a flush and - // so a potentially blocking buffer swap for the window, and skipping paints - // for the renderToTexture widgets would make it impossible to have smoothly - // animated content in them. for (int i = 0; i < dirtyRenderToTextureWidgets.count(); ++i) resetWidget(dirtyRenderToTextureWidgets.at(i)); dirtyRenderToTextureWidgets.clear(); +#endif #ifndef QT_NO_GRAPHICSVIEW if (tlw->d_func()->extra->proxyWidget) { diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp index d309b0840e..2ac31bfe1b 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp +++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp @@ -34,6 +34,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include @@ -49,6 +54,7 @@ private slots: void painter(); void reparentToAlreadyCreated(); void reparentToNotYetCreated(); + void asViewport(); }; void tst_QOpenGLWidget::create() @@ -253,6 +259,52 @@ void tst_QOpenGLWidget::reparentToNotYetCreated() QVERIFY(image.pixel(20, 10) == qRgb(0, 0, 255)); } +class CountingGraphicsView : public QGraphicsView +{ +public: + CountingGraphicsView(): m_count(0) { } + int paintCount() const { return m_count; } + void resetPaintCount() { m_count = 0; } + +protected: + void drawForeground(QPainter *, const QRectF &) Q_DECL_OVERRIDE; + int m_count; +}; + +void CountingGraphicsView::drawForeground(QPainter *, const QRectF &) +{ + ++m_count; +} + +void tst_QOpenGLWidget::asViewport() +{ + // Have a QGraphicsView with a QOpenGLWidget as its viewport. + QGraphicsScene scene; + scene.addItem(new QGraphicsRectItem(10, 10, 100, 100)); + CountingGraphicsView *view = new CountingGraphicsView; + view->setScene(&scene); + view->setViewport(new QOpenGLWidget); + QWidget widget; + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(view); + QPushButton *btn = new QPushButton("Test"); + layout->addWidget(btn); + widget.setLayout(layout); + widget.show(); + QTest::qWaitForWindowExposed(&widget); + + QVERIFY(view->paintCount() > 0); + view->resetPaintCount(); + + // And now trigger a repaint on the push button. We must not + // receive paint events for the graphics view. If we do, that's a + // side effect of QOpenGLWidget's special behavior and handling in + // the widget stack. + btn->update(); + qApp->processEvents(); + QVERIFY(view->paintCount() == 0); +} + QTEST_MAIN(tst_QOpenGLWidget) #include "tst_qopenglwidget.moc" -- cgit v1.2.3 From 14e2d8cc09192ee5ae6e6d8556135e4bc4e38f62 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Fri, 12 Dec 2014 15:58:50 +0200 Subject: Update gradle build script. Change-Id: If5142c039b6307660402f1dbd30ded75e12f8c50 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/android/templates/build.gradle | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/android/templates/build.gradle b/src/android/templates/build.gradle index d1ff362269..81acf81c4c 100644 --- a/src/android/templates/build.gradle +++ b/src/android/templates/build.gradle @@ -1,14 +1,20 @@ buildscript { repositories { - mavenCentral() + jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:0.12.1' + classpath 'com.android.tools.build:gradle:1.0.0' } } -apply plugin: 'android' +allprojects { + repositories { + jcenter() + } +} + +apply plugin: 'com.android.application' dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) -- cgit v1.2.3 From 84569773db68408704193268bc42a200bb25a924 Mon Sep 17 00:00:00 2001 From: Marko Kangas Date: Tue, 16 Dec 2014 17:56:40 +0200 Subject: Fix OS X style MDI area subwindow resize Fixed regression bug of the commit #fc11798 Change-Id: I3d64fd67dfe2196a726886a19b9510dd12ff255d Task-number: QTBUG-43392 Reviewed-by: Andy Shaw --- src/widgets/styles/qmacstyle_mac.mm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 5c17cdf489..c166b1b26e 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -879,6 +879,10 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg gbi.size = sz == QAquaSizeSmall ? kHIThemeGrowBoxSizeSmall : kHIThemeGrowBoxSizeNormal; if (HIThemeGetGrowBoxBounds(&p, &gbi, &r) == noErr) { int width = 0; +#ifndef QT_NO_MDIAREA + if (widg && qobject_cast(widg->parentWidget())) + width = r.size.width; +#endif ret = QSize(width, r.size.height); } } -- cgit v1.2.3