From 112e53fdc4e46a5e94cb2d575d132e2015694407 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 28 Apr 2016 17:47:57 -0700 Subject: [PATCH 01/43] Don't store the pthread_t thread ID twice in QThread MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was being stored once in QThreadPrivate and once in QThreadData, with the latter being hidden as a Qt::HANDLE. Besides saving a little bit of memory, this also solves a small data race condition that arises from trying to connect a signal to an object moved to that thread and then emit that signal shortly after the thread starts. Before this patch, QThreadData::threadId was initialized only by QThreadPrivate::start(), which meant that we were racing that initialization with this check in QMetaObject::activate: const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId; Task-number: QTBUG-52337 Change-Id: Ifea6e497f11a461db432ffff1449ae01f1099aae Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Jędrzej Nowacki --- src/corelib/thread/qthread.cpp | 6 +----- src/corelib/thread/qthread_p.h | 1 - src/corelib/thread/qthread_unix.cpp | 33 +++++++++++++++-------------- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index a0a2e76bda8..8ea487e3301 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -142,16 +142,12 @@ QThreadPrivate::QThreadPrivate(QThreadData *d) exited(false), returnCode(-1), stackSize(0), priority(QThread::InheritPriority), data(d) { -#if defined (Q_OS_UNIX) - thread_id = 0; -#elif defined (Q_OS_WIN) +#if defined (Q_OS_WIN) handle = 0; # ifndef Q_OS_WINRT id = 0; # endif waiters = 0; -#endif -#if defined (Q_OS_WIN) terminationEnabled = true; terminatePending = false; #endif diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index a0d354acdce..a56b879462a 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -169,7 +169,6 @@ public: static QThread *threadForId(int id); #ifdef Q_OS_UNIX - pthread_t thread_id; QWaitCondition thread_done; static void *start(void *arg); diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index af4ce7c59ec..3fc0ebfbb6e 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -105,6 +105,8 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_THREAD +Q_STATIC_ASSERT(sizeof(pthread_t) == sizeof(Qt::HANDLE)); + enum { ThreadPriorityResetFlag = 0x80000000 }; #if defined(Q_OS_LINUX) && defined(__GLIBC__) && (defined(Q_CC_GNU) || defined(Q_CC_INTEL)) && !defined(QT_LINUXBASE) @@ -234,8 +236,6 @@ QThreadData *QThreadData::current(bool createIfNecessary) void QAdoptedThread::init() { - Q_D(QThread); - d->thread_id = pthread_self(); } /* @@ -325,10 +325,11 @@ void *QThreadPrivate::start(void *arg) // sets the name of the current thread. QString objectName = thr->objectName(); + pthread_t thread_id = reinterpret_cast(data->threadId); if (Q_LIKELY(objectName.isEmpty())) - setCurrentThreadName(thr->d_func()->thread_id, thr->metaObject()->className()); + setCurrentThreadName(thread_id, thr->metaObject()->className()); else - setCurrentThreadName(thr->d_func()->thread_id, objectName.toLocal8Bit()); + setCurrentThreadName(thread_id, objectName.toLocal8Bit()); } #endif @@ -369,7 +370,6 @@ void QThreadPrivate::finish(void *arg) locker.relock(); } - d->thread_id = 0; d->running = false; d->finished = true; d->interruptionRequested = false; @@ -615,15 +615,16 @@ void QThread::start(Priority priority) } int code = - pthread_create(&d->thread_id, &attr, QThreadPrivate::start, this); + pthread_create(reinterpret_cast(&d->data->threadId), &attr, + QThreadPrivate::start, this); if (code == EPERM) { // caller does not have permission to set the scheduling // parameters/policy #if defined(QT_HAS_THREAD_PRIORITY_SCHEDULING) pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); #endif - code = - pthread_create(&d->thread_id, &attr, QThreadPrivate::start, this); + code = pthread_create(reinterpret_cast(&d->data->threadId), &attr, + QThreadPrivate::start, this); } pthread_attr_destroy(&attr); @@ -633,7 +634,7 @@ void QThread::start(Priority priority) d->running = false; d->finished = false; - d->thread_id = 0; + d->data->threadId = 0; } } @@ -643,10 +644,10 @@ void QThread::terminate() Q_D(QThread); QMutexLocker locker(&d->mutex); - if (!d->thread_id) + if (!d->data->threadId) return; - int code = pthread_cancel(d->thread_id); + int code = pthread_cancel(reinterpret_cast(d->data->threadId)); if (code) { qWarning("QThread::start: Thread termination error: %s", qPrintable(qt_error_string((code)))); @@ -659,7 +660,7 @@ bool QThread::wait(unsigned long time) Q_D(QThread); QMutexLocker locker(&d->mutex); - if (d->thread_id == pthread_self()) { + if (reinterpret_cast(d->data->threadId) == pthread_self()) { qWarning("QThread::wait: Thread tried to wait on itself"); return false; } @@ -701,7 +702,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority) int sched_policy; sched_param param; - if (pthread_getschedparam(thread_id, &sched_policy, ¶m) != 0) { + if (pthread_getschedparam(reinterpret_cast(data->threadId), &sched_policy, ¶m) != 0) { // failed to get the scheduling policy, don't bother setting // the priority qWarning("QThread::setPriority: Cannot get scheduler parameters"); @@ -717,15 +718,15 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority) } param.sched_priority = prio; - int status = pthread_setschedparam(thread_id, sched_policy, ¶m); + int status = pthread_setschedparam(reinterpret_cast(data->threadId), sched_policy, ¶m); # ifdef SCHED_IDLE // were we trying to set to idle priority and failed? if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) { // reset to lowest priority possible - pthread_getschedparam(thread_id, &sched_policy, ¶m); + pthread_getschedparam(reinterpret_cast(data->threadId), &sched_policy, ¶m); param.sched_priority = sched_get_priority_min(sched_policy); - pthread_setschedparam(thread_id, sched_policy, ¶m); + pthread_setschedparam(reinterpret_cast(data->threadId), sched_policy, ¶m); } # else Q_UNUSED(status); From fda6324b4d471c2163c94d0c451a4bb4671b7b18 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 28 Apr 2016 18:25:52 -0700 Subject: [PATCH 02/43] Remove the use of QMutexPool from QtDBus loading of libdbus-1 Change-Id: Ifea6e497f11a461db432ffff1449b013c2302d38 Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Marc Mutz --- src/dbus/qdbus_symbols.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dbus/qdbus_symbols.cpp b/src/dbus/qdbus_symbols.cpp index 395a436869c..1b8bcbcd05a 100644 --- a/src/dbus/qdbus_symbols.cpp +++ b/src/dbus/qdbus_symbols.cpp @@ -36,7 +36,6 @@ #include #endif #include -#include #ifndef QT_NO_DBUS @@ -74,8 +73,10 @@ bool qdbus_loadLibDBus() static bool triedToLoadLibrary = false; #ifndef QT_NO_THREAD - QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&qdbus_resolve_me)); + static QBasicMutex mutex; + QMutexLocker locker(&mutex); #endif + QLibrary *&lib = qdbus_libdbus; if (triedToLoadLibrary) return lib && lib->isLoaded(); From c9f9f54d3f79915723270b2a6d06216a54c87433 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 28 Apr 2016 18:36:31 -0700 Subject: [PATCH 03/43] Remove the use of QMutexPool in QHostInfo and QDnsLookup Q_GLOBAL_STATIC does the thread-safe protection for us. And who said we could only use non-POD types? We can just use a boolean! Change-Id: Ifea6e497f11a461db432ffff1449b0a88d75d194 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/network/kernel/qdnslookup_unix.cpp | 17 ++++++----------- src/network/kernel/qhostinfo_unix.cpp | 17 ++++++----------- src/network/kernel/qhostinfo_win.cpp | 14 ++++---------- 3 files changed, 16 insertions(+), 32 deletions(-) diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp index dc8ec5a3006..cb3bdfe8ff2 100644 --- a/src/network/kernel/qdnslookup_unix.cpp +++ b/src/network/kernel/qdnslookup_unix.cpp @@ -36,7 +36,6 @@ #include #include #include -#include #include #include @@ -71,7 +70,7 @@ struct QDnsLookupStateDeleter } }; -static void resolveLibrary() +static bool resolveLibraryInternal() { QLibrary lib; #ifdef LIBRESOLV_SO @@ -81,7 +80,7 @@ static void resolveLibrary() { lib.setFileName(QLatin1String("resolv")); if (!lib.load()) - return; + return false; } local_dn_expand = dn_expand_proto(lib.resolve("__dn_expand")); @@ -105,19 +104,15 @@ static void resolveLibrary() local_res_nquery = res_nquery_proto(lib.resolve("res_9_nquery")); if (!local_res_nquery) local_res_nquery = res_nquery_proto(lib.resolve("res_nquery")); + + return true; } +Q_GLOBAL_STATIC_WITH_ARGS(bool, resolveLibrary, (resolveLibraryInternal())) void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply) { // Load dn_expand, res_ninit and res_nquery on demand. - static QBasicAtomicInt triedResolve = Q_BASIC_ATOMIC_INITIALIZER(false); - if (!triedResolve.loadAcquire()) { - QMutexLocker locker(QMutexPool::globalInstanceGet(&local_res_ninit)); - if (!triedResolve.load()) { - resolveLibrary(); - triedResolve.storeRelease(true); - } - } + resolveLibrary(); // If dn_expand, res_ninit or res_nquery is missing, fail. if (!local_dn_expand || !local_res_nclose || !local_res_ninit || !local_res_nquery) { diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp index 266a67771c9..dabf1913cc4 100644 --- a/src/network/kernel/qhostinfo_unix.cpp +++ b/src/network/kernel/qhostinfo_unix.cpp @@ -43,7 +43,6 @@ #include #include #include -#include #include #include @@ -86,7 +85,7 @@ typedef void (*res_nclose_proto)(res_state_ptr); static res_nclose_proto local_res_nclose = 0; static res_state_ptr local_res = 0; -static void resolveLibrary() +static bool resolveLibraryInternal() { #if !defined(QT_NO_LIBRARY) && !defined(Q_OS_QNX) QLibrary lib; @@ -97,7 +96,7 @@ static void resolveLibrary() { lib.setFileName(QLatin1String("resolv")); if (!lib.load()) - return; + return false; } local_res_init = res_init_proto(lib.resolve("__res_init")); @@ -119,7 +118,10 @@ static void resolveLibrary() local_res_ninit = 0; } #endif + + return true; } +Q_GLOBAL_STATIC_WITH_ARGS(bool, resolveLibrary, (resolveLibraryInternal())) QHostInfo QHostInfoAgent::fromName(const QString &hostName) { @@ -131,14 +133,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) #endif // Load res_init on demand. - static QBasicAtomicInt triedResolve = Q_BASIC_ATOMIC_INITIALIZER(false); - if (!triedResolve.loadAcquire()) { - QMutexLocker locker(QMutexPool::globalInstanceGet(&local_res_init)); - if (!triedResolve.load()) { - resolveLibrary(); - triedResolve.storeRelease(true); - } - } + resolveLibrary(); // If res_init is available, poll it. if (local_res_init) diff --git a/src/network/kernel/qhostinfo_win.cpp b/src/network/kernel/qhostinfo_win.cpp index 7e45e9f9498..58816b355de 100644 --- a/src/network/kernel/qhostinfo_win.cpp +++ b/src/network/kernel/qhostinfo_win.cpp @@ -39,7 +39,6 @@ #include #include #include -#include QT_BEGIN_NAMESPACE @@ -72,7 +71,7 @@ static getnameinfoProto local_getnameinfo = 0; static getaddrinfoProto local_getaddrinfo = 0; static freeaddrinfoProto local_freeaddrinfo = 0; -static void resolveLibrary() +static bool resolveLibraryInternal() { // Attempt to resolve getaddrinfo(); without it we'll have to fall // back to gethostbyname(), which has no IPv6 support. @@ -89,7 +88,9 @@ static void resolveLibrary() local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "freeaddrinfo"); local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getnameinfo"); #endif + return true; } +Q_GLOBAL_STATIC_WITH_ARGS(bool, resolveLibrary, (resolveLibraryInternal())) static void translateWSAError(int error, QHostInfo *results) { @@ -117,14 +118,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) QSysInfo::machineHostName(); // this initializes ws2_32.dll // Load res_init on demand. - static QBasicAtomicInt triedResolve = Q_BASIC_ATOMIC_INITIALIZER(false); - if (!triedResolve.loadAcquire()) { - QMutexLocker locker(QMutexPool::globalInstanceGet(&local_getaddrinfo)); - if (!triedResolve.load()) { - resolveLibrary(); - triedResolve.storeRelease(true); - } - } + resolveLibrary(); QHostInfo results; From a4d26cf522b966056e47e47a004b7e4d668e3a2d Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Fri, 8 Apr 2016 16:55:39 +0300 Subject: [PATCH 04/43] QWindowsPipeWriter: ensure validity of the write buffer QWindowsPipeWriter uses asynchronous API to perform writing. Once a cycle has been started, the write buffer must remain valid until the write operation is completed. To avoid data corruption and possibly undefined behavior, this patch makes QWindowsPipeWriter::write() take a QByteArray, which it keeps alive for the duration of the write cycle. Autotest-by: Thomas Hartmann Task-number: QTBUG-52401 Change-Id: Ia35faee735c4e684267daa1f6bd689512b670cd2 Reviewed-by: Joerg Bornemann --- src/corelib/io/qprocess.cpp | 23 +--- src/corelib/io/qprocess_p.h | 2 +- src/corelib/io/qprocess_unix.cpp | 35 ++++-- src/corelib/io/qprocess_win.cpp | 10 +- src/corelib/io/qprocess_wince.cpp | 6 +- src/corelib/io/qwindowspipewriter.cpp | 41 ++++--- src/corelib/io/qwindowspipewriter_p.h | 4 +- src/network/socket/qlocalsocket.h | 2 +- src/network/socket/qlocalsocket_p.h | 3 +- src/network/socket/qlocalsocket_win.cpp | 24 ++-- .../socket/qlocalsocket/tst_qlocalsocket.cpp | 108 ++++++++++++++++++ 11 files changed, 185 insertions(+), 73 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 68f7157ad23..502628489dc 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1051,7 +1051,6 @@ bool QProcessPrivate::_q_canReadStandardError() */ bool QProcessPrivate::_q_canWrite() { - Q_Q(QProcess); if (stdinChannel.notifier) stdinChannel.notifier->setEnabled(false); @@ -1062,31 +1061,13 @@ bool QProcessPrivate::_q_canWrite() return false; } - qint64 written = writeToStdin(stdinChannel.buffer.readPointer(), - stdinChannel.buffer.nextDataBlockSize()); - if (written < 0) { - closeChannel(&stdinChannel); - setErrorAndEmit(QProcess::WriteError); - return false; - } + const bool writeSucceeded = writeToStdin(); -#if defined QPROCESS_DEBUG - qDebug("QProcessPrivate::canWrite(), wrote %d bytes to the process input", int(written)); -#endif - - if (written != 0) { - stdinChannel.buffer.free(written); - if (!emittedBytesWritten) { - emittedBytesWritten = true; - emit q->bytesWritten(written); - emittedBytesWritten = false; - } - } if (stdinChannel.notifier && !stdinChannel.buffer.isEmpty()) stdinChannel.notifier->setEnabled(true); if (stdinChannel.buffer.isEmpty() && stdinChannel.closed) closeWriteChannel(); - return true; + return writeSucceeded; } /*! diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index 436869462c4..0af19030631 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -375,7 +375,7 @@ public: qint64 bytesAvailableInChannel(const Channel *channel) const; qint64 readFromChannel(const Channel *channel, char *data, qint64 maxlen); - qint64 writeToStdin(const char *data, qint64 maxlen); + bool writeToStdin(); void cleanup(); void setError(QProcess::ProcessError error, const QString &description = QString()); diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index df13a2533e1..fda91780d0f 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -620,21 +620,36 @@ qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint return bytesRead; } -qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) +bool QProcessPrivate::writeToStdin() { - qint64 written = qt_safe_write_nosignal(stdinChannel.pipe[1], data, maxlen); + const char *data = stdinChannel.buffer.readPointer(); + const qint64 bytesToWrite = stdinChannel.buffer.nextDataBlockSize(); + + qint64 written = qt_safe_write_nosignal(stdinChannel.pipe[1], data, bytesToWrite); #if defined QPROCESS_DEBUG - qDebug("QProcessPrivate::writeToStdin(%p \"%s\", %lld) == %lld", - data, qt_prettyDebug(data, maxlen, 16).constData(), maxlen, written); + qDebug("QProcessPrivate::writeToStdin(), write(%p \"%s\", %lld) == %lld", + data, qt_prettyDebug(data, bytesToWrite, 16).constData(), bytesToWrite, written); if (written == -1) qDebug("QProcessPrivate::writeToStdin(), failed to write (%s)", qPrintable(qt_error_string(errno))); #endif - // If the O_NONBLOCK flag is set and If some data can be written without blocking - // the process, write() will transfer what it can and return the number of bytes written. - // Otherwise, it will return -1 and set errno to EAGAIN - if (written == -1 && errno == EAGAIN) - written = 0; - return written; + if (written == -1) { + // If the O_NONBLOCK flag is set and If some data can be written without blocking + // the process, write() will transfer what it can and return the number of bytes written. + // Otherwise, it will return -1 and set errno to EAGAIN + if (errno == EAGAIN) + return true; + + closeChannel(&stdinChannel); + setErrorAndEmit(QProcess::WriteError); + return false; + } + stdinChannel.buffer.free(written); + if (!emittedBytesWritten && written != 0) { + emittedBytesWritten = true; + emit q_func()->bytesWritten(written); + emittedBytesWritten = false; + } + return true; } void QProcessPrivate::terminateProcess() diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 7e9cffe1296..592bee58a53 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -787,17 +787,23 @@ qint64 QProcessPrivate::pipeWriterBytesToWrite() const return stdinChannel.writer ? stdinChannel.writer->bytesToWrite() : qint64(0); } -qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) +bool QProcessPrivate::writeToStdin() { Q_Q(QProcess); if (!stdinChannel.writer) { stdinChannel.writer = new QWindowsPipeWriter(stdinChannel.pipe[1], q); + QObject::connect(stdinChannel.writer, &QWindowsPipeWriter::bytesWritten, + q, &QProcess::bytesWritten); QObjectPrivate::connect(stdinChannel.writer, &QWindowsPipeWriter::canWrite, this, &QProcessPrivate::_q_canWrite); + } else { + if (stdinChannel.writer->isWriteOperationActive()) + return true; } - return stdinChannel.writer->write(data, maxlen); + stdinChannel.writer->write(stdinChannel.buffer.read()); + return true; } bool QProcessPrivate::waitForWrite(int msecs) diff --git a/src/corelib/io/qprocess_wince.cpp b/src/corelib/io/qprocess_wince.cpp index 050d6879db9..ab37a4c4845 100644 --- a/src/corelib/io/qprocess_wince.cpp +++ b/src/corelib/io/qprocess_wince.cpp @@ -265,11 +265,9 @@ qint64 QProcessPrivate::pipeWriterBytesToWrite() const return 0; } -qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) +bool QProcessPrivate::writeToStdin() { - Q_UNUSED(data); - Q_UNUSED(maxlen); - return -1; + return false; } bool QProcessPrivate::waitForWrite(int msecs) diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index ff92ca763e7..05a4aa484a3 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -73,21 +73,19 @@ QWindowsPipeWriter::~QWindowsPipeWriter() bool QWindowsPipeWriter::waitForWrite(int msecs) { - if (!writeSequenceStarted) - return false; - if (bytesWrittenPending) { - if (!inBytesWritten) - emitPendingBytesWrittenValue(); + emitPendingBytesWrittenValue(); return true; } + if (!writeSequenceStarted) + return false; + if (!waitForNotification(msecs)) return false; if (bytesWrittenPending) { - if (!inBytesWritten) - emitPendingBytesWrittenValue(); + emitPendingBytesWrittenValue(); return true; } @@ -96,20 +94,24 @@ bool QWindowsPipeWriter::waitForWrite(int msecs) qint64 QWindowsPipeWriter::bytesToWrite() const { - return numberOfBytesToWrite; + return numberOfBytesToWrite + pendingBytesWrittenValue; } void QWindowsPipeWriter::emitPendingBytesWrittenValue() { if (bytesWrittenPending) { + // Reset the state even if we don't emit bytesWritten(). + // It's a defined behavior to not re-emit this signal recursively. bytesWrittenPending = false; const qint64 bytes = pendingBytesWrittenValue; pendingBytesWrittenValue = 0; - inBytesWritten = true; - emit bytesWritten(bytes); - inBytesWritten = false; emit canWrite(); + if (!inBytesWritten) { + inBytesWritten = true; + emit bytesWritten(bytes); + inBytesWritten = false; + } } } @@ -129,6 +131,8 @@ void QWindowsPipeWriter::notified(DWORD errorCode, DWORD numberOfBytesWritten) notifiedCalled = true; writeSequenceStarted = false; numberOfBytesToWrite = 0; + Q_ASSERT(errorCode != ERROR_SUCCESS || numberOfBytesWritten == buffer.size()); + buffer.clear(); switch (errorCode) { case ERROR_SUCCESS: @@ -173,21 +177,26 @@ bool QWindowsPipeWriter::waitForNotification(int timeout) return notifiedCalled; } -qint64 QWindowsPipeWriter::write(const char *ptr, qint64 maxlen) +bool QWindowsPipeWriter::write(const QByteArray &ba) { if (writeSequenceStarted) - return 0; + return false; overlapped.clear(); - numberOfBytesToWrite = maxlen; + buffer = ba; + numberOfBytesToWrite = buffer.size(); stopped = false; writeSequenceStarted = true; - if (!WriteFileEx(handle, ptr, maxlen, &overlapped, &writeFileCompleted)) { + if (!WriteFileEx(handle, buffer.constData(), numberOfBytesToWrite, + &overlapped, &writeFileCompleted)) { writeSequenceStarted = false; + numberOfBytesToWrite = 0; + buffer.clear(); qErrnoWarning("QWindowsPipeWriter::write failed."); + return false; } - return maxlen; + return true; } void QWindowsPipeWriter::stop() diff --git a/src/corelib/io/qwindowspipewriter_p.h b/src/corelib/io/qwindowspipewriter_p.h index a78ab61adf5..02288675229 100644 --- a/src/corelib/io/qwindowspipewriter_p.h +++ b/src/corelib/io/qwindowspipewriter_p.h @@ -47,6 +47,7 @@ #include #include +#include #include QT_BEGIN_NAMESPACE @@ -106,7 +107,7 @@ public: explicit QWindowsPipeWriter(HANDLE pipeWriteEnd, QObject *parent = 0); ~QWindowsPipeWriter(); - qint64 write(const char *data, qint64 maxlen); + bool write(const QByteArray &ba); void stop(); bool waitForWrite(int msecs); bool isWriteOperationActive() const { return writeSequenceStarted; } @@ -136,6 +137,7 @@ private: HANDLE handle; Overlapped overlapped; + QByteArray buffer; qint64 numberOfBytesToWrite; qint64 pendingBytesWrittenValue; bool stopped; diff --git a/src/network/socket/qlocalsocket.h b/src/network/socket/qlocalsocket.h index 09828c8b0d8..4b39a7c562c 100644 --- a/src/network/socket/qlocalsocket.h +++ b/src/network/socket/qlocalsocket.h @@ -124,7 +124,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QAbstractSocket::SocketState)) Q_PRIVATE_SLOT(d_func(), void _q_error(QAbstractSocket::SocketError)) #elif defined(Q_OS_WIN) - Q_PRIVATE_SLOT(d_func(), void _q_bytesWritten(qint64)) + Q_PRIVATE_SLOT(d_func(), void _q_canWrite()) Q_PRIVATE_SLOT(d_func(), void _q_pipeClosed()) Q_PRIVATE_SLOT(d_func(), void _q_winError(ulong, const QString &)) #else diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h index a594605ae0f..5e9a07be82c 100644 --- a/src/network/socket/qlocalsocket_p.h +++ b/src/network/socket/qlocalsocket_p.h @@ -124,8 +124,7 @@ public: ~QLocalSocketPrivate(); void destroyPipeHandles(); void setErrorString(const QString &function); - void startNextWrite(); - void _q_bytesWritten(qint64 bytes); + void _q_canWrite(); void _q_pipeClosed(); void _q_winError(ulong windowsError, const QString &function); HANDLE handle; diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 4507c988351..99c8c77ed86 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -212,11 +212,12 @@ qint64 QLocalSocket::writeData(const char *data, qint64 len) memcpy(dest, data, len); if (!d->pipeWriter) { d->pipeWriter = new QWindowsPipeWriter(d->handle, this); - QObjectPrivate::connect(d->pipeWriter, &QWindowsPipeWriter::bytesWritten, - d, &QLocalSocketPrivate::_q_bytesWritten); + connect(d->pipeWriter, &QWindowsPipeWriter::bytesWritten, + this, &QLocalSocket::bytesWritten); + QObjectPrivate::connect(d->pipeWriter, &QWindowsPipeWriter::canWrite, + d, &QLocalSocketPrivate::_q_canWrite); } - if (!d->pipeWriter->isWriteOperationActive()) - d->startNextWrite(); + d->_q_canWrite(); return len; } @@ -269,7 +270,7 @@ qint64 QLocalSocket::bytesAvailable() const qint64 QLocalSocket::bytesToWrite() const { Q_D(const QLocalSocket); - return d->writeBuffer.size(); + return d->writeBuffer.size() + (d->pipeWriter ? d->pipeWriter->bytesToWrite() : 0); } bool QLocalSocket::canReadLine() const @@ -352,7 +353,7 @@ bool QLocalSocket::setSocketDescriptor(qintptr socketDescriptor, return true; } -void QLocalSocketPrivate::startNextWrite() +void QLocalSocketPrivate::_q_canWrite() { Q_Q(QLocalSocket); if (writeBuffer.isEmpty()) { @@ -360,18 +361,11 @@ void QLocalSocketPrivate::startNextWrite() q->close(); } else { Q_ASSERT(pipeWriter); - pipeWriter->write(writeBuffer.readPointer(), writeBuffer.nextDataBlockSize()); + if (!pipeWriter->isWriteOperationActive()) + pipeWriter->write(writeBuffer.read()); } } -void QLocalSocketPrivate::_q_bytesWritten(qint64 bytes) -{ - Q_Q(QLocalSocket); - writeBuffer.free(bytes); - startNextWrite(); - emit q->bytesWritten(bytes); -} - qintptr QLocalSocket::socketDescriptor() const { Q_D(const QLocalSocket); diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp index 99f40ca2152..6e55b15a18c 100644 --- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -78,6 +79,9 @@ private slots: void readBufferOverflow(); + void simpleCommandProtocol1(); + void simpleCommandProtocol2(); + void fullPath(); void hitMaximumConnections_data(); @@ -630,6 +634,110 @@ void tst_QLocalSocket::readBufferOverflow() QCOMPARE(client.bytesAvailable(), 0); } +static qint64 writeCommand(const QVariant &command, QIODevice *device, int commandCounter) +{ + QByteArray block; + QDataStream out(&block, QIODevice::WriteOnly); + out << qint64(0); + out << commandCounter; + out << command; + out.device()->seek(0); + out << qint64(block.size() - sizeof(qint64)); + return device->write(block); +} + +static QVariant readCommand(QIODevice *ioDevice, int *readCommandCounter, bool readSize = true) +{ + QDataStream in(ioDevice); + qint64 blockSize; + int commandCounter; + if (readSize) + in >> blockSize; + in >> commandCounter; + *readCommandCounter = commandCounter; + + QVariant command; + in >> command; + + return command; +} + +void tst_QLocalSocket::simpleCommandProtocol1() +{ + QLocalServer server; + server.listen(QStringLiteral("simpleProtocol")); + + QLocalSocket localSocketWrite; + localSocketWrite.connectToServer(server.serverName()); + QVERIFY(server.waitForNewConnection()); + QLocalSocket *localSocketRead = server.nextPendingConnection(); + QVERIFY(localSocketRead); + + int readCounter = 0; + for (int i = 0; i < 2000; ++i) { + const QVariant command(QRect(readCounter, i, 10, 10)); + const qint64 blockSize = writeCommand(command, &localSocketWrite, i); + while (localSocketWrite.bytesToWrite()) + QVERIFY(localSocketWrite.waitForBytesWritten()); + while (localSocketRead->bytesAvailable() < blockSize) { + QVERIFY(localSocketRead->waitForReadyRead(1000)); + } + const QVariant variant = readCommand(localSocketRead, &readCounter); + QCOMPARE(readCounter, i); + QCOMPARE(variant, command); + } +} + +void tst_QLocalSocket::simpleCommandProtocol2() +{ + QLocalServer server; + server.listen(QStringLiteral("simpleProtocol")); + + QLocalSocket localSocketWrite; + localSocketWrite.connectToServer(server.serverName()); + QVERIFY(server.waitForNewConnection()); + QLocalSocket* localSocketRead = server.nextPendingConnection(); + QVERIFY(localSocketRead); + + int readCounter = 0; + qint64 writtenBlockSize = 0; + qint64 blockSize = 0; + + QObject::connect(localSocketRead, &QLocalSocket::readyRead, [&] { + forever { + if (localSocketRead->bytesAvailable() < sizeof(qint64)) + return; + + if (blockSize == 0) { + QDataStream in(localSocketRead); + in >> blockSize; + } + + if (localSocketRead->bytesAvailable() < blockSize) + return; + + int commandNumber = 0; + const QVariant variant = readCommand(localSocketRead, &commandNumber, false); + QCOMPARE(writtenBlockSize, blockSize); + QCOMPARE(readCounter, commandNumber); + QCOMPARE(variant.userType(), (int)QMetaType::QRect); + + readCounter++; + blockSize = 0; + } + }); + + for (int i = 0; i < 500; ++i) { + const QVariant command(QRect(readCounter, i, 10, 10)); + writtenBlockSize = writeCommand(command, &localSocketWrite, i) - sizeof(qint64); + if (i % 10 == 0) + QTest::qWait(1); + } + + localSocketWrite.abort(); + QVERIFY(localSocketRead->waitForDisconnected(1000)); +} + // QLocalSocket/Server can take a name or path, check that it works as expected void tst_QLocalSocket::fullPath() { From 54d95d09887e9f6394dcc440369959994ff5bad9 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 29 Apr 2016 11:27:11 +0200 Subject: [PATCH 05/43] Fix UB (data race) in Q_GLOBAL_STATIC The store to guard in the inner function's critical section was not synchronized-with the load at the start of the function: T1 T2 guard.load() mutex.lock() guard.load() d = new Type guard.store() guard.load() // use d mutex.unlock() The use of d in T2 does not synchronize with the write to d in T1 -> data race -> UB. Fix by storing with release memory ordering, so that the guard.load() in T2 synchronizes with the guard.store() in T1. Change-Id: I5c1cd1fa097c6397cb0b48b0d8e8012f95978558 Reviewed-by: Thiago Macieira Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/global/qglobalstatic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qglobalstatic.h b/src/corelib/global/qglobalstatic.h index 41fc1516522..22194d8be75 100644 --- a/src/corelib/global/qglobalstatic.h +++ b/src/corelib/global/qglobalstatic.h @@ -110,7 +110,7 @@ QT_BEGIN_NAMESPACE guard.store(QtGlobalStatic::Destroyed); \ } \ } cleanup; \ - guard.store(QtGlobalStatic::Initialized); \ + guard.storeRelease(QtGlobalStatic::Initialized); \ } \ } \ return d; \ From c6d041e7ca3eb7945bf143a5c4fffcb2b2afba75 Mon Sep 17 00:00:00 2001 From: Urs Fleisch Date: Sun, 1 May 2016 14:31:48 +0200 Subject: [PATCH 06/43] xcb: Fix drag and drop to Emacs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unfortunately, the improved patch for QTBUG-45812 fixed things for Chromium, but did no longer work for Emacs. This fixes commit [269fdb] to make it work for both Emacs and Chromium. Task-number: QTBUG-45812 Change-Id: I2fca708503f27679681bc6959de1ad94943a063e Reviewed-by: Dmitry Shachnev Reviewed-by: Błażej Szczygieł Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbdrag.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index f1428d0a963..529f91e1ec0 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -1134,10 +1134,10 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event at = findTransactionByWindow(event->requestor); } - if (at == -1 && event->time == XCB_CURRENT_TIME) { + if (at == -1) { xcb_window_t target = findXdndAwareParent(connection(), event->requestor); if (target) { - if (current_target == target) + if (event->time == XCB_CURRENT_TIME && current_target == target) at = -2; else at = findTransactionByWindow(target); From c09008d27ca1456fb53a3fc9c71d5f88b1081221 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 2 May 2016 11:34:44 +0200 Subject: [PATCH 07/43] QWindowsPipeWriter: Fix developer build with MinGW. Fix signedness in comparion: io\qwindowspipewriter.cpp: In member function 'void QWindowsPipeWriter::notified(DWORD, DWORD)': io\qwindowspipewriter.cpp:134:65: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare] Q_ASSERT(errorCode != ERROR_SUCCESS || numberOfBytesWritten == buffer.size()); Amends change a4d26cf522b966056e47e47a004b7e4d668e3a2d. Task-number: QTBUG-52401 Change-Id: If0c0e2107342408675fa00b93f28c9de339080f6 Reviewed-by: Joerg Bornemann --- src/corelib/io/qwindowspipewriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index 05a4aa484a3..839dc8a19ca 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -131,7 +131,7 @@ void QWindowsPipeWriter::notified(DWORD errorCode, DWORD numberOfBytesWritten) notifiedCalled = true; writeSequenceStarted = false; numberOfBytesToWrite = 0; - Q_ASSERT(errorCode != ERROR_SUCCESS || numberOfBytesWritten == buffer.size()); + Q_ASSERT(errorCode != ERROR_SUCCESS || numberOfBytesWritten == DWORD(buffer.size())); buffer.clear(); switch (errorCode) { From 1c456751b35ded269663d63015b8078bab283b93 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 27 Apr 2016 18:40:56 +0300 Subject: [PATCH 08/43] Fix QFile::copy() on WinRT. Implementation of QFileSystemEngine::copyFile() uses CopyFile2() as if it is CopyFile() function, but CopyFile2() returns HRESULT, not BOOL. So the success should be checked by "SUCCEEDED()" instead of "!= 0". Current implementation does exactly the opposite because S_OK == 0. Change-Id: I0677d54447d22366fb2031e0b928a3d10e24c0ed Reviewed-by: Maurice Kalinowski --- src/corelib/io/qfilesystemengine_win.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index f1a60190943..e55ab0b544a 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -1416,8 +1416,9 @@ bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSyst COPYFILE2_EXTENDED_PARAMETERS copyParams = { sizeof(copyParams), COPY_FILE_FAIL_IF_EXISTS, NULL, NULL, NULL }; - bool ret = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(), - (const wchar_t*)target.nativeFilePath().utf16(), ©Params) != 0; + HRESULT hres = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(), + (const wchar_t*)target.nativeFilePath().utf16(), ©Params); + bool ret = SUCCEEDED(hres); #endif // Q_OS_WINRT if(!ret) error = QSystemError(::GetLastError(), QSystemError::NativeError); From 63169fc893973437696ad49c4e3dfdd28e356f37 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 28 Apr 2016 13:28:51 +0200 Subject: [PATCH 09/43] Fix underline position on Liberation Mono Ensure we don't round a underline position beyond the descent in our eagerness to avoid underlines too close to baseline. Task-number: QTCREATORBUG-15851 Change-Id: I9a29447bbcb938b7e9fb29d52fd392a1340d07c5 Reviewed-by: Konstantin Ritt Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/painting/qpainter.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index baeee4dbfaf..62254213f34 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6251,9 +6251,6 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const painter->setRenderHint(QPainter::Qt4CompatiblePainting, false); const qreal underlineOffset = fe->underlinePosition().toReal(); - // deliberately ceil the offset to avoid the underline coming too close to - // the text above it. - const qreal underlinePos = pos.y() + qCeil(underlineOffset) + 0.5; if (underlineStyle == QTextCharFormat::SpellCheckUnderline) { QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme(); @@ -6278,6 +6275,12 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave); painter->restore(); } else if (underlineStyle != QTextCharFormat::NoUnderline) { + // Deliberately ceil the offset to avoid the underline coming too close to + // the text above it, but limit it to stay within descent. + qreal adjustedUnderlineOffset = std::ceil(underlineOffset) + 0.5; + if (underlineOffset <= fe->descent().toReal()) + adjustedUnderlineOffset = qMin(adjustedUnderlineOffset, fe->descent().toReal() - 0.5); + const qreal underlinePos = pos.y() + adjustedUnderlineOffset; QColor uc = charFormat.underlineColor(); if (uc.isValid()) pen.setColor(uc); From 8badbd5040fd41ad258d90edacb7b28b9a0ef870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 26 Apr 2016 17:38:55 +0200 Subject: [PATCH 10/43] iOS: Report correct physicalSize and physicalDotsPerInch for iPhone6+ On iPhone 6(s) Plus devices, or when display zoom is enabled in an iPhone 6, the render buffer is scaled before being output on the physical display. We have to take this into account when computing the physical size. Task-number: QTBUG-50941 Change-Id: I318f3a866d039fccf0ba08f381fc9d8bcd676acd Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.h | 2 +- src/plugins/platforms/ios/qiosscreen.mm | 27 +++++++++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index f31be9756ca..d6627c78cbd 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -73,7 +73,7 @@ private: QRect m_geometry; QRect m_availableGeometry; int m_depth; - uint m_pixelDensity; + uint m_physicalDpi; QSizeF m_physicalSize; QIOSOrientationListener *m_orientationListener; }; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 5cb06d591dd..d9ec7008d39 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -180,18 +180,18 @@ QIOSScreen::QIOSScreen(UIScreen *screen) if (deviceIdentifier.contains(QRegularExpression("^iPhone(7,1|8,2)$"))) { // iPhone 6 Plus or iPhone 6S Plus - m_pixelDensity = 401; + m_physicalDpi = 401; } else if (deviceIdentifier.contains(QRegularExpression("^iPad(1,1|2,[1-4]|3,[1-6]|4,[1-3]|5,[3-4]|6,[7-8])$"))) { // All iPads except the iPad Mini series - m_pixelDensity = 132 * devicePixelRatio(); + m_physicalDpi = 132 * devicePixelRatio(); } else { // All non-Plus iPhones, and iPad Minis - m_pixelDensity = 163 * devicePixelRatio(); + m_physicalDpi = 163 * devicePixelRatio(); } } else { // External display, hard to say m_depth = 24; - m_pixelDensity = 96; + m_physicalDpi = 96; } for (UIWindow *existingWindow in [[UIApplication sharedApplication] windows]) { @@ -253,8 +253,23 @@ void QIOSScreen::updateProperties() } if (m_geometry != previousGeometry) { - const qreal millimetersPerInch = 25.4; - m_physicalSize = QSizeF(m_geometry.size() * devicePixelRatio()) / m_pixelDensity * millimetersPerInch; + QRectF physicalGeometry; + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_8_0) { + // We can't use the primaryOrientation of screen(), as we haven't reported the new geometry yet + Qt::ScreenOrientation primaryOrientation = m_geometry.width() >= m_geometry.height() ? + Qt::LandscapeOrientation : Qt::PortraitOrientation; + + // On iPhone 6+ devices, or when display zoom is enabled, the render buffer is scaled + // before being output on the physical display. We have to take this into account when + // computing the physical size. Note that unlike the native bounds, the physical size + // follows the primary orientation of the screen. + physicalGeometry = mapBetween(nativeOrientation(), primaryOrientation, fromCGRect(m_uiScreen.nativeBounds).toRect()); + } else { + physicalGeometry = QRectF(0, 0, m_geometry.width() * devicePixelRatio(), m_geometry.height() * devicePixelRatio()); + } + + static const qreal millimetersPerInch = 25.4; + m_physicalSize = physicalGeometry.size() / m_physicalDpi * millimetersPerInch; } // At construction time, we don't yet have an associated QScreen, but we still want From 9af2cccc597fd094de34c83d742803c5f4c0a8d6 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Mon, 2 May 2016 17:54:50 +0300 Subject: [PATCH 11/43] QNativeSocketEngine: fix build in debug mode under Windows Change-Id: Id9b42f3d40b82ae6a8d581b0fbf6fd0b2ae589aa Reviewed-by: Timur Pocheptsov --- src/network/socket/qnativesocketengine_win.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 7b6be9ebf99..770bae7bf35 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -1177,7 +1177,7 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const #endif #if defined (QNATIVESOCKETENGINE_DEBUG) - qDebug("QNativeSocketEnginePrivate::nativePendingDatagramSize() == %li", ret); + qDebug("QNativeSocketEnginePrivate::nativePendingDatagramSize() == %lli", ret); #endif return ret; @@ -1283,10 +1283,11 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL } #if defined (QNATIVESOCKETENGINE_DEBUG) - qDebug("QNativeSocketEnginePrivate::nativeReceiveDatagram(%p \"%s\", %li, %s, %i) == %li", + bool printSender = (ret != -1 && (options & QNativeSocketEngine::WantDatagramSender) != 0); + qDebug("QNativeSocketEnginePrivate::nativeReceiveDatagram(%p \"%s\", %lli, %s, %i) == %lli", data, qt_prettyDebug(data, qMin(ret, 16), ret).data(), maxLength, - address ? address->toString().toLatin1().constData() : "(nil)", - port ? *port : 0, ret); + printSender ? header->senderAddress.toString().toLatin1().constData() : "(unknown)", + printSender ? header->senderPort : 0, ret); #endif return ret; @@ -1398,9 +1399,10 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l } #if defined (QNATIVESOCKETENGINE_DEBUG) - qDebug("QNativeSocketEnginePrivate::nativeSendDatagram(%p \"%s\", %li, \"%s\", %i) == %li", data, - qt_prettyDebug(data, qMin(len, 16), len).data(), 0, address.toString().toLatin1().constData(), - port, ret); + qDebug("QNativeSocketEnginePrivate::nativeSendDatagram(%p \"%s\", %lli, \"%s\", %i) == %lli", data, + qt_prettyDebug(data, qMin(len, 16), len).data(), len, + header.destinationAddress.toString().toLatin1().constData(), + header.destinationPort, ret); #endif return ret; From be6a92ec0920491a68e747b48154ad8712d97f4b Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 22 Apr 2016 20:20:47 +0200 Subject: [PATCH 12/43] remove redundant OTHER_FILES assignments newer versions of qt creator understand QMAKE_EXTRA_COMPILERS and INSTALLS, so there is no need to list the files twice. Change-Id: Iccf3cc3248daf3422b8c366c2eb2d2f46c5f08d1 Reviewed-by: Joerg Bornemann --- mkspecs/features/qml_module.prf | 3 --- src/plugins/bearer/android/jar/jar.pri | 2 -- tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro | 1 - tests/manual/textrendering/glyphshaping/glyphshaping.pro | 1 - 4 files changed, 7 deletions(-) diff --git a/mkspecs/features/qml_module.prf b/mkspecs/features/qml_module.prf index 9e136a49f23..b09d42a0a48 100644 --- a/mkspecs/features/qml_module.prf +++ b/mkspecs/features/qml_module.prf @@ -17,9 +17,6 @@ fq_qml_files = $$_PRO_FILE_PWD_/qmldir for(qmlf, QML_FILES): fq_qml_files += $$absolute_path($$qmlf, $$_PRO_FILE_PWD_) -# Only for Qt Creator's project view -OTHER_FILES += $$fq_qml_files - qml1_target: \ instbase = $$[QT_INSTALL_IMPORTS] else: \ diff --git a/src/plugins/bearer/android/jar/jar.pri b/src/plugins/bearer/android/jar/jar.pri index 6d9aac3bb3b..e43dbf0711b 100644 --- a/src/plugins/bearer/android/jar/jar.pri +++ b/src/plugins/bearer/android/jar/jar.pri @@ -9,5 +9,3 @@ JAVASOURCES += $$PWD/src/org/qtproject/qt5/android/bearer/QtNetworkReceiver.java # install target.path = $$[QT_INSTALL_PREFIX]/jar INSTALLS += target - -OTHER_FILES += $$JAVASOURCES diff --git a/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro b/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro index a311173c0e7..f03ac49c5d4 100644 --- a/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro +++ b/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro @@ -5,7 +5,6 @@ CONFIG += testcase QT = core core-private testlib SOURCES += tst_qloggingregistry.cpp -OTHER_FILES += qtlogging.ini TESTDATA += qtlogging.ini android:!android-no-sdk: { diff --git a/tests/manual/textrendering/glyphshaping/glyphshaping.pro b/tests/manual/textrendering/glyphshaping/glyphshaping.pro index 5dc8542e863..4fef879c9cb 100644 --- a/tests/manual/textrendering/glyphshaping/glyphshaping.pro +++ b/tests/manual/textrendering/glyphshaping/glyphshaping.pro @@ -1,6 +1,5 @@ QT += widgets SOURCES = main.cpp -OTHER_FILES = glyphshaping_data.xml glyphshaping_data.path = . glyphshaping_data.files = $$PWD/glyphshaping_data.xml DEPLOYMENT += glyphshaping_data From ce044ce3482b5abc85ecaf42842df1d4a5ad7806 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 29 Apr 2016 11:38:08 +0200 Subject: [PATCH 13/43] ensure that QMAKE_FILE_{IN,OUT}_BASE are quoted it's beyond me why they shouldn't be. Change-Id: I2493469636e4f196bfeb2eb00a691aeae0f1881d Reviewed-by: Joerg Bornemann --- qmake/generators/makefile.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 5ec4cfb7efe..66d0b91d619 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1611,7 +1611,7 @@ MakefileGenerator::replaceExtraCompilerVariables( const ProKey funcname = var.mid(19).toKey(); val += project->expand(funcname, QList() << ProStringList(in)); } else if(var == QLatin1String("QMAKE_FILE_BASE") || var == QLatin1String("QMAKE_FILE_IN_BASE")) { - //filePath = true; + filePath = true; for(int i = 0; i < in.size(); ++i) { QFileInfo fi(fileInfo(Option::normalizePath(in.at(i)))); QString base = fi.completeBaseName(); @@ -1653,7 +1653,7 @@ MakefileGenerator::replaceExtraCompilerVariables( for(int i = 0; i < out.size(); ++i) val += fileInfo(Option::normalizePath(out.at(i))).filePath(); } else if(var == QLatin1String("QMAKE_FILE_OUT_BASE")) { - //filePath = true; + filePath = true; for(int i = 0; i < out.size(); ++i) { QFileInfo fi(fileInfo(Option::normalizePath(out.at(i)))); QString base = fi.completeBaseName(); From 49f92f9ab75f5fcc086543d9dbcc025c37677715 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 29 Apr 2016 11:34:14 +0200 Subject: [PATCH 14/43] add some missing filename expandos to extra compilers - QMAKE_FILE_IN_EXT as an alias for QMAKE_FILE_EXT, for consistency with QMAKE_FILE_IN_BASE - QMAKE_FILE_IN_NAME to make pairing _EXT/_BASE to get a full name unnecessary (finally ...), and make use of it - QMAKE_FILE_OUT_PATH, because i'll need it Change-Id: I3d91ddb84f9cce52a665d562da11d165c92550c8 Reviewed-by: Joerg Bornemann --- mkspecs/features/file_copies.prf | 2 +- qmake/generators/makefile.cpp | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/file_copies.prf b/mkspecs/features/file_copies.prf index f679129e030..04a02258d56 100644 --- a/mkspecs/features/file_copies.prf +++ b/mkspecs/features/file_copies.prf @@ -24,7 +24,7 @@ for (cp, COPIES) { isEmpty(path): error("COPY $cp defines no .path") base = $$eval($${cp}.base) isEmpty(base) { - $${pfx}.output = $$path/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT} + $${pfx}.output = $$path/${QMAKE_FILE_IN_NAME} } else: isEqual(base, $$_PRO_FILE_PWD_) { $${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripProPwd} } else { diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 66d0b91d619..a5964746691 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1619,7 +1619,7 @@ MakefileGenerator::replaceExtraCompilerVariables( base = fi.fileName(); val += base; } - } else if(var == QLatin1String("QMAKE_FILE_EXT")) { + } else if (var == QLatin1String("QMAKE_FILE_EXT") || var == QLatin1String("QMAKE_FILE_IN_EXT")) { filePath = true; for(int i = 0; i < in.size(); ++i) { QFileInfo fi(fileInfo(Option::normalizePath(in.at(i)))); @@ -1632,6 +1632,10 @@ MakefileGenerator::replaceExtraCompilerVariables( ext = fi.fileName().remove(0, baseLen); val += ext; } + } else if (var == QLatin1String("QMAKE_FILE_IN_NAME")) { + filePath = true; + for (int i = 0; i < in.size(); ++i) + val += fileInfo(Option::normalizePath(in.at(i))).fileName(); } else if(var == QLatin1String("QMAKE_FILE_PATH") || var == QLatin1String("QMAKE_FILE_IN_PATH")) { filePath = true; for(int i = 0; i < in.size(); ++i) @@ -1648,6 +1652,10 @@ MakefileGenerator::replaceExtraCompilerVariables( filePath = true; const ProKey funcname = var.mid(20).toKey(); val += project->expand(funcname, QList() << ProStringList(out)); + } else if (var == QLatin1String("QMAKE_FILE_OUT_PATH")) { + filePath = true; + for (int i = 0; i < out.size(); ++i) + val += fileInfo(Option::normalizePath(out.at(i))).path(); } else if(var == QLatin1String("QMAKE_FILE_OUT")) { filePath = true; for(int i = 0; i < out.size(); ++i) From 8f0bf2d3d258acfae91e7dda2d1e7ad29b950c9b Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 29 Apr 2016 11:36:15 +0200 Subject: [PATCH 15/43] support directories in COPIES this makes it fully consistent with INSTALLS. note that this also removes the file name from the target path when copying files, also for consistency. Change-Id: I69042c9aa1e2cc81f8ff982343ba25688a04abfd Reviewed-by: Joerg Bornemann --- mkspecs/features/file_copies.prf | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/mkspecs/features/file_copies.prf b/mkspecs/features/file_copies.prf index 04a02258d56..6df294212c0 100644 --- a/mkspecs/features/file_copies.prf +++ b/mkspecs/features/file_copies.prf @@ -18,10 +18,21 @@ defineReplace(qtStripProPwd) { for (cp, COPIES) { isEmpty($${cp}.files): next() pfx = copy_$${cp} - for (f, $${cp}.files): \ - $${pfx}.files += $$absolute_path($$f, $$_PRO_FILE_PWD_) + notdir = false + dir = false + for (f, $${cp}.files) { + fil = $$absolute_path($$f, $$_PRO_FILE_PWD_) + tfiles = $$files($$fil/*) + isEmpty(tfiles): \ + notdir = true + else: \ + dir = true + $${pfx}.files += $$fil + } + $$dir:$$notdir: \ + error("COPIES entry $$cp lists both files and directories.") path = $$eval($${cp}.path) - isEmpty(path): error("COPY $cp defines no .path") + isEmpty(path): error("COPIES entry $$cp defines no .path") base = $$eval($${cp}.base) isEmpty(base) { $${pfx}.output = $$path/${QMAKE_FILE_IN_NAME} @@ -34,7 +45,12 @@ for (cp, COPIES) { $${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripSrcDir_$$cp} } $${pfx}.input = $${pfx}.files - $${pfx}.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} + !$$dir: \ + $${pfx}.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT_PATH} + else: !copy_dir_files: \ + $${pfx}.commands = $$QMAKE_COPY_DIR ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT_PATH} + else: \ + $${pfx}.commands = $$QMAKE_COPY_DIR ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} $${pfx}.name = COPY ${QMAKE_FILE_IN} $${pfx}.CONFIG = no_link no_clean target_predeps QMAKE_EXTRA_COMPILERS += $${pfx} From 22a7edd816b417daf43e3b4c4f0257fbc3ad7921 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 7 Apr 2016 14:18:21 +0200 Subject: [PATCH 16/43] tst_QTcpSocket, tst_QUdpSocket: Improve diagnostics. Add more error messages on failures. Task-number: QTBUG-25367 Task-number: QTBUG-25368 Change-Id: I064143a058b7b98d9d5eecab8b5da49f5307e1eb Reviewed-by: Edward Welbourne Reviewed-by: Richard J. Moore --- tests/auto/network-settings.h | 20 +++++++++- .../socket/qtcpsocket/tst_qtcpsocket.cpp | 6 ++- .../socket/qudpsocket/tst_qudpsocket.cpp | 40 +++++++++---------- .../socket/qudpsocket/udpServer/main.cpp | 30 ++++++++++---- 4 files changed, 65 insertions(+), 31 deletions(-) diff --git a/tests/auto/network-settings.h b/tests/auto/network-settings.h index a90ea622776..f4ec460709a 100644 --- a/tests/auto/network-settings.h +++ b/tests/auto/network-settings.h @@ -34,6 +34,8 @@ #include #ifdef QT_NETWORK_LIB #include +#include +#include #endif #ifdef Q_OS_UNIX @@ -139,5 +141,21 @@ public: } return true; } -#endif + + // Helper function for usage with QVERIFY2 on sockets. + static QByteArray msgSocketError(const QAbstractSocket &s) + { + QString result; + QDebug debug(&result); + debug.nospace(); + debug.noquote(); + if (!s.localAddress().isNull()) + debug << "local=" << s.localAddress().toString() << ':' << s.localPort(); + if (!s.peerAddress().isNull()) + debug << ", peer=" << s.peerAddress().toString() << ':' << s.peerPort(); + debug << ", type=" << s.socketType() << ", state=" << s.state() + << ", error=" << s.error() << ": " << s.errorString(); + return result.toLocal8Bit(); + } +#endif // QT_NETWORK_LIB }; diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index cde453c1917..bdfb7d2fb8f 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -675,8 +675,10 @@ void tst_QTcpSocket::bindThenResolveHost() dummySocket.close(); - socket->connectToHost(hostName, 80); - QVERIFY2(socket->waitForConnected(), "Network timeout"); + const quint16 port = 80; + socket->connectToHost(hostName, port); + QVERIFY2(socket->waitForConnected(), (hostName.toLocal8Bit() + ": " + QByteArray::number(port) + ' ' + + QtNetworkSettings::msgSocketError(*socket)).constData()); QCOMPARE(socket->localPort(), boundPort); QCOMPARE(socket->socketDescriptor(), fd); diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 0ee32555028..7ab8f6d3ccb 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -265,7 +266,7 @@ void tst_QUdpSocket::unconnectedServerAndClientTest() char buf[1024]; QHostAddress host; quint16 port; - QVERIFY(serverSocket.waitForReadyRead(5000)); + QVERIFY2(serverSocket.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(serverSocket).constData()); QCOMPARE(int(serverSocket.readDatagram(buf, sizeof(buf), &host, &port)), int(strlen(message[i]))); buf[strlen(message[i])] = '\0'; @@ -397,8 +398,8 @@ void tst_QUdpSocket::loop() QCOMPARE(paul.writeDatagram(paulMessage.data(), paulMessage.length(), peterAddress, peter.localPort()), qint64(paulMessage.length())); - QVERIFY(peter.waitForReadyRead(9000)); - QVERIFY(paul.waitForReadyRead(9000)); + QVERIFY2(peter.waitForReadyRead(9000), QtNetworkSettings::msgSocketError(peter).constData()); + QVERIFY2(paul.waitForReadyRead(9000), QtNetworkSettings::msgSocketError(paul).constData()); char peterBuffer[16*1024]; char paulBuffer[16*1024]; if (success) { @@ -454,8 +455,8 @@ void tst_QUdpSocket::ipv6Loop() char peterBuffer[16*1024]; char paulBuffer[16*1024]; #if !defined(Q_OS_WINCE) - QVERIFY(peter.waitForReadyRead(5000)); - QVERIFY(paul.waitForReadyRead(5000)); + QVERIFY2(peter.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(peter).constData()); + QVERIFY2(paul.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(paul).constData()); #else QVERIFY(peter.waitForReadyRead(15000)); QVERIFY(paul.waitForReadyRead(15000)); @@ -490,7 +491,7 @@ void tst_QUdpSocket::dualStack() QByteArray buffer; //test v4 -> dual QCOMPARE((int)v4Sock.writeDatagram(v4Data.constData(), v4Data.length(), QHostAddress(QHostAddress::LocalHost), dualSock.localPort()), v4Data.length()); - QVERIFY(dualSock.waitForReadyRead(5000)); + QVERIFY2(dualSock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(dualSock).constData()); buffer.reserve(100); qint64 size = dualSock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, v4Data.length()); @@ -504,7 +505,7 @@ void tst_QUdpSocket::dualStack() //test v6 -> dual QCOMPARE((int)v6Sock.writeDatagram(v6Data.constData(), v6Data.length(), QHostAddress(QHostAddress::LocalHostIPv6), dualSock.localPort()), v6Data.length()); - QVERIFY(dualSock.waitForReadyRead(5000)); + QVERIFY2(dualSock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(dualSock).constData()); buffer.reserve(100); size = dualSock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, v6Data.length()); @@ -513,7 +514,7 @@ void tst_QUdpSocket::dualStack() //test dual -> v6 QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHostIPv6), v6Sock.localPort()), dualData.length()); - QVERIFY(v6Sock.waitForReadyRead(5000)); + QVERIFY2(v6Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v6Sock).constData()); buffer.reserve(100); size = v6Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -523,7 +524,7 @@ void tst_QUdpSocket::dualStack() //test dual -> v4 QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHost), v4Sock.localPort()), dualData.length()); - QVERIFY(v4Sock.waitForReadyRead(5000)); + QVERIFY2(v4Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v4Sock).constData()); buffer.reserve(100); size = v4Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -555,7 +556,7 @@ void tst_QUdpSocket::dualStackAutoBinding() QUdpSocket dualSock; QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHost), v4Sock.localPort()), dualData.length()); - QVERIFY(v4Sock.waitForReadyRead(5000)); + QVERIFY2(v4Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v4Sock).constData()); buffer.reserve(100); size = v4Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -563,7 +564,7 @@ void tst_QUdpSocket::dualStackAutoBinding() QCOMPARE(buffer, dualData); QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHostIPv6), v6Sock.localPort()), dualData.length()); - QVERIFY(v6Sock.waitForReadyRead(5000)); + QVERIFY2(v6Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v6Sock).constData()); buffer.reserve(100); size = v6Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -576,7 +577,7 @@ void tst_QUdpSocket::dualStackAutoBinding() QUdpSocket dualSock; QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHostIPv6), v6Sock.localPort()), dualData.length()); - QVERIFY(v6Sock.waitForReadyRead(5000)); + QVERIFY2(v6Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v6Sock).constData()); buffer.reserve(100); size = v6Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -584,7 +585,7 @@ void tst_QUdpSocket::dualStackAutoBinding() QCOMPARE(buffer, dualData); QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHost), v4Sock.localPort()), dualData.length()); - QVERIFY(v4Sock.waitForReadyRead(5000)); + QVERIFY2(v4Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v4Sock).constData()); buffer.reserve(100); size = v4Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -689,7 +690,7 @@ void tst_QUdpSocket::pendingDatagramSize() QVERIFY(client.writeDatagram("3 messages", 10, serverAddress, server.localPort()) == 10); char c = 0; - QVERIFY(server.waitForReadyRead()); + QVERIFY2(server.waitForReadyRead(), QtNetworkSettings::msgSocketError(server).constData()); if (server.hasPendingDatagrams()) { #if defined Q_OS_HPUX && defined __ia64 QEXPECT_FAIL("", "HP-UX 11i v2 can't determine the datagram size correctly.", Abort); @@ -1101,7 +1102,7 @@ void tst_QUdpSocket::zeroLengthDatagram() #endif QCOMPARE(sender.writeDatagram(QByteArray(), QHostAddress::LocalHost, receiver.localPort()), qint64(0)); - QVERIFY(receiver.waitForReadyRead(1000)); + QVERIFY2(receiver.waitForReadyRead(1000), QtNetworkSettings::msgSocketError(receiver).constData()); QVERIFY(receiver.hasPendingDatagrams()); char buf; @@ -1379,8 +1380,7 @@ void tst_QUdpSocket::multicast() int(datagram.size())); } - QVERIFY2(receiver.waitForReadyRead(), - qPrintable(receiver.errorString())); + QVERIFY2(receiver.waitForReadyRead(), QtNetworkSettings::msgSocketError(receiver).constData()); QVERIFY(receiver.hasPendingDatagrams()); QList receivedDatagrams; while (receiver.hasPendingDatagrams()) { @@ -1446,7 +1446,7 @@ void tst_QUdpSocket::echo() qDebug() << "packets in" << successes << "out" << i; QTest::qWait(50); //choke to avoid triggering flood/DDoS protections on echo service } - QVERIFY(successes >= 9); + QVERIFY2(successes >= 9, QByteArray::number(successes).constData()); } void tst_QUdpSocket::linkLocalIPv6() @@ -1567,7 +1567,7 @@ void tst_QUdpSocket::linkLocalIPv4() QByteArray receiveBuffer("xxxxx"); foreach (QUdpSocket *s, sockets) { QVERIFY(s->writeDatagram(testData, s->localAddress(), neutral.localPort())); - QVERIFY(neutral.waitForReadyRead(10000)); + QVERIFY2(neutral.waitForReadyRead(10000), QtNetworkSettings::msgSocketError(neutral).constData()); QHostAddress from; quint16 fromPort; QCOMPARE((int)neutral.readDatagram(receiveBuffer.data(), receiveBuffer.length(), &from, &fromPort), testData.length()); @@ -1576,7 +1576,7 @@ void tst_QUdpSocket::linkLocalIPv4() QCOMPARE(receiveBuffer, testData); QVERIFY(neutral.writeDatagram(testData, s->localAddress(), s->localPort())); - QVERIFY(s->waitForReadyRead(10000)); + QVERIFY2(s->waitForReadyRead(10000), QtNetworkSettings::msgSocketError(*s).constData()); QCOMPARE((int)s->readDatagram(receiveBuffer.data(), receiveBuffer.length(), &from, &fromPort), testData.length()); QCOMPARE(receiveBuffer, testData); diff --git a/tests/auto/network/socket/qudpsocket/udpServer/main.cpp b/tests/auto/network/socket/qudpsocket/udpServer/main.cpp index 2562e58862d..f393c263291 100644 --- a/tests/auto/network/socket/qudpsocket/udpServer/main.cpp +++ b/tests/auto/network/socket/qudpsocket/udpServer/main.cpp @@ -36,18 +36,21 @@ class Server : public QObject { Q_OBJECT public: - Server(int port) + + Server() { connect(&serverSocket, &QIODevice::readyRead, this, &Server::sendEcho); } + + bool bind(quint16 port) { - connect(&serverSocket, SIGNAL(readyRead()), - this, SLOT(sendEcho())); - if (serverSocket.bind(QHostAddress::Any, port, - QUdpSocket::ReuseAddressHint - | QUdpSocket::ShareAddress)) { + const bool result = serverSocket.bind(QHostAddress::Any, port, + QUdpSocket::ReuseAddressHint + | QUdpSocket::ShareAddress); + if (result) { printf("OK\n"); } else { - printf("FAILED\n"); + printf("FAILED: %s\n", qPrintable(serverSocket.errorString())); } fflush(stdout); + return result; } private slots: @@ -73,8 +76,19 @@ private: int main(int argc, char **argv) { QCoreApplication app(argc, argv); + QStringList arguments = QCoreApplication::arguments(); + arguments.pop_front(); + quint16 port = 0; + if (!arguments.isEmpty()) + port = arguments.constFirst().toUShort(); + if (!port) { + printf("Specify port number\n"); + return -1; + } - Server server(app.arguments().at(1).toInt()); + Server server; + if (!server.bind(port)) + return -2; return app.exec(); } From fecaa6aae83a3ffa8f1fd41c5aa8275a1bfa7c9b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 27 Apr 2016 23:44:57 -0700 Subject: [PATCH 17/43] Workaround Windows DLL unload issue with threads running We don't know why it happens, so let's apply a workaround. See the comment for more details. Task-number: QTBUG-53031 Change-Id: Ifea6e497f11a461db432ffff144972e892fbbda5 Reviewed-by: Roland Winklmeier Reviewed-by: Friedemann Kleint Reviewed-by: Maurice Kalinowski Reviewed-by: Thiago Macieira --- src/dbus/qdbusconnection.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index 34b3da7df38..7cdacc12849 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -62,6 +62,10 @@ QT_BEGIN_NAMESPACE +#ifdef Q_OS_WIN +static void preventDllUnload(); +#endif + Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager) // can be replaced with a lambda in Qt 5.7 @@ -150,6 +154,10 @@ QDBusConnectionManager::QDBusConnectionManager() this, &QDBusConnectionManager::createServer, Qt::BlockingQueuedConnection); moveToThread(this); // ugly, don't do this in other projects +#ifdef Q_OS_WIN + // prevent the library from being unloaded on Windows. See comments in the function. + preventDllUnload(); +#endif defaultBuses[0] = defaultBuses[1] = Q_NULLPTR; start(); } @@ -1275,4 +1283,31 @@ QT_END_NAMESPACE #include "qdbusconnection.moc" +#ifdef Q_OS_WIN +# include + +QT_BEGIN_NAMESPACE +static void preventDllUnload() +{ + // Thread termination is really wacky on Windows. For some reason we don't + // understand, exiting from the thread may try to unload the DLL. Since the + // QDBusConnectionManager thread runs until the DLL is unloaded, we've got + // a deadlock: the main thread is waiting for the manager thread to exit, + // but the manager thread is attempting to acquire a lock to unload the DLL. + // + // We work around the issue by preventing the unload from happening in the + // first place. + // + // For this trick, see + // https://blogs.msdn.microsoft.com/oldnewthing/20131105-00/?p=2733 + + static HMODULE self; + GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_PIN, + reinterpret_cast(&self), // any address in this DLL + &self); +} +QT_END_NAMESPACE +#endif + #endif // QT_NO_DBUS From cb320925b9b4c33ffbdac73597bf78db842109c9 Mon Sep 17 00:00:00 2001 From: James McDonnell Date: Fri, 18 Mar 2016 11:56:43 -0400 Subject: [PATCH 18/43] Change some QNX defaults Make REDUCE_EXPORTS the default for QNX. This is what the Linux builds use. The Windows builds should too. Turn on ICU detection for QNX. QNX has ICU. Task-number: QTBUG-52578 Change-Id: Ie65c6ff03c4eecf361727b3b6026338f686d9749 Reviewed-by: Dan Cape Reviewed-by: Oswald Buddenhagen --- tools/configure/configureapp.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 6f1e2b7d2dd..3be0ea2b7c3 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -1742,6 +1742,7 @@ void Configure::applySpecSpecifics() dictionary["DECORATIONS"] = "default windows styled"; } else if ((platform() == QNX) || (platform() == BLACKBERRY)) { + dictionary[ "REDUCE_EXPORTS" ] = "yes"; dictionary["STACK_PROTECTOR_STRONG"] = "auto"; dictionary["SLOG2"] = "auto"; dictionary["QNX_IMF"] = "auto"; @@ -1751,6 +1752,7 @@ void Configure::applySpecSpecifics() dictionary[ "ANGLE" ] = "no"; dictionary[ "DYNAMICGL" ] = "no"; dictionary[ "FONT_CONFIG" ] = "auto"; + dictionary[ "ICU" ] = "auto"; } else if (platform() == ANDROID) { dictionary[ "REDUCE_EXPORTS" ] = "yes"; dictionary[ "BUILD" ] = "release"; From 6efa3215a2724415ec7c11e3631594ada1b722b0 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 15 Apr 2016 16:51:04 +0200 Subject: [PATCH 19/43] QOpenGLCustomShaderStage - fix a memory leak Coverity found a memory leak - CID-10995. Fix a dtor + make copy constructor / assignment operator private (Q_DISABLE_COPY). Change-Id: I4f046d075b60fbfb69f350e4a4d8b07ea1643914 Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopenglcustomshaderstage.cpp | 1 + src/gui/opengl/qopenglcustomshaderstage_p.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/gui/opengl/qopenglcustomshaderstage.cpp b/src/gui/opengl/qopenglcustomshaderstage.cpp index e0d131e64dc..e5504e6195e 100644 --- a/src/gui/opengl/qopenglcustomshaderstage.cpp +++ b/src/gui/opengl/qopenglcustomshaderstage.cpp @@ -63,6 +63,7 @@ QOpenGLCustomShaderStage::~QOpenGLCustomShaderStage() d->m_manager->removeCustomStage(); d->m_manager->sharedShaders->cleanupCustomStage(this); } + delete d_ptr; } void QOpenGLCustomShaderStage::setUniformsDirty() diff --git a/src/gui/opengl/qopenglcustomshaderstage_p.h b/src/gui/opengl/qopenglcustomshaderstage_p.h index 78c414d3169..9b3c9fbce10 100644 --- a/src/gui/opengl/qopenglcustomshaderstage_p.h +++ b/src/gui/opengl/qopenglcustomshaderstage_p.h @@ -46,6 +46,7 @@ // #include +#include QT_BEGIN_NAMESPACE @@ -72,6 +73,8 @@ protected: private: QOpenGLCustomShaderStagePrivate* d_ptr; + + Q_DISABLE_COPY(QOpenGLCustomShaderStage) }; From e34ebe632825433d591165db737f732f741bbd9f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 Apr 2016 20:02:20 +0200 Subject: [PATCH 20/43] automate the installation of some more example source files Change-Id: I61f9f4882c5a7743817059824250958f5ce4a603 Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_example_installs.prf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mkspecs/features/qt_example_installs.prf b/mkspecs/features/qt_example_installs.prf index a6449049813..ebf68a8a217 100644 --- a/mkspecs/features/qt_example_installs.prf +++ b/mkspecs/features/qt_example_installs.prf @@ -47,8 +47,13 @@ probase = $$relative_path($$_PRO_FILE_PWD_, $$dirname(_QMAKE_CONF_)/examples) sourcefiles += $$resrc } } + sourcefiles += \ + $$ANDROID_PACKAGE_SOURCE_DIR \ + $$QMAKE_INFO_PLIST \ + $$DISTFILES extras = \ $$_PRO_FILE_PWD_/README \ + $$_PRO_FILE_PWD_/README.TXT \ $$files($$_PRO_FILE_PWD_/*.pri) \ $$replace(_PRO_FILE_, \\.pro$, .qmlproject) \ $$replace(_PRO_FILE_, \\.pro$, .json) \ From 5bbbea4c83149d6920cff2991fc2458c49a1004e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 26 Apr 2016 14:43:01 +0200 Subject: [PATCH 21/43] normalize structure of plugandpaint example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit as in other examples which come with plugins, use an additional hierarchy level which contains the app and plugin subdirs. Change-Id: I2487755967aa3474c337c8c8af10be49627b63d0 Reviewed-by: Topi Reiniö --- .gitignore | 1 - examples/widgets/doc/src/plugandpaint.qdoc | 120 +++++++++--------- .../widgets/tools/plugandpaint/app/app.pro | 26 ++++ .../tools/plugandpaint/{ => app}/interfaces.h | 0 .../tools/plugandpaint/{ => app}/main.cpp | 0 .../plugandpaint/{ => app}/mainwindow.cpp | 0 .../tools/plugandpaint/{ => app}/mainwindow.h | 0 .../plugandpaint/{ => app}/paintarea.cpp | 0 .../tools/plugandpaint/{ => app}/paintarea.h | 0 .../plugandpaint/{ => app}/plugindialog.cpp | 0 .../plugandpaint/{ => app}/plugindialog.h | 0 .../tools/plugandpaint/plugandpaint.pro | 25 +--- .../plugins}/basictools/basictools.json | 0 .../plugins}/basictools/basictools.pro | 4 +- .../plugins}/basictools/basictoolsplugin.cpp | 0 .../plugins}/basictools/basictoolsplugin.h | 6 +- .../plugins}/extrafilters/extrafilters.json | 0 .../plugins}/extrafilters/extrafilters.pro | 4 +- .../extrafilters/extrafiltersplugin.cpp | 0 .../extrafilters/extrafiltersplugin.h | 4 +- .../plugins/plugins.pro} | 0 examples/widgets/tools/tools.pro | 3 - src/corelib/kernel/qobject.cpp | 8 +- src/corelib/plugin/qplugin.qdoc | 6 +- 24 files changed, 104 insertions(+), 103 deletions(-) create mode 100644 examples/widgets/tools/plugandpaint/app/app.pro rename examples/widgets/tools/plugandpaint/{ => app}/interfaces.h (100%) rename examples/widgets/tools/plugandpaint/{ => app}/main.cpp (100%) rename examples/widgets/tools/plugandpaint/{ => app}/mainwindow.cpp (100%) rename examples/widgets/tools/plugandpaint/{ => app}/mainwindow.h (100%) rename examples/widgets/tools/plugandpaint/{ => app}/paintarea.cpp (100%) rename examples/widgets/tools/plugandpaint/{ => app}/paintarea.h (100%) rename examples/widgets/tools/plugandpaint/{ => app}/plugindialog.cpp (100%) rename examples/widgets/tools/plugandpaint/{ => app}/plugindialog.h (100%) rename examples/widgets/tools/{plugandpaintplugins => plugandpaint/plugins}/basictools/basictools.json (100%) rename examples/widgets/tools/{plugandpaintplugins => plugandpaint/plugins}/basictools/basictools.pro (82%) rename examples/widgets/tools/{plugandpaintplugins => plugandpaint/plugins}/basictools/basictoolsplugin.cpp (100%) rename examples/widgets/tools/{plugandpaintplugins => plugandpaint/plugins}/basictools/basictoolsplugin.h (98%) rename examples/widgets/tools/{plugandpaintplugins => plugandpaint/plugins}/extrafilters/extrafilters.json (100%) rename examples/widgets/tools/{plugandpaintplugins => plugandpaint/plugins}/extrafilters/extrafilters.pro (82%) rename examples/widgets/tools/{plugandpaintplugins => plugandpaint/plugins}/extrafilters/extrafiltersplugin.cpp (100%) rename examples/widgets/tools/{plugandpaintplugins => plugandpaint/plugins}/extrafilters/extrafiltersplugin.h (98%) rename examples/widgets/tools/{plugandpaintplugins/plugandpaintplugins.pro => plugandpaint/plugins/plugins.pro} (100%) diff --git a/.gitignore b/.gitignore index 1ecd8c1009f..7179340e204 100644 --- a/.gitignore +++ b/.gitignore @@ -226,7 +226,6 @@ config.tests/unix/sse2/sse2 # --------------------- debug -examples/tools/plugandpaint/plugins include/* include/*/* lib/* diff --git a/examples/widgets/doc/src/plugandpaint.qdoc b/examples/widgets/doc/src/plugandpaint.qdoc index b139de9fa1b..a79f8546eaa 100644 --- a/examples/widgets/doc/src/plugandpaint.qdoc +++ b/examples/widgets/doc/src/plugandpaint.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! - \example tools/plugandpaint + \example tools/plugandpaint/app \title Plug & Paint Example \ingroup examples-widgets-tools @@ -47,8 +47,8 @@ through plugins, we recommend that you start by reading this overview, which explains how to make an application use plugins. Afterwards, you can read the - \l{tools/plugandpaintplugins/basictools}{Basic Tools} and - \l{tools/plugandpaintplugins/extrafilters}{Extra Filters} + \l{tools/plugandpaint/plugins/basictools}{Basic Tools} and + \l{tools/plugandpaint/plugins/extrafilters}{Extra Filters} overviews, which show how to implement static and dynamic plugins, respectively. @@ -74,7 +74,7 @@ in the plugins. - \snippet tools/plugandpaint/interfaces.h 0 + \snippet tools/plugandpaint/app/interfaces.h 0 The \c BrushInterface class declares four pure virtual functions. The first pure virtual function, \c brushes(), returns a list of @@ -96,7 +96,7 @@ virtual destructor. We provide the destructor to keep these compilers happy. - \snippet tools/plugandpaint/interfaces.h 1 + \snippet tools/plugandpaint/app/interfaces.h 1 The \c ShapeInterface class declares a \c shapes() function that works the same as \c{BrushInterface}'s \c brushes() function, and @@ -106,13 +106,13 @@ parent parameter can be used by the plugin to pop up a dialog asking the user to specify more information. - \snippet tools/plugandpaint/interfaces.h 2 + \snippet tools/plugandpaint/app/interfaces.h 2 The \c FilterInterface class declares a \c filters() function that returns a list of filter names, and a \c filterImage() function that applies a filter to an image. - \snippet tools/plugandpaint/interfaces.h 4 + \snippet tools/plugandpaint/app/interfaces.h 4 To make it possible to query at run-time whether a plugin implements a given interface, we must use the \c @@ -125,8 +125,8 @@ a good idea to include a version number in the string, as we did above. - The \l{tools/plugandpaintplugins/basictools}{Basic Tools} plugin - and the \l{tools/plugandpaintplugins/extrafilters}{Extra Filters} + The \l{tools/plugandpaint/plugins/basictools}{Basic Tools} plugin + and the \l{tools/plugandpaint/plugins/extrafilters}{Extra Filters} plugin shows how to derive from \c BrushInterface, \c ShapeInterface, and \c FilterInterface. @@ -144,7 +144,7 @@ \l{mainwindows/application}{Application}). Here, we'll concentrate on the parts of the code that are related to plugins. - \snippet tools/plugandpaint/mainwindow.cpp 4 + \snippet tools/plugandpaint/app/mainwindow.cpp 4 The \c loadPlugins() function is called from the \c MainWindow constructor to detect plugins and update the \uicontrol{Brush}, @@ -155,7 +155,7 @@ QObject. That QObject implements plugin interfaces using multiple inheritance. - \snippet tools/plugandpaint/mainwindow.cpp 5 + \snippet tools/plugandpaint/app/mainwindow.cpp 5 The next step is to load dynamic plugins. We initialize the \c pluginsDir member variable to refer to the \c plugins @@ -166,9 +166,9 @@ this file is usually located in a subdirectory, so we need to take this into account. - \snippet tools/plugandpaint/mainwindow.cpp 6 - \snippet tools/plugandpaint/mainwindow.cpp 7 - \snippet tools/plugandpaint/mainwindow.cpp 8 + \snippet tools/plugandpaint/app/mainwindow.cpp 6 + \snippet tools/plugandpaint/app/mainwindow.cpp 7 + \snippet tools/plugandpaint/app/mainwindow.cpp 8 We use QDir::entryList() to get a list of all files in that directory. Then we iterate over the result using \l foreach and @@ -181,12 +181,12 @@ If QPluginLoader::instance() is non-null, we add it to the menus. - \snippet tools/plugandpaint/mainwindow.cpp 9 + \snippet tools/plugandpaint/app/mainwindow.cpp 9 At the end, we enable or disable the \uicontrol{Brush}, \uicontrol{Shapes}, and \uicontrol{Filters} menus based on whether they contain any items. - \snippet tools/plugandpaint/mainwindow.cpp 10 + \snippet tools/plugandpaint/app/mainwindow.cpp 10 For each plugin (static or dynamic), we check which interfaces it implements using \l qobject_cast(). First, we try to cast the @@ -195,7 +195,7 @@ by \c brushes(). Then we do the same with the \c ShapeInterface and the \c FilterInterface. - \snippet tools/plugandpaint/mainwindow.cpp 3 + \snippet tools/plugandpaint/app/mainwindow.cpp 3 The \c aboutPlugins() slot is called on startup and can be invoked at any time through the \uicontrol{About Plugins} action. It @@ -211,7 +211,7 @@ plugin from which it comes from as the parent; this makes it convenient to get access to the plugin later. - \snippet tools/plugandpaint/mainwindow.cpp 0 + \snippet tools/plugandpaint/app/mainwindow.cpp 0 The \c changeBrush() slot is invoked when the user chooses one of the brushes from the \uicontrol{Brush} menu. We start by finding out @@ -222,7 +222,7 @@ identifying the brush. Next time the user draws on the paint area, \c PaintArea will use this brush. - \snippet tools/plugandpaint/mainwindow.cpp 1 + \snippet tools/plugandpaint/app/mainwindow.cpp 1 The \c insertShape() is invoked when the use chooses one of the shapes from the \uicontrol{Shapes} menu. We retrieve the QAction that @@ -230,7 +230,7 @@ QAction, and finally we call \c ShapeInterface::generateShape() to obtain a QPainterPath. - \snippet tools/plugandpaint/mainwindow.cpp 2 + \snippet tools/plugandpaint/app/mainwindow.cpp 2 The \c applyFilter() slot is similar: We retrieve the QAction that invoked the slot, then the \c FilterInterface associated to @@ -243,12 +243,12 @@ The \c PaintArea class contains some code that deals with \c BrushInterface, so we'll review it briefly. - \snippet tools/plugandpaint/paintarea.cpp 0 + \snippet tools/plugandpaint/app/paintarea.cpp 0 In \c setBrush(), we simply store the \c BrushInterface and the brush that are given to us by \c MainWindow. - \snippet tools/plugandpaint/paintarea.cpp 1 + \snippet tools/plugandpaint/app/paintarea.cpp 1 In the \l{QWidget::mouseMoveEvent()}{mouse move event handler}, we call the \c BrushInterface::mouseMove() function on the @@ -262,7 +262,7 @@ and a list of plugin file names. It calls \c findPlugins() to fill the QTreeWdiget with information about the plugins: - \snippet tools/plugandpaint/plugindialog.cpp 0 + \snippet tools/plugandpaint/app/plugindialog.cpp 0 The \c findPlugins() is very similar to \c MainWindow::loadPlugins(). It uses QPluginLoader to access the @@ -270,11 +270,11 @@ populateTreeWidget() uses \l qobject_cast() to find out which interfaces are implemented by the plugins: - \snippet tools/plugandpaint/plugindialog.cpp 1 + \snippet tools/plugandpaint/app/plugindialog.cpp 1 \section1 Importing Static Plugins - The \l{tools/plugandpaintplugins/basictools}{Basic Tools} plugin + The \l{tools/plugandpaint/plugins/basictools}{Basic Tools} plugin is built as a static plugin, to ensure that it is always available to the application. This requires using the Q_IMPORT_PLUGIN() macro somewhere in the application (in a \c @@ -283,7 +283,7 @@ For Plug & Paint, we have chosen to put Q_IMPORT_PLUGIN() in \c main.cpp: - \snippet tools/plugandpaint/main.cpp 0 + \snippet tools/plugandpaint/app/main.cpp 0 The argument to Q_IMPORT_PLUGIN() is the plugin name, which corresponds with the name of the class that declares metadata for the plugin with @@ -292,10 +292,10 @@ In the \c .pro file, we need to specify the static library. Here's the project file for building Plug & Paint: - \snippet tools/plugandpaint/plugandpaint.pro 0 + \snippet tools/plugandpaint/app/app.pro 0 The \c LIBS line variable specifies the library \c pnp_basictools - located in the \c ../plugandpaintplugins/basictools directory. + located in the \c ../plugandpaint/plugins/basictools directory. (Although the \c LIBS syntax has a distinct Unix flavor, \c qmake supports it on all platforms.) @@ -306,19 +306,19 @@ This completes our review of the Plug & Paint application. At this point, you might want to take a look at the - \l{tools/plugandpaintplugins/basictools}{Basic Tools} example + \l{tools/plugandpaint/plugins/basictools}{Basic Tools} example plugin. */ /*! - \example tools/plugandpaintplugins/basictools + \example tools/plugandpaint/plugins/basictools \title Plug & Paint Basic Tools Example \brief A plugin providing the basic tools for painting functionality. \image plugandpaint.png Screenshot of the Plug & Paint example The Basic Tools example is a static plugin for the - \l{tools/plugandpaint}{Plug & Paint} example. It provides a set + \l{tools/plugandpaint/app}{Plug & Paint} example. It provides a set of basic brushes, shapes, and filters. Through the Basic Tools example, we will review the four steps involved in writing a Qt plugin: @@ -332,13 +332,13 @@ \section1 Declaration of the Plugin Class - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 0 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.h 0 We start by including \c interfaces.h, which defines the plugin - interfaces for the \l{tools/plugandpaint}{Plug & Paint} + interfaces for the \l{tools/plugandpaint/app}{Plug & Paint} application. For the \c #include to work, we need to add an \c - INCLUDEPATH entry to the \c .pro file with the path to Qt's \c - examples/tools directory. + INCLUDEPATH entry to the \c .pro file with the path to the + header file. The \c BasicToolsPlugin class is a QObject subclass that implements the \c BrushInterface, the \c ShapeInterface, and the @@ -346,12 +346,12 @@ The \c Q_INTERFACES() macro is necessary to tell \l{moc}, Qt's meta-object compiler, that the base classes are plugin interfaces. Without the \c Q_INTERFACES() macro, we couldn't use - \l qobject_cast() in the \l{tools/plugandpaint}{Plug & Paint} + \l qobject_cast() in the \l{tools/plugandpaint/app}{Plug & Paint} application to detect interfaces. For an explanation for the \c Q_PLUGIN_METADATA() macro see \l {Exporting the Plugin}. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 2 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.h 2 In the \c public section of the class, we declare all the functions from the three interfaces. @@ -361,23 +361,23 @@ Let's now review the implementation of the \c BasicToolsPlugin member functions inherited from \c BrushInterface. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 0 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 0 The \c brushes() function returns a list of brushes provided by this plugin. We provide three brushes: \uicontrol{Pencil}, \uicontrol{Air Brush}, and \uicontrol{Random Letters}. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 1 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 1 On a mouse press event, we just call \c mouseMove() to draw the spot where the event occurred. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 2 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 2 In \c mouseMove(), we start by saving the state of the QPainter and we compute a few variables that we'll need later. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 3 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 3 Then comes the brush-dependent part of the code: @@ -399,14 +399,14 @@ At the end, we restore the painter state to what it was upon entering the function and we return the bounding rectangle. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 4 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 4 When the user releases the mouse, we do nothing and return an empty QRect. \section1 Implementation of the Shape Interface - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 5 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 5 The plugin provides three shapes: \uicontrol{Circle}, \uicontrol{Star}, and \uicontrol{Text...}. The three dots after \uicontrol{Text} are there because @@ -418,7 +418,7 @@ distinguish between the internal shape name and the name used in the user interface. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 6 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 6 The \c generateShape() creates a QPainterPath for the specified shape. If the shape is \uicontrol{Text}, we pop up a QInputDialog to @@ -426,12 +426,12 @@ \section1 Implementation of the Filter Interface - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 7 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 7 The plugin provides three filters: \uicontrol{Invert Pixels}, \uicontrol{Swap RGB}, and \uicontrol{Grayscale}. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 8 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 8 The \c filterImage() function takes a filter name and a QImage as parameters and returns an altered QImage. The first thing we do @@ -450,7 +450,7 @@ It must contain the plugins IID and optionally a filename pointing to a json file containing the metadata for the plugin. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 4 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.h 4 Within this example the json file does not need to export any metadata, so it just contains an empty json object. @@ -463,7 +463,7 @@ Here's the project file for building the Basic Tools plugin: - \snippet tools/plugandpaintplugins/basictools/basictools.pro 0 + \snippet tools/plugandpaint/plugins/basictools/basictools.pro 0 The \c .pro file differs from typical \c .pro files in many respects. First, it starts with a \c TEMPLATE entry specifying \c @@ -475,15 +475,14 @@ To make the plugin a static plugin, all that is required is to specify \c static in addition to \c plugin. The - \l{tools/plugandpaintplugins/extrafilters}{Extra Filters} plugin, + \l{tools/plugandpaint/plugins/extrafilters}{Extra Filters} plugin, which is compiled as a dynamic plugin, doesn't specify \c static in its \c .pro file. The \c INCLUDEPATH variable sets the search paths for global headers (i.e., header files included using \c{#include <...>}). - We add Qt's \c examples/tools directory (strictly speaking, - \c{examples/tools/plugandpaintplugins/basictools/../..}) to the - list, so that we can include \c . + We add \c ../../app to the list, so that we can include + \c . The \c TARGET variable specifies which name we want to give the target library. We use \c pnp_ as the prefix to show that the @@ -499,27 +498,27 @@ */ /*! - \example tools/plugandpaintplugins/extrafilters + \example tools/plugandpaint/plugins/extrafilters \title Plug & Paint Extra Filters Example \brief A plugin providing the extra filters. \image plugandpaint.png Screenshot of the Plug & Paint example The Extra Filters example is a plugin for the - \l{tools/plugandpaint}{Plug & Paint} example. It provides a set + \l{tools/plugandpaint/app}{Plug & Paint} example. It provides a set of filters in addition to those provided by the - \l{tools/plugandpaintplugins/basictools}{Basic Tools} plugin. + \l{tools/plugandpaint/plugins/basictools}{Basic Tools} plugin. Since the approach is identical to - \l{tools/plugandpaintplugins/basictools}{Basic Tools}, we won't + \l{tools/plugandpaint/plugins/basictools}{Basic Tools}, we won't review the code here. The only part of interest is the \c .pro file, since Extra Filters is a dynamic plugin - (\l{tools/plugandpaintplugins/basictools}{Basic Tools} is + (\l{tools/plugandpaint/plugins/basictools}{Basic Tools} is linked statically into the Plug & Paint executable). Here's the project file for building the Extra Filters plugin: - \snippet tools/plugandpaintplugins/extrafilters/extrafilters.pro 0 + \snippet tools/plugandpaint/plugins/extrafilters/extrafilters.pro 0 The \c .pro file differs from typical \c .pro files in many respects. First, it starts with a \c TEMPLATE entry specifying \c @@ -531,9 +530,8 @@ The \c INCLUDEPATH variable sets the search paths for global headers (i.e., header files included using \c{#include <...>}). - We add Qt's \c examples/tools directory (strictly speaking, - \c{examples/tools/plugandpaintplugins/basictools/../..}) to the - list, so that we can include \c . + We add \c ../../app to the list, so that we can include + \c . The \c TARGET variable specifies which name we want to give the target library. We use \c pnp_ as the prefix to show that the diff --git a/examples/widgets/tools/plugandpaint/app/app.pro b/examples/widgets/tools/plugandpaint/app/app.pro new file mode 100644 index 00000000000..45fb7224e0d --- /dev/null +++ b/examples/widgets/tools/plugandpaint/app/app.pro @@ -0,0 +1,26 @@ +#! [0] +TARGET = plugandpaint +DESTDIR = .. + +QT += widgets + +HEADERS = interfaces.h \ + mainwindow.h \ + paintarea.h \ + plugindialog.h +SOURCES = main.cpp \ + mainwindow.cpp \ + paintarea.cpp \ + plugindialog.cpp + +LIBS = -L../plugins -lpnp_basictools + +if(!debug_and_release|build_pass):CONFIG(debug, debug|release) { + mac:LIBS = $$member(LIBS, 0) $$member(LIBS, 1)_debug + win32:LIBS = $$member(LIBS, 0) $$member(LIBS, 1)d +} +#! [0] + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/plugandpaint +INSTALLS += target diff --git a/examples/widgets/tools/plugandpaint/interfaces.h b/examples/widgets/tools/plugandpaint/app/interfaces.h similarity index 100% rename from examples/widgets/tools/plugandpaint/interfaces.h rename to examples/widgets/tools/plugandpaint/app/interfaces.h diff --git a/examples/widgets/tools/plugandpaint/main.cpp b/examples/widgets/tools/plugandpaint/app/main.cpp similarity index 100% rename from examples/widgets/tools/plugandpaint/main.cpp rename to examples/widgets/tools/plugandpaint/app/main.cpp diff --git a/examples/widgets/tools/plugandpaint/mainwindow.cpp b/examples/widgets/tools/plugandpaint/app/mainwindow.cpp similarity index 100% rename from examples/widgets/tools/plugandpaint/mainwindow.cpp rename to examples/widgets/tools/plugandpaint/app/mainwindow.cpp diff --git a/examples/widgets/tools/plugandpaint/mainwindow.h b/examples/widgets/tools/plugandpaint/app/mainwindow.h similarity index 100% rename from examples/widgets/tools/plugandpaint/mainwindow.h rename to examples/widgets/tools/plugandpaint/app/mainwindow.h diff --git a/examples/widgets/tools/plugandpaint/paintarea.cpp b/examples/widgets/tools/plugandpaint/app/paintarea.cpp similarity index 100% rename from examples/widgets/tools/plugandpaint/paintarea.cpp rename to examples/widgets/tools/plugandpaint/app/paintarea.cpp diff --git a/examples/widgets/tools/plugandpaint/paintarea.h b/examples/widgets/tools/plugandpaint/app/paintarea.h similarity index 100% rename from examples/widgets/tools/plugandpaint/paintarea.h rename to examples/widgets/tools/plugandpaint/app/paintarea.h diff --git a/examples/widgets/tools/plugandpaint/plugindialog.cpp b/examples/widgets/tools/plugandpaint/app/plugindialog.cpp similarity index 100% rename from examples/widgets/tools/plugandpaint/plugindialog.cpp rename to examples/widgets/tools/plugandpaint/app/plugindialog.cpp diff --git a/examples/widgets/tools/plugandpaint/plugindialog.h b/examples/widgets/tools/plugandpaint/app/plugindialog.h similarity index 100% rename from examples/widgets/tools/plugandpaint/plugindialog.h rename to examples/widgets/tools/plugandpaint/app/plugindialog.h diff --git a/examples/widgets/tools/plugandpaint/plugandpaint.pro b/examples/widgets/tools/plugandpaint/plugandpaint.pro index 965eacf3888..f7da8a52bdb 100644 --- a/examples/widgets/tools/plugandpaint/plugandpaint.pro +++ b/examples/widgets/tools/plugandpaint/plugandpaint.pro @@ -1,23 +1,4 @@ -#! [0] -QT += widgets +TEMPLATE = subdirs +SUBDIRS = plugins app -HEADERS = interfaces.h \ - mainwindow.h \ - paintarea.h \ - plugindialog.h -SOURCES = main.cpp \ - mainwindow.cpp \ - paintarea.cpp \ - plugindialog.cpp - -LIBS = -Lplugins -lpnp_basictools - -if(!debug_and_release|build_pass):CONFIG(debug, debug|release) { - mac:LIBS = $$member(LIBS, 0) $$member(LIBS, 1)_debug - win32:LIBS = $$member(LIBS, 0) $$member(LIBS, 1)d -} -#! [0] - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/plugandpaint -INSTALLS += target +app.depends = plugins diff --git a/examples/widgets/tools/plugandpaintplugins/basictools/basictools.json b/examples/widgets/tools/plugandpaint/plugins/basictools/basictools.json similarity index 100% rename from examples/widgets/tools/plugandpaintplugins/basictools/basictools.json rename to examples/widgets/tools/plugandpaint/plugins/basictools/basictools.json diff --git a/examples/widgets/tools/plugandpaintplugins/basictools/basictools.pro b/examples/widgets/tools/plugandpaint/plugins/basictools/basictools.pro similarity index 82% rename from examples/widgets/tools/plugandpaintplugins/basictools/basictools.pro rename to examples/widgets/tools/plugandpaint/plugins/basictools/basictools.pro index 670ebb57093..0c0a262339b 100644 --- a/examples/widgets/tools/plugandpaintplugins/basictools/basictools.pro +++ b/examples/widgets/tools/plugandpaint/plugins/basictools/basictools.pro @@ -2,11 +2,11 @@ TEMPLATE = lib CONFIG += plugin static QT += widgets -INCLUDEPATH += ../.. +INCLUDEPATH += ../../app HEADERS = basictoolsplugin.h SOURCES = basictoolsplugin.cpp TARGET = $$qtLibraryTarget(pnp_basictools) -DESTDIR = ../../plugandpaint/plugins +DESTDIR = ../../plugins #! [0] # install diff --git a/examples/widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.cpp b/examples/widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp similarity index 100% rename from examples/widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.cpp rename to examples/widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp diff --git a/examples/widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.h b/examples/widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.h similarity index 98% rename from examples/widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.h rename to examples/widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.h index 3cf4e8ff11f..d701c8357e2 100644 --- a/examples/widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.h +++ b/examples/widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.h @@ -41,6 +41,9 @@ #ifndef BASICTOOLSPLUGIN_H #define BASICTOOLSPLUGIN_H +//! [0] +#include + #include #include #include @@ -48,9 +51,6 @@ #include #include -//! [0] -#include - //! [1] class BasicToolsPlugin : public QObject, public BrushInterface, diff --git a/examples/widgets/tools/plugandpaintplugins/extrafilters/extrafilters.json b/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafilters.json similarity index 100% rename from examples/widgets/tools/plugandpaintplugins/extrafilters/extrafilters.json rename to examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafilters.json diff --git a/examples/widgets/tools/plugandpaintplugins/extrafilters/extrafilters.pro b/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafilters.pro similarity index 82% rename from examples/widgets/tools/plugandpaintplugins/extrafilters/extrafilters.pro rename to examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafilters.pro index aa0ead87bcd..0c86a575f38 100644 --- a/examples/widgets/tools/plugandpaintplugins/extrafilters/extrafilters.pro +++ b/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafilters.pro @@ -2,11 +2,11 @@ TEMPLATE = lib CONFIG += plugin QT += widgets -INCLUDEPATH += ../.. +INCLUDEPATH += ../../app HEADERS = extrafiltersplugin.h SOURCES = extrafiltersplugin.cpp TARGET = $$qtLibraryTarget(pnp_extrafilters) -DESTDIR = ../../plugandpaint/plugins +DESTDIR = ../../plugins #! [0] # install diff --git a/examples/widgets/tools/plugandpaintplugins/extrafilters/extrafiltersplugin.cpp b/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafiltersplugin.cpp similarity index 100% rename from examples/widgets/tools/plugandpaintplugins/extrafilters/extrafiltersplugin.cpp rename to examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafiltersplugin.cpp diff --git a/examples/widgets/tools/plugandpaintplugins/extrafilters/extrafiltersplugin.h b/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafiltersplugin.h similarity index 98% rename from examples/widgets/tools/plugandpaintplugins/extrafilters/extrafiltersplugin.h rename to examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafiltersplugin.h index 79cf083794d..837f1a9c7fc 100644 --- a/examples/widgets/tools/plugandpaintplugins/extrafilters/extrafiltersplugin.h +++ b/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafiltersplugin.h @@ -42,13 +42,13 @@ #define EXTRAFILTERSPLUGIN_H //! [0] +#include + #include #include #include #include -#include - class ExtraFiltersPlugin : public QObject, public FilterInterface { Q_OBJECT diff --git a/examples/widgets/tools/plugandpaintplugins/plugandpaintplugins.pro b/examples/widgets/tools/plugandpaint/plugins/plugins.pro similarity index 100% rename from examples/widgets/tools/plugandpaintplugins/plugandpaintplugins.pro rename to examples/widgets/tools/plugandpaint/plugins/plugins.pro diff --git a/examples/widgets/tools/tools.pro b/examples/widgets/tools/tools.pro index 282f8dedeaf..69a37f342c3 100644 --- a/examples/widgets/tools/tools.pro +++ b/examples/widgets/tools/tools.pro @@ -5,7 +5,6 @@ SUBDIRS = \ customcompleter \ echoplugin \ i18n \ - plugandpaintplugins \ plugandpaint \ regexp \ regularexpression \ @@ -16,5 +15,3 @@ SUBDIRS = \ undoframework contains(DEFINES, QT_NO_TRANSLATION): SUBDIRS -= i18n - -plugandpaint.depends = plugandpaintplugins diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 19df24744a5..d97f8d0ef1d 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1123,7 +1123,7 @@ QObjectPrivate::Connection::~Connection() RTTI support and it works across dynamic library boundaries. qobject_cast() can also be used in conjunction with interfaces; - see the \l{tools/plugandpaint}{Plug & Paint} example for details. + see the \l{tools/plugandpaint/app}{Plug & Paint} example for details. \warning If T isn't declared with the Q_OBJECT macro, this function's return value is undefined. @@ -4150,11 +4150,11 @@ QDebug operator<<(QDebug dbg, const QObject *o) Example: - \snippet ../widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.h 1 + \snippet ../widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.h 1 \dots - \snippet ../widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.h 3 + \snippet ../widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.h 3 - See the \l{tools/plugandpaintplugins/basictools}{Plug & Paint + See the \l{tools/plugandpaint/plugins/basictools}{Plug & Paint Basic Tools} example for details. \sa Q_DECLARE_INTERFACE(), Q_PLUGIN_METADATA(), {How to Create Qt Plugins} diff --git a/src/corelib/plugin/qplugin.qdoc b/src/corelib/plugin/qplugin.qdoc index 1b394c4174a..09eed5a1e6c 100644 --- a/src/corelib/plugin/qplugin.qdoc +++ b/src/corelib/plugin/qplugin.qdoc @@ -44,11 +44,11 @@ to the interface class called \a ClassName. The \a Identifier must be unique. For example: - \snippet plugandpaint/interfaces.h 3 + \snippet plugandpaint/app/interfaces.h 3 This macro is normally used right after the class definition for \a ClassName, in a header file. See the - \l{tools/plugandpaint}{Plug & Paint} example for details. + \l{tools/plugandpaint/app}{Plug & Paint} example for details. If you want to use Q_DECLARE_INTERFACE with interface classes declared in a namespace then you have to make sure the Q_DECLARE_INTERFACE @@ -76,7 +76,7 @@ \snippet code/doc_src_qplugin.cpp 1 - See the \l{tools/plugandpaint}{Plug & Paint} example for details. + See the \l{tools/plugandpaint/app}{Plug & Paint} example for details. Note that the class this macro appears on must be default-constructible. From 619ab8080dfc4e0908552e71ee2ae19db6ab2c9c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 Apr 2016 16:19:52 +0200 Subject: [PATCH 22/43] fix build and installation of queuedcustomtype example it was not built at all (and didn't build with qt in a namespace), and consequently was not installed as well. Change-Id: I24d8ac4dd5d70927c262ad6336e5ee32a0fd003a Reviewed-by: Olivier Goffart (Woboq GmbH) --- .../corelib/threads/queuedcustomtype/queuedcustomtype.pro | 2 +- examples/corelib/threads/queuedcustomtype/window.h | 2 ++ examples/corelib/threads/threads.pro | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/corelib/threads/queuedcustomtype/queuedcustomtype.pro b/examples/corelib/threads/queuedcustomtype/queuedcustomtype.pro index 77421eb6380..8b91fb9ac7d 100644 --- a/examples/corelib/threads/queuedcustomtype/queuedcustomtype.pro +++ b/examples/corelib/threads/queuedcustomtype/queuedcustomtype.pro @@ -8,7 +8,7 @@ SOURCES = main.cpp \ QT += widgets # install -target.path = $$[QT_INSTALL_EXAMPLES]/corelib/threads/mandelbrot +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/threads/queuedcustomtype INSTALLS += target diff --git a/examples/corelib/threads/queuedcustomtype/window.h b/examples/corelib/threads/queuedcustomtype/window.h index b1e578faa00..52c67428dd0 100644 --- a/examples/corelib/threads/queuedcustomtype/window.h +++ b/examples/corelib/threads/queuedcustomtype/window.h @@ -44,8 +44,10 @@ #include #include "renderthread.h" +QT_BEGIN_NAMESPACE class QLabel; class QPushButton; +QT_END_NAMESPACE //! [Window class definition] class Window : public QWidget diff --git a/examples/corelib/threads/threads.pro b/examples/corelib/threads/threads.pro index e47da84a06b..b9e17a84305 100644 --- a/examples/corelib/threads/threads.pro +++ b/examples/corelib/threads/threads.pro @@ -4,4 +4,6 @@ CONFIG += no_docs_target SUBDIRS = semaphores \ waitconditions -qtHaveModule(widgets): SUBDIRS += mandelbrot +qtHaveModule(widgets): SUBDIRS += \ + mandelbrot \ + queuedcustomtype From 2c7b3726bf7fe8ec1516e2327c2a5d046ccdb8fc Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 Apr 2016 16:05:45 +0200 Subject: [PATCH 23/43] install the opengl legacy examples while they are not built, their sources should be installed as long we don't delete them completely. Change-Id: I5e628e96cc9715520cb6e5aadb2cae61d1d03a4f Reviewed-by: Laszlo Agocs --- examples/opengl/opengl.pro | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/opengl/opengl.pro b/examples/opengl/opengl.pro index ed8134743bc..a102e087334 100644 --- a/examples/opengl/opengl.pro +++ b/examples/opengl/opengl.pro @@ -16,3 +16,6 @@ qtHaveModule(widgets) { textures \ hellogles3 } + +EXAMPLE_FILES += \ + legacy From 1ae1f0da0d3b39fe5477161b1e70a7960c4785e3 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 Apr 2016 16:14:17 +0200 Subject: [PATCH 24/43] delete unreferenced file Change-Id: Ibc70cafdc098ff4f6036182d6f41a2debb15a996 Reviewed-by: Joerg Bornemann --- examples/qtestlib/tutorial5/containers.cpp | 264 --------------------- 1 file changed, 264 deletions(-) delete mode 100644 examples/qtestlib/tutorial5/containers.cpp diff --git a/examples/qtestlib/tutorial5/containers.cpp b/examples/qtestlib/tutorial5/containers.cpp deleted file mode 100644 index 401a2c54fa3..00000000000 --- a/examples/qtestlib/tutorial5/containers.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -// This file contains benchmarks for comparing QVector against std::vector - -#include -#include -#include - -#include - -template // T is the item type -class UseCases { -public: - virtual ~UseCases() {} - - // Use case: Insert \a size items into the vector. - virtual void insert(int size) = 0; - - // Use case: Lookup \a size items from the vector. - virtual void lookup(int size) = 0; -}; - -template -T * f(T *ts) // dummy function to prevent code from being optimized away by the compiler -{ - return ts; -} - -// This subclass implements the use cases using QVector as efficiently as possible. -template -class UseCases_QVector : public UseCases -{ - void insert(int size) - { - QVector v; - T t; - QBENCHMARK { - for (int i = 0; i < size; ++i) - v.append(t); - } - } - - void lookup(int size) - { - QVector v; - - T t; - for (int i = 0; i < size; ++i) - v.append(t); - - T *ts = new T[size]; - QBENCHMARK { - for (int i = 0; i < size; ++i) - ts[i] = v.value(i); - } - f(ts); - delete[] ts; - } -}; - -// This subclass implements the use cases using std::vector as efficiently as possible. -template -class UseCases_stdvector : public UseCases -{ - void insert(int size) - { - std::vector v; - T t; - QBENCHMARK { - for (int i = 0; i < size; ++i) - v.push_back(t); - } - } - - void lookup(int size) - { - std::vector v; - - T t; - for (int i = 0; i < size; ++i) - v.push_back(t); - - T *ts = new T[size]; - QBENCHMARK { - for (int i = 0; i < size; ++i) - ts[i] = v[i]; - } - f(ts); - delete[] ts; - } -}; - -struct Large { // A "large" item type - int x[1000]; -}; - -// Symbian devices typically have limited memory -# define LARGE_MAX_SIZE 20000 - -class tst_vector_vs_std : public QObject -{ - Q_OBJECT -public: - tst_vector_vs_std() - { - useCases_QVector_int = new UseCases_QVector; - useCases_stdvector_int = new UseCases_stdvector; - - useCases_QVector_Large = new UseCases_QVector; - useCases_stdvector_Large = new UseCases_stdvector; - } - -private: - UseCases *useCases_QVector_int; - UseCases *useCases_stdvector_int; - UseCases *useCases_QVector_Large; - UseCases *useCases_stdvector_Large; - -private slots: - void insert_int_data(); - void insert_int(); - void insert_Large_data(); - void insert_Large(); - void lookup_int_data(); - void lookup_int(); - void lookup_Large_data(); - void lookup_Large(); -}; - -void tst_vector_vs_std::insert_int_data() -{ - QTest::addColumn("useStd"); - QTest::addColumn("size"); - - for (int size = 10; size < 20000; size += 100) { - const QByteArray sizeString = QByteArray::number(size); - QTest::newRow(("std::vector-int--" + sizeString).constData()) << true << size; - QTest::newRow(("QVector-int--" + sizeString).constData()) << false << size; - } -} - -void tst_vector_vs_std::insert_int() -{ - QFETCH(bool, useStd); - QFETCH(int, size); - - if (useStd) - useCases_stdvector_int->insert(size); - else - useCases_QVector_int->insert(size); -} - -void tst_vector_vs_std::insert_Large_data() -{ - QTest::addColumn("useStd"); - QTest::addColumn("size"); - - for (int size = 10; size < LARGE_MAX_SIZE; size += 100) { - const QByteArray sizeString = QByteArray::number(size); - QTest::newRow(("std::vector-Large--" + sizeString).constData()) << true << size; - QTest::newRow(("QVector-Large--" + sizeString).constData()) << false << size; - } -} - -void tst_vector_vs_std::insert_Large() -{ - QFETCH(bool, useStd); - QFETCH(int, size); - - if (useStd) - useCases_stdvector_Large->insert(size); - else - useCases_QVector_Large->insert(size); -} - -//! [1] -void tst_vector_vs_std::lookup_int_data() -{ - QTest::addColumn("useStd"); - QTest::addColumn("size"); - - for (int size = 10; size < 20000; size += 100) { - const QByteArray sizeString = QByteArray::number(size); - QTest::newRow(("std::vector-int--" + sizeString).constData()) << true << size; - QTest::newRow(("QVector-int--" + sizeString).constData()) << false << size; - } -} -//! [1] - -//! [2] -void tst_vector_vs_std::lookup_int() -{ - QFETCH(bool, useStd); - QFETCH(int, size); - - if (useStd) - useCases_stdvector_int->lookup(size); // Create a std::vector and run the benchmark. - else - useCases_QVector_int->lookup(size); // Create a QVector and run the benchmark. -} -//! [2] - -void tst_vector_vs_std::lookup_Large_data() -{ - QTest::addColumn("useStd"); - QTest::addColumn("size"); - - for (int size = 10; size < LARGE_MAX_SIZE; size += 100) { - const QByteArray sizeString = QByteArray::number(size); - QTest::newRow(("std::vector-Large--" + sizeString).constData()) << true << size; - QTest::newRow(("QVector-Large--" + sizeString).constData()) << false << size; - } -} - -void tst_vector_vs_std::lookup_Large() -{ - QFETCH(bool, useStd); - QFETCH(int, size); - - if (useStd) - useCases_stdvector_Large->lookup(size); - else - useCases_QVector_Large->lookup(size); -} - -QTEST_MAIN(tst_vector_vs_std) -#include "main.moc" From 780d21e1290cb289ae330c46597a381c61b2d86c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 20 Apr 2016 18:50:12 +0200 Subject: [PATCH 25/43] fix example installs Change-Id: Ib34795f10b1d7120b28958127ced049af3b4f72b Reviewed-by: Joerg Bornemann --- examples/corelib/tools/customtype/customtype.pro | 2 +- .../corelib/tools/customtypesending/customtypesending.pro | 2 +- examples/opengl/contextinfo/contextinfo.pro | 4 ++++ examples/widgets/itemviews/storageview/storageview.pro | 4 ++++ examples/widgets/tools/echoplugin/echoplugin.pro | 4 ---- examples/widgets/tools/echoplugin/echowindow/echowindow.pro | 2 ++ examples/widgets/tools/echoplugin/plugin/plugin.pro | 4 +++- examples/widgets/tools/plugandpaint/app/app.pro | 2 ++ .../tools/plugandpaint/plugins/basictools/basictools.pro | 2 ++ .../tools/plugandpaint/plugins/extrafilters/extrafilters.pro | 2 ++ examples/widgets/tools/styleplugin/plugin/plugin.pro | 2 ++ examples/widgets/tools/styleplugin/styleplugin.pro | 4 ---- .../widgets/tools/styleplugin/stylewindow/stylewindow.pro | 2 ++ 13 files changed, 25 insertions(+), 11 deletions(-) diff --git a/examples/corelib/tools/customtype/customtype.pro b/examples/corelib/tools/customtype/customtype.pro index 1bd792db85a..0e0fe9b1a5a 100644 --- a/examples/corelib/tools/customtype/customtype.pro +++ b/examples/corelib/tools/customtype/customtype.pro @@ -4,5 +4,5 @@ SOURCES = main.cpp \ QT += widgets # install -target.path = $$[QT_INSTALL_EXAMPLES]/corelib/tools/customcompleter +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/tools/customtype INSTALLS += target diff --git a/examples/corelib/tools/customtypesending/customtypesending.pro b/examples/corelib/tools/customtypesending/customtypesending.pro index 672f6569c28..da351ce828f 100644 --- a/examples/corelib/tools/customtypesending/customtypesending.pro +++ b/examples/corelib/tools/customtypesending/customtypesending.pro @@ -6,5 +6,5 @@ SOURCES = main.cpp \ QT += widgets # install -target.path = $$[QT_INSTALL_EXAMPLES]/corelib/tools/customcompleter +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/tools/customtypesending INSTALLS += target diff --git a/examples/opengl/contextinfo/contextinfo.pro b/examples/opengl/contextinfo/contextinfo.pro index ddaa084f384..2836e5ea5a3 100644 --- a/examples/opengl/contextinfo/contextinfo.pro +++ b/examples/opengl/contextinfo/contextinfo.pro @@ -7,3 +7,7 @@ SOURCES += main.cpp \ HEADERS += widget.h \ renderwindow.h + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/contextinfo +INSTALLS += target diff --git a/examples/widgets/itemviews/storageview/storageview.pro b/examples/widgets/itemviews/storageview/storageview.pro index c5c01dc4f1a..07e7fb51456 100644 --- a/examples/widgets/itemviews/storageview/storageview.pro +++ b/examples/widgets/itemviews/storageview/storageview.pro @@ -5,3 +5,7 @@ SOURCES += storagemodel.cpp \ main.cpp HEADERS += \ storagemodel.h + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/storageview +INSTALLS += target diff --git a/examples/widgets/tools/echoplugin/echoplugin.pro b/examples/widgets/tools/echoplugin/echoplugin.pro index d95eb6b64aa..1e3d625b2f3 100644 --- a/examples/widgets/tools/echoplugin/echoplugin.pro +++ b/examples/widgets/tools/echoplugin/echoplugin.pro @@ -3,7 +3,3 @@ TEMPLATE = subdirs SUBDIRS = echowindow \ plugin #! [0] - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin -INSTALLS += target diff --git a/examples/widgets/tools/echoplugin/echowindow/echowindow.pro b/examples/widgets/tools/echoplugin/echowindow/echowindow.pro index fca0252a826..092258dd307 100644 --- a/examples/widgets/tools/echoplugin/echowindow/echowindow.pro +++ b/examples/widgets/tools/echoplugin/echowindow/echowindow.pro @@ -17,3 +17,5 @@ win32 { # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin INSTALLS += target + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/widgets/tools/echoplugin/plugin/plugin.pro b/examples/widgets/tools/echoplugin/plugin/plugin.pro index 4afe56c024c..a4b54b18f6c 100644 --- a/examples/widgets/tools/echoplugin/plugin/plugin.pro +++ b/examples/widgets/tools/echoplugin/plugin/plugin.pro @@ -12,5 +12,7 @@ DESTDIR = ../plugins EXAMPLE_FILES = echoplugin.json # install -target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin/plugin +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin/plugins INSTALLS += target + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/widgets/tools/plugandpaint/app/app.pro b/examples/widgets/tools/plugandpaint/app/app.pro index 45fb7224e0d..8139cd53ad2 100644 --- a/examples/widgets/tools/plugandpaint/app/app.pro +++ b/examples/widgets/tools/plugandpaint/app/app.pro @@ -24,3 +24,5 @@ if(!debug_and_release|build_pass):CONFIG(debug, debug|release) { # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/plugandpaint INSTALLS += target + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/widgets/tools/plugandpaint/plugins/basictools/basictools.pro b/examples/widgets/tools/plugandpaint/plugins/basictools/basictools.pro index 0c0a262339b..f28be96b036 100644 --- a/examples/widgets/tools/plugandpaint/plugins/basictools/basictools.pro +++ b/examples/widgets/tools/plugandpaint/plugins/basictools/basictools.pro @@ -12,3 +12,5 @@ DESTDIR = ../../plugins # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/plugandpaint/plugins INSTALLS += target + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafilters.pro b/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafilters.pro index 0c86a575f38..deb3c5e70e5 100644 --- a/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafilters.pro +++ b/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafilters.pro @@ -12,3 +12,5 @@ DESTDIR = ../../plugins # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/plugandpaint/plugins INSTALLS += target + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/widgets/tools/styleplugin/plugin/plugin.pro b/examples/widgets/tools/styleplugin/plugin/plugin.pro index c7e8de6ee24..35184fc82a9 100644 --- a/examples/widgets/tools/styleplugin/plugin/plugin.pro +++ b/examples/widgets/tools/styleplugin/plugin/plugin.pro @@ -20,3 +20,5 @@ EXAMPLE_FILES += simplestyle.json # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/styleplugin/styles INSTALLS += target + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/widgets/tools/styleplugin/styleplugin.pro b/examples/widgets/tools/styleplugin/styleplugin.pro index b9f251116df..4f120637b0c 100644 --- a/examples/widgets/tools/styleplugin/styleplugin.pro +++ b/examples/widgets/tools/styleplugin/styleplugin.pro @@ -1,7 +1,3 @@ TEMPLATE = subdirs SUBDIRS = stylewindow \ plugin - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/styleplugin -INSTALLS += target diff --git a/examples/widgets/tools/styleplugin/stylewindow/stylewindow.pro b/examples/widgets/tools/styleplugin/stylewindow/stylewindow.pro index 56aa373b0e2..cdc1bd2fda4 100644 --- a/examples/widgets/tools/styleplugin/stylewindow/stylewindow.pro +++ b/examples/widgets/tools/styleplugin/stylewindow/stylewindow.pro @@ -15,3 +15,5 @@ win32 { # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/styleplugin INSTALLS += target + +CONFIG += install_ok # Do not cargo-cult this! From 155533e05995c743f8ba983055f7df98d0960c48 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 3 May 2016 11:28:34 +0200 Subject: [PATCH 26/43] Fix grammar in QSKIP documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia57dd2c859ae5b025515c45593a7f89a1b7f28ff Reviewed-by: Topi Reiniö --- src/testlib/qtestcase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 6e30a5d429b..62649441dbc 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -420,7 +420,7 @@ static void stackTrace() row of test data, so an unconditional call to QSKIP will produce one skip message in the test log for each row of test data. - If called from an _data function, the QSKIP() macro will stop execution of + If called from a _data function, the QSKIP() macro will stop execution of the _data function and will prevent execution of the associated test function. From 73df18e16108fdfc3d9e4c60bbfc328d769d4234 Mon Sep 17 00:00:00 2001 From: Jesus Fernandez Date: Tue, 9 Feb 2016 10:48:26 +0100 Subject: [PATCH 27/43] Added a missing comma to the comment. Change-Id: Ia32c9b298dc35ccdd95d92550c06cff52f918ea1 Reviewed-by: Nico Vertriest --- .../doc/snippets/code/src_concurrent_qtconcurrentmap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp index 9252aa1cadf..930a11d7a1f 100644 --- a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp +++ b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp @@ -160,7 +160,7 @@ QImage scaledToWith(const QImage &image) //! [13] QList images = ...; -QFuture thumbnails = QtConcurrent::mapped(images, std::bind(&QImage::scaledToWidth, 100 Qt::SmoothTransformation)); +QFuture thumbnails = QtConcurrent::mapped(images, std::bind(&QImage::scaledToWidth, 100, Qt::SmoothTransformation)); //! [13] //! [14] From e6b1e918e12df25a359fbb87ae26f584d46df823 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 2 May 2016 11:02:09 +0200 Subject: [PATCH 28/43] QLinuxFbScreen: fix uninitialized member warnings Prompted by Coverity CID 11720 (allegedly recently new in dev but long-standing in 5.6). Even assuming the class is used correctly - test initialize() and only use if that succeeded - the destructor would have passed uninitialized arguments to munmap() and ioctl(). Noticed a double close along the way: it's been fixed on dev but should have been fixed in 5.6, too. Documented why ioctl() failure in switchToGraphicsMode() should at least do no harm. Change-Id: Ie26a9eefa435b5ff5b1a02e03e29469b8db72d3c Reviewed-by: Laszlo Agocs --- .../platforms/linuxfb/qlinuxfbscreen.cpp | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp index 91708c0a476..8c3e73fd808 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp @@ -256,15 +256,15 @@ static int openTtyDevice(const QString &device) return fd; } -static bool switchToGraphicsMode(int ttyfd, int *oldMode) +static void switchToGraphicsMode(int ttyfd, bool doSwitch, int *oldMode) { - ioctl(ttyfd, KDGETMODE, oldMode); - if (*oldMode != KD_GRAPHICS) { - if (ioctl(ttyfd, KDSETMODE, KD_GRAPHICS) != 0) - return false; + // Do not warn if the switch fails: the ioctl fails when launching from a + // remote console and there is nothing we can do about it. The matching + // call in resetTty should at least fail then, too, so we do no harm. + if (ioctl(ttyfd, KDGETMODE, oldMode) == 0) { + if (doSwitch && *oldMode != KD_GRAPHICS) + ioctl(ttyfd, KDSETMODE, KD_GRAPHICS); } - - return true; } static void resetTty(int ttyfd, int oldMode) @@ -280,21 +280,21 @@ static void blankScreen(int fd, bool on) } QLinuxFbScreen::QLinuxFbScreen(const QStringList &args) - : mArgs(args), mFbFd(-1), mBlitter(0) + : mArgs(args), mFbFd(-1), mTtyFd(-1), mBlitter(0) { + mMmap.data = 0; } QLinuxFbScreen::~QLinuxFbScreen() { if (mFbFd != -1) { - munmap(mMmap.data - mMmap.offset, mMmap.size); + if (mMmap.data) + munmap(mMmap.data - mMmap.offset, mMmap.size); close(mFbFd); } - if (mTtyFd != -1) { + if (mTtyFd != -1) resetTty(mTtyFd, mOldTtyMode); - close(mTtyFd); - } delete mBlitter; } @@ -389,11 +389,7 @@ bool QLinuxFbScreen::initialize() if (mTtyFd == -1) qErrnoWarning(errno, "Failed to open tty"); - if (doSwitchToGraphicsMode) - switchToGraphicsMode(mTtyFd, &mOldTtyMode); - // Do not warn if the switch fails: the ioctl fails when launching from - // a remote console and there is nothing we can do about it. - + switchToGraphicsMode(mTtyFd, doSwitchToGraphicsMode, &mOldTtyMode); blankScreen(mFbFd, false); return true; From ecf127505effbbf4dbfd1e7cb9561de5dae51bf2 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 22 Apr 2016 17:13:38 +0200 Subject: [PATCH 29/43] egl: Reshuffle headers to help less fortunate systems with X11 EGL headers including X headers has traditionally been problematic due to getting macros for Status, None, etc. In most cases this is not an issue anymore because on embedded one will almost always use a driver targeting the framebuffer or DRM/KMS and therefore the EGL headers do not pull in X dependencies. Furthermore, Mesa supports MESA_EGL_NO_X11_HEADERS which we set, avoiding the problem altogether with Mesa regardless of targeting X11 or KMS. However, other drivers do not have this option. On i.MX6 for instance, targeting X11 is problematic due to not having EGL_API_FB defined, which in turn means the EGL headers pulls in X headers in order to be able to define the native display and window types as Display and Window. Try to play nice with this use case by reshuffling the includes and undefining the problematic names. Task-number: QTBUG-52928 Change-Id: I059f26b340b6e442e7296055915d18f5a1ce7a7f Reviewed-by: Louai Al-Khanji --- .../eglconvenience/eglconvenience.pri | 3 +- .../eglconvenience/qeglconvenience_p.h | 2 +- .../eglconvenience/qeglpbuffer_p.h | 2 +- .../eglconvenience/qeglplatformcontext_p.h | 2 +- .../eglconvenience/qeglstreamconvenience_p.h | 3 +- src/platformsupport/eglconvenience/qt_egl_p.h | 67 +++++++++++++++++++ src/plugins/platforms/eglfs/qeglfscontext.cpp | 1 + src/plugins/platforms/eglfs/qeglfscontext.h | 2 +- .../platforms/eglfs/qeglfsdeviceintegration.h | 3 +- src/plugins/platforms/eglfs/qeglfsglobal.h | 1 + src/plugins/platforms/eglfs/qeglfshooks.h | 2 +- .../platforms/eglfs/qeglfsintegration.cpp | 2 - .../platforms/eglfs/qeglfsintegration.h | 3 +- .../platforms/eglfs/qeglfsoffscreenwindow.h | 3 +- src/plugins/platforms/eglfs/qeglfsscreen.h | 1 - src/plugins/platforms/eglfs/qeglfswindow.h | 3 +- .../gl_integrations/xcb_egl/qxcbeglinclude.h | 2 +- src/plugins/platforms/xcb/qxcbintegration.cpp | 2 +- 18 files changed, 83 insertions(+), 21 deletions(-) create mode 100644 src/platformsupport/eglconvenience/qt_egl_p.h diff --git a/src/platformsupport/eglconvenience/eglconvenience.pri b/src/platformsupport/eglconvenience/eglconvenience.pri index f1e0d58a6d2..7ad0209e997 100644 --- a/src/platformsupport/eglconvenience/eglconvenience.pri +++ b/src/platformsupport/eglconvenience/eglconvenience.pri @@ -1,7 +1,8 @@ contains(QT_CONFIG,egl) { HEADERS += \ $$PWD/qeglconvenience_p.h \ - $$PWD/qeglstreamconvenience_p.h + $$PWD/qeglstreamconvenience_p.h \ + $$PWD/qt_egl_p.h SOURCES += \ $$PWD/qeglconvenience.cpp \ diff --git a/src/platformsupport/eglconvenience/qeglconvenience_p.h b/src/platformsupport/eglconvenience/qeglconvenience_p.h index ec6f668cbac..027930d2c24 100644 --- a/src/platformsupport/eglconvenience/qeglconvenience_p.h +++ b/src/platformsupport/eglconvenience/qeglconvenience_p.h @@ -48,7 +48,7 @@ #include #include #include -#include +#include QT_BEGIN_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglpbuffer_p.h b/src/platformsupport/eglconvenience/qeglpbuffer_p.h index 81fdab89015..a932762a678 100644 --- a/src/platformsupport/eglconvenience/qeglpbuffer_p.h +++ b/src/platformsupport/eglconvenience/qeglpbuffer_p.h @@ -45,9 +45,9 @@ // We mean it. // -#include #include #include +#include QT_BEGIN_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h index 41601272a38..666c5fa0f36 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h @@ -49,7 +49,7 @@ #include #include #include -#include +#include QT_BEGIN_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h index 648b1295799..ac81c2ff0e2 100644 --- a/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h +++ b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h @@ -46,8 +46,7 @@ // #include -#include -#include +#include // This provides runtime EGLDevice/Output/Stream support even when eglext.h in // the sysroot is not up-to-date. diff --git a/src/platformsupport/eglconvenience/qt_egl_p.h b/src/platformsupport/eglconvenience/qt_egl_p.h new file mode 100644 index 00000000000..d03ac025885 --- /dev/null +++ b/src/platformsupport/eglconvenience/qt_egl_p.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT_EGL_P_H +#define QT_EGL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +#undef Status +#undef None +#undef Bool +#undef CursorShape +#undef KeyPress +#undef KeyRelease +#undef FocusIn +#undef FocusOut +#undef FontChange +#undef Expose +#undef Unsorted + +QT_BEGIN_NAMESPACE + +QT_END_NAMESPACE + +#endif // QT_EGL_P_H diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp index db35338423e..bb638091f78 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp @@ -31,6 +31,7 @@ ** ****************************************************************************/ +#include "qeglfsglobal.h" #include #include #include diff --git a/src/plugins/platforms/eglfs/qeglfscontext.h b/src/plugins/platforms/eglfs/qeglfscontext.h index 906d11b3d1b..8da4c731b8b 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.h +++ b/src/plugins/platforms/eglfs/qeglfscontext.h @@ -34,9 +34,9 @@ #ifndef QEGLFSCONTEXT_H #define QEGLFSCONTEXT_H +#include "qeglfsglobal.h" #include #include -#include "qeglfsglobal.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h index 5ec98b37d13..303810eb6e1 100644 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h @@ -45,13 +45,12 @@ // We mean it. // +#include "qeglfsglobal.h" #include #include #include #include #include -#include -#include "qeglfsglobal.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsglobal.h b/src/plugins/platforms/eglfs/qeglfsglobal.h index 9109f6be383..bd6e2082666 100644 --- a/src/plugins/platforms/eglfs/qeglfsglobal.h +++ b/src/plugins/platforms/eglfs/qeglfsglobal.h @@ -35,6 +35,7 @@ #define QEGLFSGLOBAL_H #include +#include #ifdef QT_BUILD_EGL_DEVICE_LIB #define Q_EGLFS_EXPORT Q_DECL_EXPORT diff --git a/src/plugins/platforms/eglfs/qeglfshooks.h b/src/plugins/platforms/eglfs/qeglfshooks.h index 3e4143918e0..5f19d492f8d 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks.h +++ b/src/plugins/platforms/eglfs/qeglfshooks.h @@ -34,8 +34,8 @@ #ifndef QEGLFSHOOKS_H #define QEGLFSHOOKS_H -#include "qeglfsdeviceintegration.h" #include "qeglfsglobal.h" +#include "qeglfsdeviceintegration.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 35b27cba0bb..c226c0134ab 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -79,8 +79,6 @@ #include -#include - static void initResources() { #ifndef QT_NO_CURSOR diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h index 98c7ee9f78a..2edb287b1e7 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsintegration.h @@ -34,12 +34,11 @@ #ifndef QEGLFSINTEGRATION_H #define QEGLFSINTEGRATION_H +#include "qeglfsglobal.h" #include #include #include #include -#include -#include "qeglfsglobal.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.h b/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.h index 9b8eaacd51e..f20055b4e70 100644 --- a/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.h +++ b/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.h @@ -34,9 +34,8 @@ #ifndef QEGLFSOFFSCREENWINDOW_H #define QEGLFSOFFSCREENWINDOW_H -#include -#include #include "qeglfsglobal.h" +#include QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h index 8f1d87ea250..ea669bd5bcd 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.h +++ b/src/plugins/platforms/eglfs/qeglfsscreen.h @@ -36,7 +36,6 @@ #include "qeglfsglobal.h" #include -#include QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h index 806b21de0ac..2c396e8ef45 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.h +++ b/src/plugins/platforms/eglfs/qeglfswindow.h @@ -34,13 +34,12 @@ #ifndef QEGLFSWINDOW_H #define QEGLFSWINDOW_H +#include "qeglfsglobal.h" #include "qeglfsintegration.h" #include "qeglfsscreen.h" -#include "qeglfsglobal.h" #include #include -#include QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglinclude.h b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglinclude.h index ec59cbc7c94..ce655462e4f 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglinclude.h +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglinclude.h @@ -40,7 +40,7 @@ #include #include -#include +#include QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 94e17a2983d..1176ee10c99 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -59,7 +59,7 @@ #include #ifdef XCB_USE_EGL -#include +#include #endif #ifdef XCB_USE_XLIB From 2422c1a22720e99f63f7d0f132a0ba7b02da5039 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 14 Apr 2016 16:20:06 -0700 Subject: [PATCH 30/43] Cocoa: Enable skipping Ctrl+LMB to RMB override This can be enabled with QT_MAC_DONT_OVERRIDE_CTRL_LMB=1 environment variable. The goal is to provide consistent cross-platform input when it's more desirable than full platform comformance. Change-Id: I3b96733077bd1c0367edeef21a98a44b15425807 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qnsview.mm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index a2f97c78dca..4b7b50a265f 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -70,6 +70,8 @@ static QTouchDevice *touchDevice = 0; // ### HACK Remove once 10.8 is unsupported static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; +static bool _q_dontOverrideCtrlLMB = false; + @interface NSEvent (Qt_Compile_Leopard_DeviceDelta) - (CGFloat)deviceDeltaX; - (CGFloat)deviceDeltaY; @@ -130,6 +132,8 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; NSString **notificationNameVar = (NSString **)dlsym(RTLD_NEXT, "NSWindowDidChangeOcclusionStateNotification"); if (notificationNameVar) _q_NSWindowDidChangeOcclusionStateNotification = *notificationNameVar; + + _q_dontOverrideCtrlLMB = qt_mac_resolveOption(false, "QT_MAC_DONT_OVERRIDE_CTRL_LMB"); } - (id) init @@ -854,7 +858,7 @@ QT_WARNING_POP if ([self hasMarkedText]) { [[NSTextInputContext currentInputContext] handleEvent:theEvent]; } else { - if ([QNSView convertKeyModifiers:[theEvent modifierFlags]] & Qt::MetaModifier) { + if (!_q_dontOverrideCtrlLMB && [QNSView convertKeyModifiers:[theEvent modifierFlags]] & Qt::MetaModifier) { m_buttons |= Qt::RightButton; m_sendUpAsRightButton = true; } else { From 60cd1c67759642018ef93cc45a90714729100d9d Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 28 Apr 2016 11:30:30 +0200 Subject: [PATCH 31/43] xcb: don't compress tablet motion events 7edd10e6c added this compression feature, but it's not a good idea for drawing-tablet applications, because smooth drawing depends on receiving every movement of the stylus. Also show the device ID in qt.qpa.input.devices category logging. [ChangeLog][X11] The new X event compression feature that was added in 5.6.0 no longer applies to motion events from drawing tablets. Task-number: QTBUG-44964 Change-Id: Icd2ca8ca77d8f80c2f39160c74208db10e382501 Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbconnection.cpp | 7 ++++++- src/plugins/platforms/xcb/qxcbconnection.h | 1 + .../platforms/xcb/qxcbconnection_xi2.cpp | 21 ++++++++++++------- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index edfaf2b0156..669ef3a98e3 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1626,8 +1626,13 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex, if (!m_xi2Enabled) return false; - // compress XI_Motion + // compress XI_Motion, but not from tablet devices if (isXIType(event, m_xiOpCode, XI_Motion)) { +#ifndef QT_NO_TABLETEVENT + xXIDeviceEvent *xdev = reinterpret_cast(event); + if (const_cast(this)->tabletDataForDevice(xdev->sourceid)) + return false; +#endif // QT_NO_TABLETEVENT for (int j = nextIndex; j < eventqueue->size(); ++j) { xcb_generic_event_t *next = eventqueue->at(j); if (!isValid(next)) diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 7ba95887ffe..501da1ce7b9 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -578,6 +578,7 @@ private: bool xi2HandleTabletEvent(void *event, TabletData *tabletData, QXcbWindowEventListener *eventListener); void xi2ReportTabletEvent(TabletData &tabletData, void *event); QVector m_tabletData; + TabletData *tabletDataForDevice(int id); #endif // !QT_NO_TABLETEVENT struct ScrollingDevice { ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0), legacyOrientations(0) { } diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 9911afb11e3..025dde3dbbc 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -113,7 +113,7 @@ void QXcbConnection::xi2SetupDevices() // Only non-master pointing devices are relevant here. if (devices[i].use != XISlavePointer) continue; - qCDebug(lcQpaXInputDevices) << "input device "<< devices[i].name; + qCDebug(lcQpaXInputDevices) << "input device " << devices[i].name << "ID" << devices[i].deviceid; #ifndef QT_NO_TABLETEVENT TabletData tabletData; #endif @@ -530,12 +530,9 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) #ifndef QT_NO_TABLETEVENT if (!xiEnterEvent) { - for (int i = 0; i < m_tabletData.count(); ++i) { - if (m_tabletData.at(i).deviceId == sourceDeviceId) { - if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener)) - return; - } - } + QXcbConnection::TabletData *tablet = tabletDataForDevice(sourceDeviceId); + if (tablet && xi2HandleTabletEvent(xiEvent, tablet, eventListener)) + return; } #endif // QT_NO_TABLETEVENT @@ -1198,6 +1195,16 @@ void QXcbConnection::xi2ReportTabletEvent(TabletData &tabletData, void *event) xTilt, yTilt, tangentialPressure, rotation, 0, tabletData.serialId); } + +QXcbConnection::TabletData *QXcbConnection::tabletDataForDevice(int id) +{ + for (int i = 0; i < m_tabletData.count(); ++i) { + if (m_tabletData.at(i).deviceId == id) + return &m_tabletData[i]; + } + return Q_NULLPTR; +} + #endif // QT_NO_TABLETEVENT #endif // XCB_USE_XINPUT2 From 63ec10353db7aaaf227f769398056b6fd42f9b7d Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 4 May 2016 10:44:53 +0200 Subject: [PATCH 32/43] Revert "egl: Reshuffle headers to help less fortunate systems with X11" This reverts commit ecf127505effbbf4dbfd1e7cb9561de5dae51bf2. ecf12750 breaks the build of qtwayland. Change-Id: If8bf04f035aa47e4e867d201ec7d95b0d3e18317 Reviewed-by: Laszlo Agocs --- .../eglconvenience/eglconvenience.pri | 3 +- .../eglconvenience/qeglconvenience_p.h | 2 +- .../eglconvenience/qeglpbuffer_p.h | 2 +- .../eglconvenience/qeglplatformcontext_p.h | 2 +- .../eglconvenience/qeglstreamconvenience_p.h | 3 +- src/platformsupport/eglconvenience/qt_egl_p.h | 67 ------------------- src/plugins/platforms/eglfs/qeglfscontext.cpp | 1 - src/plugins/platforms/eglfs/qeglfscontext.h | 2 +- .../platforms/eglfs/qeglfsdeviceintegration.h | 3 +- src/plugins/platforms/eglfs/qeglfsglobal.h | 1 - src/plugins/platforms/eglfs/qeglfshooks.h | 2 +- .../platforms/eglfs/qeglfsintegration.cpp | 2 + .../platforms/eglfs/qeglfsintegration.h | 3 +- .../platforms/eglfs/qeglfsoffscreenwindow.h | 3 +- src/plugins/platforms/eglfs/qeglfsscreen.h | 1 + src/plugins/platforms/eglfs/qeglfswindow.h | 3 +- .../gl_integrations/xcb_egl/qxcbeglinclude.h | 2 +- src/plugins/platforms/xcb/qxcbintegration.cpp | 2 +- 18 files changed, 21 insertions(+), 83 deletions(-) delete mode 100644 src/platformsupport/eglconvenience/qt_egl_p.h diff --git a/src/platformsupport/eglconvenience/eglconvenience.pri b/src/platformsupport/eglconvenience/eglconvenience.pri index 7ad0209e997..f1e0d58a6d2 100644 --- a/src/platformsupport/eglconvenience/eglconvenience.pri +++ b/src/platformsupport/eglconvenience/eglconvenience.pri @@ -1,8 +1,7 @@ contains(QT_CONFIG,egl) { HEADERS += \ $$PWD/qeglconvenience_p.h \ - $$PWD/qeglstreamconvenience_p.h \ - $$PWD/qt_egl_p.h + $$PWD/qeglstreamconvenience_p.h SOURCES += \ $$PWD/qeglconvenience.cpp \ diff --git a/src/platformsupport/eglconvenience/qeglconvenience_p.h b/src/platformsupport/eglconvenience/qeglconvenience_p.h index 027930d2c24..ec6f668cbac 100644 --- a/src/platformsupport/eglconvenience/qeglconvenience_p.h +++ b/src/platformsupport/eglconvenience/qeglconvenience_p.h @@ -48,7 +48,7 @@ #include #include #include -#include +#include QT_BEGIN_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglpbuffer_p.h b/src/platformsupport/eglconvenience/qeglpbuffer_p.h index a932762a678..81fdab89015 100644 --- a/src/platformsupport/eglconvenience/qeglpbuffer_p.h +++ b/src/platformsupport/eglconvenience/qeglpbuffer_p.h @@ -45,9 +45,9 @@ // We mean it. // +#include #include #include -#include QT_BEGIN_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h index 666c5fa0f36..41601272a38 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h @@ -49,7 +49,7 @@ #include #include #include -#include +#include QT_BEGIN_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h index ac81c2ff0e2..648b1295799 100644 --- a/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h +++ b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h @@ -46,7 +46,8 @@ // #include -#include +#include +#include // This provides runtime EGLDevice/Output/Stream support even when eglext.h in // the sysroot is not up-to-date. diff --git a/src/platformsupport/eglconvenience/qt_egl_p.h b/src/platformsupport/eglconvenience/qt_egl_p.h deleted file mode 100644 index d03ac025885..00000000000 --- a/src/platformsupport/eglconvenience/qt_egl_p.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins 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 The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/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. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT_EGL_P_H -#define QT_EGL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include - -#undef Status -#undef None -#undef Bool -#undef CursorShape -#undef KeyPress -#undef KeyRelease -#undef FocusIn -#undef FocusOut -#undef FontChange -#undef Expose -#undef Unsorted - -QT_BEGIN_NAMESPACE - -QT_END_NAMESPACE - -#endif // QT_EGL_P_H diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp index bb638091f78..db35338423e 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp @@ -31,7 +31,6 @@ ** ****************************************************************************/ -#include "qeglfsglobal.h" #include #include #include diff --git a/src/plugins/platforms/eglfs/qeglfscontext.h b/src/plugins/platforms/eglfs/qeglfscontext.h index 8da4c731b8b..906d11b3d1b 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.h +++ b/src/plugins/platforms/eglfs/qeglfscontext.h @@ -34,9 +34,9 @@ #ifndef QEGLFSCONTEXT_H #define QEGLFSCONTEXT_H -#include "qeglfsglobal.h" #include #include +#include "qeglfsglobal.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h index 303810eb6e1..5ec98b37d13 100644 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h @@ -45,12 +45,13 @@ // We mean it. // -#include "qeglfsglobal.h" #include #include #include #include #include +#include +#include "qeglfsglobal.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsglobal.h b/src/plugins/platforms/eglfs/qeglfsglobal.h index bd6e2082666..9109f6be383 100644 --- a/src/plugins/platforms/eglfs/qeglfsglobal.h +++ b/src/plugins/platforms/eglfs/qeglfsglobal.h @@ -35,7 +35,6 @@ #define QEGLFSGLOBAL_H #include -#include #ifdef QT_BUILD_EGL_DEVICE_LIB #define Q_EGLFS_EXPORT Q_DECL_EXPORT diff --git a/src/plugins/platforms/eglfs/qeglfshooks.h b/src/plugins/platforms/eglfs/qeglfshooks.h index 5f19d492f8d..3e4143918e0 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks.h +++ b/src/plugins/platforms/eglfs/qeglfshooks.h @@ -34,8 +34,8 @@ #ifndef QEGLFSHOOKS_H #define QEGLFSHOOKS_H -#include "qeglfsglobal.h" #include "qeglfsdeviceintegration.h" +#include "qeglfsglobal.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index c226c0134ab..35b27cba0bb 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -79,6 +79,8 @@ #include +#include + static void initResources() { #ifndef QT_NO_CURSOR diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h index 2edb287b1e7..98c7ee9f78a 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsintegration.h @@ -34,11 +34,12 @@ #ifndef QEGLFSINTEGRATION_H #define QEGLFSINTEGRATION_H -#include "qeglfsglobal.h" #include #include #include #include +#include +#include "qeglfsglobal.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.h b/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.h index f20055b4e70..9b8eaacd51e 100644 --- a/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.h +++ b/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.h @@ -34,8 +34,9 @@ #ifndef QEGLFSOFFSCREENWINDOW_H #define QEGLFSOFFSCREENWINDOW_H -#include "qeglfsglobal.h" +#include #include +#include "qeglfsglobal.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h index ea669bd5bcd..8f1d87ea250 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.h +++ b/src/plugins/platforms/eglfs/qeglfsscreen.h @@ -36,6 +36,7 @@ #include "qeglfsglobal.h" #include +#include QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h index 2c396e8ef45..806b21de0ac 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.h +++ b/src/plugins/platforms/eglfs/qeglfswindow.h @@ -34,12 +34,13 @@ #ifndef QEGLFSWINDOW_H #define QEGLFSWINDOW_H -#include "qeglfsglobal.h" #include "qeglfsintegration.h" #include "qeglfsscreen.h" +#include "qeglfsglobal.h" #include #include +#include QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglinclude.h b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglinclude.h index ce655462e4f..ec59cbc7c94 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglinclude.h +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglinclude.h @@ -40,7 +40,7 @@ #include #include -#include +#include QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 1176ee10c99..94e17a2983d 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -59,7 +59,7 @@ #include #ifdef XCB_USE_EGL -#include +#include #endif #ifdef XCB_USE_XLIB From 67509693bdac23af4e062140a1b1058dee3f060b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Mon, 14 Dec 2015 10:42:51 +0100 Subject: [PATCH 33/43] Improve tst_qtimeline::setPaused resilience MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test should not depend on qWait explicitly Change-Id: I13c01c47c9f7bae8b0c30afa2ac8550dc0fbf028 Reviewed-by: Friedemann Kleint Reviewed-by: Jan Arve Sæther --- .../corelib/tools/qtimeline/tst_qtimeline.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp index b588e1fe821..dd41b5632d3 100644 --- a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp +++ b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp @@ -649,22 +649,21 @@ void tst_QTimeLine::restart() void tst_QTimeLine::setPaused() { - QTimeLine timeLine(1000); + const int EndTime = 10000; + QTimeLine timeLine(EndTime); { QCOMPARE(timeLine.currentTime(), 0); timeLine.start(); - QTest::qWait(250); + QTRY_VERIFY(timeLine.currentTime() != 0); // wait for start timeLine.setPaused(true); int oldCurrentTime = timeLine.currentTime(); QVERIFY(oldCurrentTime > 0); - QVERIFY(oldCurrentTime < 1000); + QVERIFY(oldCurrentTime < EndTime); QTest::qWait(1000); timeLine.setPaused(false); - QTest::qWait(250); - int currentTime = timeLine.currentTime(); - QVERIFY(currentTime > 0); - QVERIFY(currentTime > oldCurrentTime); - QVERIFY(currentTime < 1000); + QTRY_VERIFY(timeLine.currentTime() > oldCurrentTime); + QVERIFY(timeLine.currentTime() > 0); + QVERIFY(timeLine.currentTime() < EndTime); timeLine.stop(); } } From 54781edbaabc563f1fb6e4f14edc35e675009ac7 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 4 May 2016 09:32:30 +0200 Subject: [PATCH 34/43] Manual touch test: Add color for Qt::MouseEventSynthesizedByApplication. Fix a warning about a missing case statement. Change-Id: Ic89646704d62668cf83c463dbf6e9b549a4b5200 Reviewed-by: Shawn Rutledge --- tests/manual/touch/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/manual/touch/main.cpp b/tests/manual/touch/main.cpp index 2a5c2b508ed..6fa81413614 100644 --- a/tests/manual/touch/main.cpp +++ b/tests/manual/touch/main.cpp @@ -261,6 +261,9 @@ QColor Point::color() const case Qt::MouseEventSynthesizedByQt: globalColor = Qt::blue; break; + case Qt::MouseEventSynthesizedByApplication: + globalColor = Qt::green; + break; case Qt::MouseEventNotSynthesized: break; } From b75e10684cb4d14e49059e6c85bfe60ca6ab9dff Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 4 May 2016 09:57:46 +0200 Subject: [PATCH 35/43] doc: Clarify how to remove a QTextFrame The documentation wrongfully recommended deleting QTextFrames directly. This would cause a crash, since the destructor didn't update the document's layout at all. The correct way is the same as when removing other aspects of the document. Task-number: QTBUG-53082 Change-Id: I64f0ad08f1d063626456fa51d03611871ce6aa45 Reviewed-by: Simon Hausmann --- src/gui/text/qtextobject.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index e70b8ed3007..e1cfd22295a 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -412,9 +412,12 @@ QTextFrame::QTextFrame(QTextDocument *doc) { } -// ### DOC: What does this do to child frames? /*! - Destroys the frame, and removes it from the document's layout. + Destroys the text frame. + + \warning Text frames are owned by the document, so you should + never destroy them yourself. In order to remove a frame from + its document, remove its contents using a \c QTextCursor. */ QTextFrame::~QTextFrame() { From b3e9144c3a326af26d94e0cbd448357d3072a650 Mon Sep 17 00:00:00 2001 From: Elena Zaretskaya Date: Sat, 9 Apr 2016 00:46:24 +0400 Subject: [PATCH 36/43] Fix FPE under EGLFS_KMS if mesa-10.2.7 If mesa-10.2.7 is installed, gbm_bo_create returns NULL (QEglFSKmsCursor ctor, qeglfskmscursor.cpp:80), but after that the pointer m_bo is used in function QEGlFSKmsCursor::changeCursor without verification. Task-number: QTBUG-52404 Change-Id: I5b1b15d751e46a5200248e7a8642f7917dedd220 Reviewed-by: Laszlo Agocs --- .../deviceintegration/eglfs_kms/qeglfskmscursor.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp index dda61e3901d..97ea3f1eca0 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp @@ -100,8 +100,10 @@ QEglFSKmsCursor::~QEglFSKmsCursor() drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0); } - gbm_bo_destroy(m_bo); - m_bo = Q_NULLPTR; + if (m_bo) { + gbm_bo_destroy(m_bo); + m_bo = Q_NULLPTR; + } } void QEglFSKmsCursor::pointerEvent(const QMouseEvent &event) @@ -114,6 +116,9 @@ void QEglFSKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window) { Q_UNUSED(window); + if (!m_bo) + return; + if (!m_visible) return; From 8d45759432e7f954360b76ddeaf2b09acee8606e Mon Sep 17 00:00:00 2001 From: Elena Zaretskaya Date: Fri, 8 Apr 2016 12:29:25 +0400 Subject: [PATCH 37/43] Fix segfault when exiting app running under eglfs In function QWindow::destroy() the platformWindow is destroyed (QEglFSWindow in this case), but after that the QSurface destructor is called (qsurface.cpp:127), where access to the opengl context is performed (QOpenGLContext::currentContext()->doneCurrent()). Therefore the surface pointer is deleted earlier (gbm_surface_destroy) than the working with it (eglMakeCurrent) is finished. But the event QPlatformSurfaceEvent, that is sent before deleting platformWindow, isn't processed (qwindow.cpp:1665), though we can perform doneCurrent() in the handler of QPlatformSurfaceEvent. The full description with valgrind stacks on bugreports. Task-number: QTBUG-52399 Change-Id: I69035dfd8ba5b5eeec243bc0edd3f571dc9525f9 Reviewed-by: Laszlo Agocs --- src/gui/kernel/qwindow.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 68bcbdec71f..7f84706b6f7 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2109,6 +2109,17 @@ bool QWindow::event(QEvent *ev) break; } + case QEvent::PlatformSurface: { + if ((static_cast(ev))->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed) { +#ifndef QT_NO_OPENGL + QOpenGLContext *context = QOpenGLContext::currentContext(); + if (context && context->surface() == static_cast(this)) + context->doneCurrent(); +#endif + } + break; + } + default: return QObject::event(ev); } From 2c60125ef967d157b8c1de8eec7e40dcef424c34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 4 May 2016 12:07:20 +0200 Subject: [PATCH 38/43] Add missing Q_DECL_OVERRIDEs Change-Id: I54552d9fdd0bc8871247246aea1da14848c4f7a0 Reviewed-by: Timur Pocheptsov --- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 55b6aff237d..92e504e1fb6 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -5862,7 +5862,7 @@ public: startTimer(1000); } - void timerEvent(QTimerEvent *) + void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE { switch (state++) { case 0: @@ -5885,7 +5885,7 @@ public: return false; } - bool nativeEvent(const QByteArray &eventType, void *message, long *) + bool nativeEvent(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE { if (isMapNotify(eventType, message)) gotExpectedMapNotify = true; @@ -5893,7 +5893,7 @@ public: } // QAbstractNativeEventFilter interface - virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE + bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE { if (isMapNotify(eventType, message)) gotExpectedGlobalEvent = true; From dec0b15685985d5b7c56748c0e52cfbdb4d1d6a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 4 May 2016 13:01:00 +0200 Subject: [PATCH 39/43] Change Q_OS_MAC -> Q_OS_OSX Q_OS_DARWIN is the general replacement for Q_OS_MAC, but most/all of the MAC sections in this test are OS X specific. Change-Id: Ic54af9d3dce1e1952a57e15b74acdedf2af60c79 Reviewed-by: Timur Pocheptsov --- .../widgets/kernel/qwidget/tst_qwidget.cpp | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 92e504e1fb6..c2b01ea087b 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -74,7 +74,7 @@ #include "../../../qtest-config.h" -#if defined(Q_OS_MAC) +#if defined(Q_OS_OSX) #include "tst_qwidget_mac_helpers.h" // Abstract the ObjC stuff out so not everyone must run an ObjC++ compile. #endif @@ -141,7 +141,7 @@ bool qt_wince_is_smartphone() { } #endif -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX #include bool macHasAccessToWindowsServer() { @@ -268,7 +268,7 @@ private slots: void restoreVersion1Geometry(); void widgetAt(); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX void sheetOpacity(); void setMask(); #endif @@ -301,7 +301,7 @@ private slots: void update(); void isOpaque(); -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX void scroll(); void scrollNativeChildren(); #endif @@ -434,7 +434,7 @@ private slots: void taskQTBUG_7532_tabOrderWithFocusProxy(); void movedAndResizedAttributes(); void childAt(); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX void childAt_unifiedToolBar(); void taskQTBUG_11373(); #endif @@ -2380,12 +2380,12 @@ void tst_QWidget::showMinimizedKeepsFocus() window.showNormal(); qApp->setActiveWindow(&window); QVERIFY(QTest::qWaitForWindowActive(&window)); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX if (!macHasAccessToWindowsServer()) QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue); #endif QTRY_COMPARE(window.focusWidget(), firstchild); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX if (!macHasAccessToWindowsServer()) QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue); #endif @@ -2725,7 +2725,7 @@ public: void tst_QWidget::lostUpdatesOnHide() { -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX UpdateWidget widget; widget.setAttribute(Qt::WA_DontShowOnScreen); widget.show(); @@ -2767,7 +2767,7 @@ void tst_QWidget::raise() QVERIFY(QTest::qWaitForWindowExposed(parentPtr.data())); QTest::qWait(10); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX if (child1->internalWinId()) { QSKIP("Cocoa has no Z-Order for views, we hack it, but it results in paint events."); } @@ -2947,7 +2947,7 @@ void tst_QWidget::stackUnder() foreach (UpdateWidget *child, allChildren) { int expectedPaintEvents = child == child4 ? 1 : 0; -#if defined(Q_OS_WIN) || defined(Q_OS_MAC) +#if defined(Q_OS_WIN) || defined(Q_OS_OSX) if (expectedPaintEvents == 1 && child->numPaintEvents == 2) QEXPECT_FAIL(0, "Mac and Windows issues double repaints for Z-Order change", Continue); #endif @@ -2986,7 +2986,7 @@ void tst_QWidget::stackUnder() #ifdef Q_OS_WINCE qApp->processEvents(); #endif -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX QEXPECT_FAIL(0, "See QTBUG-493", Continue); #endif QCOMPARE(child->numPaintEvents, 0); @@ -3523,7 +3523,7 @@ void tst_QWidget::testDeletionInEventHandlers() delete w; } -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX void tst_QWidget::sheetOpacity() { QWidget tmpWindow; @@ -4314,7 +4314,7 @@ void tst_QWidget::update() QCOMPARE(sibling.numPaintEvents, 1); QCOMPARE(sibling.paintedRegion, sibling.visibleRegion()); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX if (child.internalWinId()) // child is native QEXPECT_FAIL(0, "Cocoa compositor paints child and sibling", Continue); #endif @@ -4340,7 +4340,7 @@ static inline bool isOpaque(QWidget *widget) void tst_QWidget::isOpaque() { -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX QWidget w; QVERIFY(::isOpaque(&w)); @@ -4412,7 +4412,7 @@ void tst_QWidget::isOpaque() #endif } -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX /* Test that scrolling of a widget invalidates the correct regions */ @@ -4859,7 +4859,7 @@ void tst_QWidget::windowMoveResize() widget.move(r.topLeft()); widget.resize(r.size()); QApplication::processEvents(); -#if defined(Q_OS_MAC) +#if defined(Q_OS_OSX) if (r.width() == 0 && r.height() > 0) { widget.move(r.topLeft()); widget.resize(r.size()); @@ -4930,7 +4930,7 @@ void tst_QWidget::windowMoveResize() widget.move(r.topLeft()); widget.resize(r.size()); QApplication::processEvents(); -#if defined(Q_OS_MAC) +#if defined(Q_OS_OSX) if (r.width() == 0 && r.height() > 0) { widget.move(r.topLeft()); widget.resize(r.size()); @@ -5120,7 +5120,7 @@ void tst_QWidget::moveChild() QTRY_COMPARE(pos, child.pos()); QCOMPARE(parent.r, QRegion(oldGeometry) - child.geometry()); -#if !defined(Q_OS_MAC) +#if !defined(Q_OS_OSX) // should be scrolled in backingstore QCOMPARE(child.r, QRegion()); #endif @@ -6912,7 +6912,7 @@ void tst_QWidget::render_systemClip() // rrrrrrrrrr // ... -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX for (int i = 0; i < image.height(); ++i) { for (int j = 0; j < image.width(); ++j) { if (i < 50 && j < i) @@ -7916,7 +7916,7 @@ void tst_QWidget::sendUpdateRequestImmediately() void tst_QWidget::doubleRepaint() { -#if defined(Q_OS_MAC) +#if defined(Q_OS_OSX) if (!macHasAccessToWindowsServer()) QSKIP("Not having window server access causes the wrong number of repaints to be issues"); #endif @@ -8626,7 +8626,7 @@ void tst_QWidget::setClearAndResizeMask() QTRY_COMPARE(child.mask(), childMask); QTest::qWait(50); // and ensure that the child widget doesn't get any update. -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QCOMPARE(child.numPaintEvents, 1); @@ -8649,7 +8649,7 @@ void tst_QWidget::setClearAndResizeMask() // and ensure that that the child widget gets an update for the area outside the old mask. QTRY_COMPARE(child.numPaintEvents, 1); outsideOldMask = child.rect(); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (!child.internalWinId()) #endif @@ -8664,7 +8664,7 @@ void tst_QWidget::setClearAndResizeMask() // Mask child widget with a mask that is bigger than the rect child.setMask(QRegion(0, 0, 1000, 1000)); QTest::qWait(100); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QTRY_COMPARE(child.numPaintEvents, 1); @@ -8677,7 +8677,7 @@ void tst_QWidget::setClearAndResizeMask() // ...and the same applies when clearing the mask. child.clearMask(); QTest::qWait(100); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QTRY_VERIFY(child.numPaintEvents > 0); @@ -8707,7 +8707,7 @@ void tst_QWidget::setClearAndResizeMask() QTimer::singleShot(100, &resizeChild, SLOT(shrinkMask())); QTest::qWait(200); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask()); @@ -8719,7 +8719,7 @@ void tst_QWidget::setClearAndResizeMask() const QRegion oldMask = resizeChild.mask(); QTimer::singleShot(0, &resizeChild, SLOT(enlargeMask())); QTest::qWait(100); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask()); @@ -9432,7 +9432,7 @@ void tst_QWidget::taskQTBUG_7532_tabOrderWithFocusProxy() void tst_QWidget::movedAndResizedAttributes() { -#if defined (Q_OS_MAC) +#if defined (Q_OS_OSX) QEXPECT_FAIL("", "FixMe, QTBUG-8941 and QTBUG-8977", Abort); QVERIFY(false); #else @@ -9539,7 +9539,7 @@ void tst_QWidget::childAt() QCOMPARE(parent.childAt(120, 120), grandChild); } -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX void tst_QWidget::childAt_unifiedToolBar() { QLabel *label = new QLabel(QLatin1String("foo")); From 22bcf7ba3433753fd93a59beb9006e6983e1530e Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Tue, 3 May 2016 09:10:32 +0200 Subject: [PATCH 40/43] QSplitter: Add note about ownership transfer to addWidget() and insertWidget() Change-Id: I971db2c25e4e667a416f58d148e18c4f11c349f1 Reviewed-by: Marc Mutz --- src/widgets/widgets/qsplitter.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp index 20b6a029cd6..b6959e2460f 100644 --- a/src/widgets/widgets/qsplitter.cpp +++ b/src/widgets/widgets/qsplitter.cpp @@ -1093,6 +1093,8 @@ void QSplitter::resizeEvent(QResizeEvent *) If \a widget is already in the splitter, it will be moved to the new position. + \note The splitter takes ownership of the widget. + \sa insertWidget(), widget(), indexOf() */ void QSplitter::addWidget(QWidget *widget) @@ -1107,7 +1109,9 @@ void QSplitter::addWidget(QWidget *widget) If \a widget is already in the splitter, it will be moved to the new position. - if \a index is an invalid index, then the widget will be inserted at the end. + If \a index is an invalid index, then the widget will be inserted at the end. + + \note The splitter takes ownership of the widget. \sa addWidget(), indexOf(), widget() */ From 728a1b4f29f0042fc13299bf6cc78e83cdc9d7f9 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 4 May 2016 13:00:42 +0200 Subject: [PATCH 41/43] tst_QKeyEvent::modifiers(): Ensure test data row names are pure ASCII. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test used to output random character sequences which contained terminal control characters. Change it to output plain ASCII and Unicode syntax for non-ASCII characters. Change-Id: Ifaa72f50242bd27416a8698a1f5152bc8b902898 Reviewed-by: Jędrzej Nowacki --- .../gui/kernel/qkeyevent/tst_qkeyevent.cpp | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp b/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp index db0bfaf6228..811a6d111fb 100644 --- a/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp +++ b/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp @@ -116,6 +116,23 @@ static bool orderByModifier(const QVector &v1, const QVector &v2) return true; } +static QByteArray modifiersTestRowName(const QString &keySequence) +{ + QByteArray result; + QTextStream str(&result); + for (int i = 0, size = keySequence.size(); i < size; ++i) { + const QChar &c = keySequence.at(i); + const ushort uc = c.unicode(); + if (uc > 32 && uc < 128) + str << '"' << c << '"'; + else + str << "U+" << hex << uc << dec; + if (i < size - 1) + str << ','; + } + return result; +} + void tst_QKeyEvent::modifiers_data() { struct Modifier @@ -155,7 +172,8 @@ void tst_QKeyEvent::modifiers_data() mods |= modifier.modifier; } QKeySequence keySequence(keys[0], keys[1], keys[2], keys[3]); - QTest::newRow(keySequence.toString(QKeySequence::NativeText).toUtf8().constData()) << mods; + QTest::newRow(modifiersTestRowName(keySequence.toString(QKeySequence::NativeText)).constData()) + << mods; } } From 4ef269963bad7a76ed03e81b91b94058c812e31b Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Mon, 2 May 2016 12:08:00 +0300 Subject: [PATCH 42/43] Avoid use of v4-mapped QHostAddress::AnyIPv4 local address on Windows Some Windows kernels return a v4-mapped QHostAddress::AnyIPv4 as a local address of the socket which bound on both IPv4 and IPv6 interfaces. This address does not match to any special address and should not be used to send the data. To allow handling of the local addresses properly, replace it with QHostAddress::Any. Already tested by tst_qudpsocket. Task-number: QTBUG-52714 Change-Id: Icb7cb75f48cd7ec9b0a9dfaf861ffe0d3093e20d Reviewed-by: Thiago Macieira --- src/network/socket/qnativesocketengine_win.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 770bae7bf35..41834b21ae5 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -573,6 +573,19 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() } } + // Some Windows kernels return a v4-mapped QHostAddress::AnyIPv4 as a + // local address of the socket which bound on both IPv4 and IPv6 interfaces. + // This address does not match to any special address and should not be used + // to send the data. So, replace it with QHostAddress::Any. + if (socketProtocol == QAbstractSocket::IPv6Protocol) { + bool ok = false; + const quint32 localIPv4 = localAddress.toIPv4Address(&ok); + if (ok && localIPv4 == INADDR_ANY) { + socketProtocol = QAbstractSocket::AnyIPProtocol; + localAddress = QHostAddress::Any; + } + } + memset(&sa, 0, sizeof(sa)); if (::getpeername(socketDescriptor, &sa.a, &sockAddrSize) == 0) { qt_socket_getPortAndAddress(socketDescriptor, &sa, &peerPort, &peerAddress); From f57d8f1341587e6b2aa84b8404aa218432584206 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Sat, 5 Mar 2016 19:32:02 +0200 Subject: [PATCH 43/43] QFileSystemMetaData: do not treat block devices as sequential MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch allows handling of special block devices in random-access mode that restores a Qt4 behavior. Can not be tested because requires root privileges in the system. Task-number: QTBUG-51666 Change-Id: Iaa56355f1be343c0d05b292e3c7d2e1c88724529 Reviewed-by: Edward Welbourne Reviewed-by: Andrius Štikonas Reviewed-by: Oswald Buddenhagen Reviewed-by: Allan Sandfeld Jensen --- src/corelib/io/qfilesystemengine.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index a49d69d4478..02aa2ff4b72 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -258,7 +258,7 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) entryFlags |= QFileSystemMetaData::FileType; else if ((statBuffer.st_mode & S_IFMT) == S_IFDIR) entryFlags |= QFileSystemMetaData::DirectoryType; - else + else if ((statBuffer.st_mode & S_IFMT) != S_IFBLK) entryFlags |= QFileSystemMetaData::SequentialType; // Attributes @@ -341,6 +341,18 @@ void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry) break; case DT_BLK: + knownFlagsMask = QFileSystemMetaData::LinkType + | QFileSystemMetaData::FileType + | QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::BundleType + | QFileSystemMetaData::AliasType + | QFileSystemMetaData::SequentialType + | QFileSystemMetaData::ExistsAttribute; + + entryFlags = QFileSystemMetaData::ExistsAttribute; + + break; + case DT_CHR: case DT_FIFO: case DT_SOCK: