From 5e921a18b2a098f68dbce368f9d20447939b3510 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 25 Nov 2016 11:16:45 +0100 Subject: [PATCH 01/74] Doc: Enable global linking to new Qt Creator VCS subtopics Each supported version control system is described in more detail in a dedicated topic since version 4.2. Change-Id: I666f8c18d31954935c836509e572a3bfd2c2a32e Reviewed-by: Venugopal Shivashankar --- doc/global/externalsites/qtcreator.qdoc | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/doc/global/externalsites/qtcreator.qdoc b/doc/global/externalsites/qtcreator.qdoc index f73b17c92f..0e66610d84 100644 --- a/doc/global/externalsites/qtcreator.qdoc +++ b/doc/global/externalsites/qtcreator.qdoc @@ -81,6 +81,34 @@ \externalpage http://doc.qt.io/qtcreator/creator-version-control.html \title Qt Creator: Using Version Control Systems */ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-vcs-bazaar.html + \title Qt Creator: Using Bazaar +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-vcs-clearcase.html + \title Qt Creator: Using ClearCase +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-vcs-cvs.html + \title Qt Creator: Using CVS +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-vcs-git.html + \title Qt Creator: Using Git +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-vcs-mercurial.html + \title Qt Creator: Using Mercurial +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-vcs-perforce.html + \title Qt Creator: Using Perforce +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-vcs-subversion.html + \title Qt Creator: Using Subversion +*/ /*! \externalpage http://doc.qt.io/qtcreator/creator-keyboard-shortcuts.html \title Qt Creator: Keyboard Shortcuts From 20526cb01466105c0e4ed1430ac9722f3dddf60a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 15 Nov 2016 07:37:16 -0800 Subject: [PATCH 02/74] Make sure all pattern args get cleared when parsing a new pattern The user can call qSetMessagePattern after program start, so we need to be sure that the parsed argument data is properly cleared. Task-number: QTBUG-57144 Change-Id: I1978c6b95bd84639a8c4fffd1487429b04725522 Reviewed-by: Kai Koehne --- src/corelib/global/qlogging.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 22b75afac8..e1b8ef4b6d 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1039,6 +1039,10 @@ void QMessagePattern::setPattern(const QString &pattern) delete [] literals; } delete [] tokens; + timeArgs.clear(); +#ifdef QLOGGING_HAVE_BACKTRACE + backtraceArgs.clear(); +#endif // scanner QList lexemes; From 1ff2acf20f6b2a0f7d49635bc46a19bc45d55fb1 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Thu, 24 Nov 2016 02:02:42 +0300 Subject: [PATCH 03/74] QtGui: Add missing override Change-Id: Ief5b0863d7649d5a8d421c05766513276c264776 Reviewed-by: hjk --- src/gui/image/qbmphandler_p.h | 14 +++---- src/gui/image/qpnghandler_p.h | 14 +++---- src/gui/image/qppmhandler_p.h | 14 +++---- src/gui/image/qxbmhandler_p.h | 14 +++---- src/gui/image/qxpmhandler_p.h | 14 +++---- src/gui/opengl/qopenglpaintdevice.h | 6 +-- src/gui/painting/qemulationpaintengine_p.h | 48 +++++++++++----------- src/gui/painting/qpaintengine_raster_p.h | 2 +- src/gui/painting/qpdfwriter.h | 12 +++--- src/gui/painting/qstroker_p.h | 8 ++-- 10 files changed, 73 insertions(+), 73 deletions(-) diff --git a/src/gui/image/qbmphandler_p.h b/src/gui/image/qbmphandler_p.h index c4800e3f97..ab164d9f83 100644 --- a/src/gui/image/qbmphandler_p.h +++ b/src/gui/image/qbmphandler_p.h @@ -93,17 +93,17 @@ public: }; explicit QBmpHandler(InternalFormat fmt = BmpFormat); - bool canRead() const; - bool read(QImage *image); - bool write(const QImage &image); + bool canRead() const override; + bool read(QImage *image) override; + bool write(const QImage &image) override; - QByteArray name() const; + QByteArray name() const override; static bool canRead(QIODevice *device); - QVariant option(ImageOption option) const; - void setOption(ImageOption option, const QVariant &value); - bool supportsOption(ImageOption option) const; + QVariant option(ImageOption option) const override; + void setOption(ImageOption option, const QVariant &value) override; + bool supportsOption(ImageOption option) const override; private: bool readHeader(); diff --git a/src/gui/image/qpnghandler_p.h b/src/gui/image/qpnghandler_p.h index fb5a830baa..00f9fa5921 100644 --- a/src/gui/image/qpnghandler_p.h +++ b/src/gui/image/qpnghandler_p.h @@ -64,15 +64,15 @@ public: QPngHandler(); ~QPngHandler(); - bool canRead() const; - bool read(QImage *image); - bool write(const QImage &image); + bool canRead() const override; + bool read(QImage *image) override; + bool write(const QImage &image) override; - QByteArray name() const; + QByteArray name() const override; - QVariant option(ImageOption option) const; - void setOption(ImageOption option, const QVariant &value); - bool supportsOption(ImageOption option) const; + QVariant option(ImageOption option) const override; + void setOption(ImageOption option, const QVariant &value) override; + bool supportsOption(ImageOption option) const override; static bool canRead(QIODevice *device); diff --git a/src/gui/image/qppmhandler_p.h b/src/gui/image/qppmhandler_p.h index 1e8ca2b81e..e790aafdcd 100644 --- a/src/gui/image/qppmhandler_p.h +++ b/src/gui/image/qppmhandler_p.h @@ -62,17 +62,17 @@ class QPpmHandler : public QImageIOHandler { public: QPpmHandler(); - bool canRead() const; - bool read(QImage *image); - bool write(const QImage &image); + bool canRead() const override; + bool read(QImage *image) override; + bool write(const QImage &image) override; - QByteArray name() const; + QByteArray name() const override; static bool canRead(QIODevice *device, QByteArray *subType = 0); - QVariant option(ImageOption option) const; - void setOption(ImageOption option, const QVariant &value); - bool supportsOption(ImageOption option) const; + QVariant option(ImageOption option) const override; + void setOption(ImageOption option, const QVariant &value) override; + bool supportsOption(ImageOption option) const override; private: bool readHeader(); diff --git a/src/gui/image/qxbmhandler_p.h b/src/gui/image/qxbmhandler_p.h index 5094a43ef6..8649857255 100644 --- a/src/gui/image/qxbmhandler_p.h +++ b/src/gui/image/qxbmhandler_p.h @@ -61,17 +61,17 @@ class QXbmHandler : public QImageIOHandler { public: QXbmHandler(); - bool canRead() const; - bool read(QImage *image); - bool write(const QImage &image); + bool canRead() const override; + bool read(QImage *image) override; + bool write(const QImage &image) override; - QByteArray name() const; + QByteArray name() const override; static bool canRead(QIODevice *device); - QVariant option(ImageOption option) const; - void setOption(ImageOption option, const QVariant &value); - bool supportsOption(ImageOption option) const; + QVariant option(ImageOption option) const override; + void setOption(ImageOption option, const QVariant &value) override; + bool supportsOption(ImageOption option) const override; private: bool readHeader(); diff --git a/src/gui/image/qxpmhandler_p.h b/src/gui/image/qxpmhandler_p.h index 9a2041be94..a54427e853 100644 --- a/src/gui/image/qxpmhandler_p.h +++ b/src/gui/image/qxpmhandler_p.h @@ -61,17 +61,17 @@ class QXpmHandler : public QImageIOHandler { public: QXpmHandler(); - bool canRead() const; - bool read(QImage *image); - bool write(const QImage &image); + bool canRead() const override; + bool read(QImage *image) override; + bool write(const QImage &image) override; static bool canRead(QIODevice *device); - QByteArray name() const; + QByteArray name() const override; - QVariant option(ImageOption option) const; - void setOption(ImageOption option, const QVariant &value); - bool supportsOption(ImageOption option) const; + QVariant option(ImageOption option) const override; + void setOption(ImageOption option, const QVariant &value) override; + bool supportsOption(ImageOption option) const override; private: bool readHeader(); diff --git a/src/gui/opengl/qopenglpaintdevice.h b/src/gui/opengl/qopenglpaintdevice.h index dffa68c29e..ce639e647e 100644 --- a/src/gui/opengl/qopenglpaintdevice.h +++ b/src/gui/opengl/qopenglpaintdevice.h @@ -61,8 +61,8 @@ public: QOpenGLPaintDevice(int width, int height); virtual ~QOpenGLPaintDevice(); - int devType() const { return QInternal::OpenGL; } - QPaintEngine *paintEngine() const; + int devType() const override { return QInternal::OpenGL; } + QPaintEngine *paintEngine() const override; QOpenGLContext *context() const; QSize size() const; @@ -82,7 +82,7 @@ public: protected: QOpenGLPaintDevice(QOpenGLPaintDevicePrivate &dd); - int metric(QPaintDevice::PaintDeviceMetric metric) const; + int metric(QPaintDevice::PaintDeviceMetric metric) const override; Q_DISABLE_COPY(QOpenGLPaintDevice) QScopedPointer d_ptr; diff --git a/src/gui/painting/qemulationpaintengine_p.h b/src/gui/painting/qemulationpaintengine_p.h index f3cf88af17..df58332479 100644 --- a/src/gui/painting/qemulationpaintengine_p.h +++ b/src/gui/painting/qemulationpaintengine_p.h @@ -61,37 +61,37 @@ class QEmulationPaintEngine : public QPaintEngineEx public: QEmulationPaintEngine(QPaintEngineEx *engine); - virtual bool begin(QPaintDevice *pdev); - virtual bool end(); + bool begin(QPaintDevice *pdev) override; + bool end() override; - virtual Type type() const; - virtual QPainterState *createState(QPainterState *orig) const; + Type type() const override; + QPainterState *createState(QPainterState *orig) const override; - virtual void fill(const QVectorPath &path, const QBrush &brush); - virtual void stroke(const QVectorPath &path, const QPen &pen); - virtual void clip(const QVectorPath &path, Qt::ClipOperation op); + void fill(const QVectorPath &path, const QBrush &brush) override; + void stroke(const QVectorPath &path, const QPen &pen) override; + void clip(const QVectorPath &path, Qt::ClipOperation op) override; - virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); - virtual void drawTextItem(const QPointF &p, const QTextItem &textItem); - virtual void drawStaticTextItem(QStaticTextItem *item); - virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s); - virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags); + void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override; + void drawTextItem(const QPointF &p, const QTextItem &textItem) override; + void drawStaticTextItem(QStaticTextItem *item) override; + void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s) override; + void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags) override; - virtual void clipEnabledChanged(); - virtual void penChanged(); - virtual void brushChanged(); - virtual void brushOriginChanged(); - virtual void opacityChanged(); - virtual void compositionModeChanged(); - virtual void renderHintsChanged(); - virtual void transformChanged(); + void clipEnabledChanged() override; + void penChanged() override; + void brushChanged() override; + void brushOriginChanged() override; + void opacityChanged() override; + void compositionModeChanged() override; + void renderHintsChanged() override; + void transformChanged() override; - virtual void setState(QPainterState *s); + void setState(QPainterState *s) override; - virtual void beginNativePainting(); - virtual void endNativePainting(); + void beginNativePainting() override; + void endNativePainting() override; - virtual uint flags() const {return QPaintEngineEx::IsEmulationEngine | QPaintEngineEx::DoNotEmulate;} + uint flags() const override { return QPaintEngineEx::IsEmulationEngine | QPaintEngineEx::DoNotEmulate; } inline QPainterState *state() { return (QPainterState *)QPaintEngine::state; } inline const QPainterState *state() const { return (const QPainterState *)QPaintEngine::state; } diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index 1afb119535..2a213fa238 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -286,7 +286,7 @@ public: void rasterize(QT_FT_Outline *outline, ProcessSpans callback, void *userData, QRasterBuffer *rasterBuffer); void updateMatrixData(QSpanData *spanData, const QBrush &brush, const QTransform &brushMatrix); - void systemStateChanged(); + void systemStateChanged() override; void drawImage(const QPointF &pt, const QImage &img, SrcOverBlendFunc func, const QRect &clip, int alpha, const QRect &sr = QRect()); diff --git a/src/gui/painting/qpdfwriter.h b/src/gui/painting/qpdfwriter.h index cf1da95bf1..c36f3c7a91 100644 --- a/src/gui/painting/qpdfwriter.h +++ b/src/gui/painting/qpdfwriter.h @@ -67,7 +67,7 @@ public: QString creator() const; void setCreator(const QString &creator); - bool newPage(); + bool newPage() override; void setResolution(int resolution); int resolution() const; @@ -83,14 +83,14 @@ public: using QPagedPaintDevice::setPageSize; #endif - void setPageSize(PageSize size); - void setPageSizeMM(const QSizeF &size); + void setPageSize(PageSize size) override; + void setPageSizeMM(const QSizeF &size) override; - void setMargins(const Margins &m); + void setMargins(const Margins &m) override; protected: - QPaintEngine *paintEngine() const; - int metric(PaintDeviceMetric id) const; + QPaintEngine *paintEngine() const override; + int metric(PaintDeviceMetric id) const override; private: Q_DISABLE_COPY(QPdfWriter) diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h index e17e68b237..ac30f5b5e8 100644 --- a/src/gui/painting/qstroker_p.h +++ b/src/gui/painting/qstroker_p.h @@ -233,7 +233,7 @@ protected: static Qt::PenJoinStyle joinForJoinMode(LineJoinMode mode); static LineJoinMode joinModeForJoin(Qt::PenJoinStyle joinStyle); - virtual void processCurrentSubpath(); + void processCurrentSubpath() override; qfixed m_strokeWidth; qfixed m_miterLimit; @@ -264,14 +264,14 @@ public: void setDashOffset(qreal offset) { m_dashOffset = offset; } qreal dashOffset() const { return m_dashOffset; } - virtual void begin(void *data); - virtual void end(); + void begin(void *data) override; + void end() override; inline void setStrokeWidth(qreal width) { m_stroke_width = width; } inline void setMiterLimit(qreal limit) { m_miter_limit = limit; } protected: - virtual void processCurrentSubpath(); + void processCurrentSubpath() override; QStroker *m_stroker; QVector m_dashPattern; From 534c1ce76d499c680b1b5163346064e8b2bc4617 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 23 Nov 2016 17:38:05 -0800 Subject: [PATCH 04/74] Remove unnecessary warning disabling Qt 5.7 cannot be compiled in C++03 mode anymore. Change-Id: Iaeecaffe26af4535b416fffd1489d808edc3c996 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qmetatype.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index b68dbacbd3..4c3435be53 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1390,10 +1390,6 @@ namespace QtPrivate }; -QT_WARNING_PUSH -// In C++03 mode, clang consider local or unnamed type and throw a warning instead of ignoring them -QT_WARNING_DISABLE_CLANG("-Wunnamed-type-template-args") -QT_WARNING_DISABLE_CLANG("-Wlocal-type-template-args") template char qt_getEnumMetaObject(const T&); template @@ -1406,7 +1402,6 @@ QT_WARNING_DISABLE_CLANG("-Wlocal-type-template-args") enum { Value = sizeof(qt_getEnumMetaObject(declval())) == sizeof(QMetaObject*) }; }; template<> struct IsQEnumHelper { enum { Value = false }; }; -QT_WARNING_POP template struct MetaObjectForType From 1710947fde5b65cf27d274624459f17cda1f4700 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 29 Nov 2016 10:02:44 +0100 Subject: [PATCH 05/74] QMutex: small doc fixes Add parentheses after function names, replace is different -> differs Change-Id: I6332db1d1650ed8d8320c5f20cd79d0bf1870e27 Reviewed-by: Mitch Curtis --- src/corelib/thread/qmutex.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp index 0aee4aeda4..653c3efe1c 100644 --- a/src/corelib/thread/qmutex.cpp +++ b/src/corelib/thread/qmutex.cpp @@ -279,7 +279,7 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT for the mutex to become available. Note: Passing a negative duration as the \a duration is equivalent to - calling try_lock(). This behavior is different from tryLock. + calling try_lock(). This behavior differs from tryLock(). If the lock was obtained, the mutex must be unlocked with unlock() before another thread can successfully lock it. @@ -303,7 +303,7 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT for the mutex to become available. Note: Passing a \a timePoint which has already passed is equivalent - to calling try_lock. This behavior is different from tryLock. + to calling try_lock(). This behavior differs from tryLock(). If the lock was obtained, the mutex must be unlocked with unlock() before another thread can successfully lock it. From feb95effc4a694426acadc84364a938098186df7 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 29 Nov 2016 16:43:44 +0100 Subject: [PATCH 06/74] QDeadlineTimer: fix namespace for chrono literals in examples Change-Id: I6d39b4fe653cf89d2bd27af4b3f606d98ac83eba Reviewed-by: Thiago Macieira --- src/corelib/kernel/qdeadlinetimer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qdeadlinetimer.cpp b/src/corelib/kernel/qdeadlinetimer.cpp index d670637d53..1f554c9f2e 100644 --- a/src/corelib/kernel/qdeadlinetimer.cpp +++ b/src/corelib/kernel/qdeadlinetimer.cpp @@ -122,6 +122,7 @@ Q_DECL_CONST_FUNCTION static inline QPair toSecsAndNSecs(qint64 \code using namespace std::chrono; + using namespace std::chrono_literals; QDeadlineTimer deadline(30s); device->waitForReadyRead(deadline); @@ -141,6 +142,7 @@ Q_DECL_CONST_FUNCTION static inline QPair toSecsAndNSecs(qint64 \code using namespace std::chrono; + using namespace std::chrono_literals; auto now = steady_clock::now(); QDeadlineTimer deadline(now + 1s); Q_ASSERT(deadline == now + 1s); @@ -240,7 +242,7 @@ QDeadlineTimer::QDeadlineTimer(qint64 msecs, Qt::TimerType type) Q_DECL_NOTHROW This constructor can be used with C++14's user-defined literals for time, such as in: \code - using namespace std::chrono; + using namespace std::chrono_literals; QDeadlineTimer deadline(250ms); \endcode @@ -333,7 +335,7 @@ void QDeadlineTimer::setPreciseRemainingTime(qint64 secs, qint64 nsecs, Qt::Time This function can be used with C++14's user-defined literals for time, such as in: \code - using namespace std::chrono; + using namespace std::chrono_literals; deadline.setRemainingTime(250ms); \endcode From fe0b91879b672486ad9581e3fa577b4b32732ecc Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 28 Nov 2016 17:46:22 +0100 Subject: [PATCH 07/74] Fix type of VcprojGenerator::extraCompilerOutputs The values of this hash are strings, not lists of strings. Enforce this by using the proper type instead of just using a comment. Change-Id: Id8a13acdceb8f9f8a9a8eaa04e790b1e6cd5faa7 Reviewed-by: Oswald Buddenhagen --- qmake/generators/win32/msvc_objectmodel.cpp | 6 +++--- qmake/generators/win32/msvc_vcproj.cpp | 2 +- qmake/generators/win32/msvc_vcproj.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index fb9c4f354d..98d60f4f04 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -2260,10 +2260,10 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info) QString inFile = info.file; // is the extracompiler rule on a file with a built in compiler? - const QStringList &objectMappedFile = Project->extraCompilerOutputs[inFile]; + const QString objectMappedFile = Project->extraCompilerOutputs.value(inFile); bool hasBuiltIn = false; if (!objectMappedFile.isEmpty()) { - hasBuiltIn = Project->hasBuiltinCompiler(objectMappedFile.at(0)); + hasBuiltIn = Project->hasBuiltinCompiler(objectMappedFile); // qDebug("*** Extra compiler file has object mapped file '%s' => '%s'", qPrintable(inFile), qPrintable(objectMappedFile.join(' '))); } @@ -2305,7 +2305,7 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info) // compiler, too bad.. if (hasBuiltIn) { out = inFile; - inFile = objectMappedFile.at(0); + inFile = objectMappedFile; } // Dependency for the output diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 7b3d7fd160..38e7e96b98 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -889,7 +889,7 @@ void VcprojGenerator::init() QString out = Option::fixPathToTargetOS(replaceExtraCompilerVariables( compiler_out, file, QString(), NoShell), false); extraCompilerSources[out] += quc.toQString(); - extraCompilerOutputs[out] = QStringList(file); // Can only have one + extraCompilerOutputs[out] = file; } } } diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index 9ccd8c2552..39ba2f0900 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -63,7 +63,7 @@ public: static bool hasBuiltinCompiler(const QString &file); QHash extraCompilerSources; - QHash extraCompilerOutputs; + QHash extraCompilerOutputs; bool usePCH; VCProjectWriter *projectWriter; From 6515d942aef76d7090e2421b85ac58eeae3614ea Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 24 Nov 2016 16:53:53 +0100 Subject: [PATCH 08/74] Set a proper name for the moc_predefs extra compiler In VS builds the default name is the first word of the command, in this case "cl". Use the generated file name instead. Change-Id: I8f0039eeae045f8b9a13caea8bd3e338bbe2ed17 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/moc.prf | 1 + 1 file changed, 1 insertion(+) diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index dc14d71db7..4d3632531a 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -28,6 +28,7 @@ win32:count(MOC_INCLUDEPATH, 40, >) { # UIKit builds are always multi-arch due to simulator_and_device (unless # -sdk is used) so this feature cannot possibly work. if(gcc|intel_icl|msvc):!rim_qcc:!uikit { + moc_predefs.name = "Generate moc_predefs.h" moc_predefs.CONFIG = no_link gcc: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -dM -E -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} else:intel_icl: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -QdM -P -Fi${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} From 448790eaedff47c8a8df9da964b988e309c06182 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 30 Nov 2016 10:07:43 +0100 Subject: [PATCH 09/74] Windows QPA: Fix build with MSVC2015 on Windows 7 The installation uses SDK 8.1 which does not have the required include files. Add a check depending on NTDDI_VERSION. Change-Id: I6323496aed2a2d6e22d41ec14bdf8c6cf1bf2f31 Reviewed-by: Konstantin Tokarev Reviewed-by: Maurice Kalinowski --- src/plugins/platforms/windows/qwin10helpers.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwin10helpers.cpp b/src/plugins/platforms/windows/qwin10helpers.cpp index 3ded96b9d6..977bbfd11b 100644 --- a/src/plugins/platforms/windows/qwin10helpers.cpp +++ b/src/plugins/platforms/windows/qwin10helpers.cpp @@ -44,7 +44,8 @@ #if defined(Q_CC_MINGW) # define HAS_UI_VIEW_SETTINGS_INTEROP -#elif !defined(Q_CC_MSVC) || _MSC_VER >= 1900 // MSVC2013 is lacking both +// Present from MSVC2015 + SDK 10 onwards +#elif (!defined(Q_CC_MSVC) || _MSC_VER >= 1900) && NTDDI_VERSION >= 0xa000000 # define HAS_UI_VIEW_SETTINGS_INTEROP # define HAS_UI_VIEW_SETTINGS #endif From dcd2f8295179170d6459edcb06ff9bd339748de6 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 28 Nov 2016 18:16:35 +0100 Subject: [PATCH 10/74] Fix circular dependencies in generated vcxproj files For QMAKE_EXTRA_COMPILERS with inputs that are "buildable" (e.g. C++ sources) the custom build step is added to the output file. From Visual Studio's point of view this looks like a circular dependency (e.g. foo.moc generates foo.moc). Usually this just prints a warning that can be ignored. But this circular dependency also breaks dependencies between custom build steps. This became noticeable when the generation of moc_predefs.h was added. Generating moc_predefs.h must be done before any moc custom build step is executed. This patch fixes the issue by using fake files (output file plus suffix ".cbt" for "custom build tool") that act as dummy inputs for the custom build tools. Task-number: QTBUG-16904 Task-number: QTBUG-57196 Change-Id: I4711e44a0551046d215db151fa0312af8a9177a2 Reviewed-by: Oswald Buddenhagen Reviewed-by: Oliver Wolff --- qmake/generators/win32/msvc_objectmodel.cpp | 4 ++++ qmake/generators/win32/msvc_vcproj.cpp | 7 ++++++- qmake/generators/win32/msvc_vcproj.h | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 98d60f4f04..70a722ba23 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -2264,6 +2264,10 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info) bool hasBuiltIn = false; if (!objectMappedFile.isEmpty()) { hasBuiltIn = Project->hasBuiltinCompiler(objectMappedFile); + + // Remove the fake file suffix we've added initially to generate correct command lines. + inFile.chop(Project->customBuildToolFilterFileSuffix.length()); + // qDebug("*** Extra compiler file has object mapped file '%s' => '%s'", qPrintable(inFile), qPrintable(objectMappedFile.join(' '))); } diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 38e7e96b98..21bdad1bbf 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -198,7 +198,8 @@ const char _slnExtSections[] = "\n\tGlobalSection(ExtensibilityGlobals) = pos VcprojGenerator::VcprojGenerator() : Win32MakefileGenerator(), is64Bit(false), - projectWriter(0) + projectWriter(0), + customBuildToolFilterFileSuffix(QStringLiteral(".cbt")) { } @@ -886,8 +887,12 @@ void VcprojGenerator::init() if (!hasBuiltinCompiler(file)) { extraCompilerSources[file] += quc.toQString(); } else { + // Use a fake file name foo.moc.cbt for the project view. + // This prevents VS from complaining about a circular + // dependency from foo.moc -> foo.moc. QString out = Option::fixPathToTargetOS(replaceExtraCompilerVariables( compiler_out, file, QString(), NoShell), false); + out += customBuildToolFilterFileSuffix; extraCompilerSources[out] += quc.toQString(); extraCompilerOutputs[out] = file; } diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index 39ba2f0900..e3e67d64b9 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -64,6 +64,7 @@ public: QHash extraCompilerSources; QHash extraCompilerOutputs; + const QString customBuildToolFilterFileSuffix; bool usePCH; VCProjectWriter *projectWriter; From a55f36211efe1bb0d6717c8545366120bd6dfd9f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 21 Nov 2016 15:17:03 -0800 Subject: [PATCH 11/74] Fix the JPEG EXIF reader to deal with some broken/corrupt files We parse the EXIF header in order to get the proper orientation, so let's be a bit more careful in what we accept. This patch adds better handling for reading past the end of the stream, plus it limits the number of IFDs read (to avoid processing too much data) and deals with a pathological case of the EXIF file format: EXIF (due to its TIFF origins) permits the offset to the next IFD to be backwards in the file, which means it could result in a loop or pointing to plain corrupt data. We disallow any backwards pointers, since it seems that's what other decoders do (libexif, for example). Change-Id: Iaeecaffe26af4535b416fffd1489332db92e3888 (cherry picked from 5.6 commit 02150649f95b8f46f826e6e002be3fa0b6d009bc) Reviewed-by: Allan Sandfeld Jensen --- src/gui/image/qjpeghandler.cpp | 31 ++++++++++++------ .../jpeg_exif_invalid_data_back_pointers.jpg | Bin 0 -> 910 bytes .../jpeg_exif_invalid_data_past_end.jpg | Bin 0 -> 910 bytes .../jpeg_exif_invalid_data_too_many_ifds.jpg | Bin 0 -> 964 bytes .../jpeg_exif_invalid_data_too_many_tags.jpg | Bin 0 -> 910 bytes tests/auto/gui/image/qimage/tst_qimage.cpp | 17 ++++++++-- 6 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_back_pointers.jpg create mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_past_end.jpg create mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_too_many_ifds.jpg create mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_too_many_tags.jpg diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index 52e8b39f11..f3ba303d62 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -786,6 +786,10 @@ static bool readExifHeader(QDataStream &stream) */ static int getExifOrientation(QByteArray &exifData) { + // Current EXIF version (2.3) says there can be at most 5 IFDs, + // byte we allow for 10 so we're able to deal with future extensions. + const int maxIfdCount = 10; + QDataStream stream(&exifData, QIODevice::ReadOnly); if (!readExifHeader(stream)) @@ -793,7 +797,8 @@ static int getExifOrientation(QByteArray &exifData) quint16 val; quint32 offset; - const qint64 headerStart = stream.device()->pos(); + const qint64 headerStart = 6; // the EXIF header has a constant size + Q_ASSERT(headerStart == stream.device()->pos()); // read byte order marker stream >> val; @@ -804,7 +809,7 @@ static int getExifOrientation(QByteArray &exifData) else return -1; // unknown byte order - // read size + // confirm byte order stream >> val; if (val != 0x2a) return -1; @@ -812,18 +817,22 @@ static int getExifOrientation(QByteArray &exifData) stream >> offset; // read IFD - while (!stream.atEnd()) { + for (int n = 0; n < maxIfdCount; ++n) { quint16 numEntries; - // skip offset bytes to get the next IFD const qint64 bytesToSkip = offset - (stream.device()->pos() - headerStart); - - if (stream.skipRawData(bytesToSkip) != bytesToSkip) + if (bytesToSkip < 0 || (offset + headerStart >= exifData.size())) { + // disallow going backwards, though it's permitted in the spec return -1; + } else if (bytesToSkip != 0) { + // seek to the IFD + if (!stream.device()->seek(offset + headerStart)) + return -1; + } stream >> numEntries; - for (; numEntries > 0; --numEntries) { + for (; numEntries > 0 && stream.status() == QDataStream::Ok; --numEntries) { quint16 tag; quint16 type; quint32 components; @@ -847,12 +856,14 @@ static int getExifOrientation(QByteArray &exifData) // read offset to next IFD stream >> offset; + if (stream.status() != QDataStream::Ok) + return -1; if (offset == 0) // this is the last IFD - break; + return 0; // No Exif orientation was found } - // No Exif orientation was found - return 0; + // too many IFDs + return -1; } static QImageIOHandler::Transformations exif2Qt(int exifOrientation) diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_back_pointers.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_back_pointers.jpg new file mode 100644 index 0000000000000000000000000000000000000000..164d3080a3148b8db93180c2eb98d7339f29d597 GIT binary patch literal 910 zcmex=vd68JL)XenbLn zOw25-|8Fty0L7UEm<1RZ7_Uggt^0Z|#p5bFNQ(diGY}#HW)^lvHUXd(4p5M>GU=I3 z4w0Pee>Z(TP`R`q12a$Z zkvzyE21XWyO+b$@vNN!<2?_`)f-PeLS;oN1py{9;b;L27@c?T>`V|M3T8@ssG>&I! zY3XbJyz=vT(xEy_qLTfbQkUjsmBN!x=l;q}nO54BJ}dKbg;wQ-1+1!Cj8W5+7?hM} zeg=6E7#`qQgNFzx0NEG?grFh9X3rFE-@Pj0PPpaC!e3=ipNp|1{@x$HeTr&~S)ufn z+oGAzK7WqssIv3EGoy8iLutr;R+Gql?&IO9`MIXo{f)bRWiEZ@TPtF_Q8?ziNoQ|1 zM{k=;THN$~zrO>m7Xw8HDqw`ig}tKa_36y^t-njlT+`REt$)Sk4|EhbX2H4yO89|B zhzbHD2n9e*07Z^~_kv?PA7;zAq&qm8R_%0jTD2M!+G0RGsG1lVAl8BcS-?)-YsG{@ xbp|HsC$o0EN;ZFa9%PRInid8|1!x!nwG_XSbITT+k#_2-P~Be^{s#H~Hvw*O+c*FK literal 0 HcmV?d00001 diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_past_end.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_past_end.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7e2451e6f9d5078aba50c989583b8647d5d8ca09 GIT binary patch literal 910 zcmex=a010885x+Efqp~+ zY)s57tp9H@@Bqb`1egUF7#Oce#I5^!F2&<2J4lNF12YgJ0cI9wh9d*PpoACf^L;4j5mRgREzBG!e-ADZr{Bs;!e2b$--Y{PoImiB>vtXzI}>nj9H=d zmfND4&pv;S>8P^vzB8kBibHA0eO8mmeD34nsrk94*ZqyVeq}Cw=36UbyHPmiyGdtn zHb-xpOIqCYeZRj0trr7D2P$BM$A!J3==JH$_N~85%Usjfu&sZ^0CtV7wv`x9;n?6pyRy zAT0t6%s_|)m|55v*#v-EI6wi-%A{vDIYe@<|K0TYK;_bc49q}bBn^yAEX;}w0)k)- zKskHHb-UKDn!RpWciy(%)tgRzyEJR{s$S_V&1JnazuoKoT6R5mYx!kg*||4oOn%s9 zraH@W=8Q>aZlpwZzEqj|%hOin%lvwvMe-nv7#LX)HUT}t$j-pZCMY1J2)2v~WElf1 zgQkOa)Dg#Q#sjPk=~oOVo*|^`5ELvV0eII4IUz(0Aynn5Q2sXn>|ywefO$} zJK>fm3xAb8eJ;k5_@;!M&X$6CY`<69KCHWX>rr{{r(QLUJMi+sDKe37xs#x*QYbv zxBf0Ib4_2vw*D2DKhRO&m<8(+DB%YhAu0%rAQS*K0Tej`-V2WHe3&iclJ4MWTD8;B zY1L{_Xo~^$plV`dfLIF(WC1&QuN4yt)ft$ipUm3vD%t$yd5}E=2{JMZGX6ipAO`jh#LWN! z5@2IuW?}t*i-89y&LqGrz`($GMIvt9*K;WzSJ^>Y1Q?is5D74|ursm=0JU&{f{c|( z&unstGOfgr3D$7fx<`{7@1g@6&VBs!5V;a_KfRxtzR{J-LmeyZM~~Eo%(iZ z*6LNg(pj3zdS`yS*ZZ~XdhXWp%f7O6Z_b$fu**z!mgmeFlg`{oiR^r-GWD0It;(1A z^+1c{K^8GEvLI{%dW4akft5{AKu8g68577d237`52kodMj@gU{SR2x>IIz@mbo8Zh zJWESUU-RdcpU;yH)maji?B|raG%u?Zo_sp@S7yqz(ysJbnU^cHDlaTxRn=mQnx@2{ zq&)L8$b-P}0LL0UL_h(^#wZ{J4G}hbrf~c2RS|c>El(EyDtr1|j3x2+{_yQnRAbBv zrMKJ`&3yLxb4*8-o%fv?ty3IIL+-PhMCNlJ4^Pd{HNEa{-1RGS=`-J25!;QzG2cx( zd$T!u+g#G(rtkax9caB6C^}F9BRnqb6-BR4XSQ$sU0UXvzJ_i6D=vSaqrfo>)+JEF z4>Uql5Ewxy0BQm#as<2=9NYOYTgD~b!O^s8r=!!V)u7N81L{H5#K-`#78J+=cJf{; zCKReOFiAg|wc}N?`OEVldj!z5Ffb}W!w9IQ_?4Vnw%ClcQ%{BJ{<82l$p60y05=QW AHUIzs literal 0 HcmV?d00001 diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 85d258de5b..26772d5655 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -183,7 +183,8 @@ private slots: void exifOrientation(); void exif_QTBUG45865(); - void exif_invalid_data_QTBUG46870(); + void exifInvalidData_data(); + void exifInvalidData(); void cleanupFunctions(); @@ -3028,10 +3029,20 @@ void tst_QImage::exif_QTBUG45865() QCOMPARE(image.size(), QSize(5, 8)); } -void tst_QImage::exif_invalid_data_QTBUG46870() +void tst_QImage::exifInvalidData_data() +{ + QTest::addColumn("$never used"); + QTest::newRow("QTBUG-46870"); + QTest::newRow("back_pointers"); + QTest::newRow("past_end"); + QTest::newRow("too_many_ifds"); + QTest::newRow("too_many_tags"); +} + +void tst_QImage::exifInvalidData() { QImage image; - QVERIFY(image.load(m_prefix + "jpeg_exif_invalid_data_QTBUG-46870.jpg")); + QVERIFY(image.load(m_prefix + "jpeg_exif_invalid_data_" + QTest::currentDataTag() + ".jpg")); QVERIFY(!image.isNull()); } From f4a33e345eb658996e171daa6478fdc2ef62ff17 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 22 Nov 2016 13:59:35 +0100 Subject: [PATCH 12/74] Fix compilation on platforms that don't support printing Task-number: QTBUG-56259 Change-Id: Ice1d7601494b01b387e787da412cd94b6717ebde Reviewed-by: Simon Hausmann --- examples/widgets/painting/fontsampler/mainwindow.cpp | 6 ++++-- examples/widgets/painting/fontsampler/mainwindow.h | 10 ++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/examples/widgets/painting/fontsampler/mainwindow.cpp b/examples/widgets/painting/fontsampler/mainwindow.cpp index 06ffac3728..88b23d5cfb 100644 --- a/examples/widgets/painting/fontsampler/mainwindow.cpp +++ b/examples/widgets/painting/fontsampler/mainwindow.cpp @@ -49,7 +49,9 @@ ****************************************************************************/ #include +#if defined(QT_PRINTSUPPORT_LIB) #include +#endif #include "mainwindow.h" @@ -210,7 +212,7 @@ QMap MainWindow::currentPageMap() return pageMap; } -#if !defined(QT_NO_PRINTER) && !defined(QT_NO_PRINTDIALOG) +#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printdialog) void MainWindow::on_printAction_triggered() { pageMap = currentPageMap(); @@ -342,4 +344,4 @@ void MainWindow::printPage(int index, QPainter *painter, QPrinter *printer) painter->restore(); } -#endif // QT_NO_PRINTER +#endif diff --git a/examples/widgets/painting/fontsampler/mainwindow.h b/examples/widgets/painting/fontsampler/mainwindow.h index ada0d47354..21e76f1a62 100644 --- a/examples/widgets/painting/fontsampler/mainwindow.h +++ b/examples/widgets/painting/fontsampler/mainwindow.h @@ -55,6 +55,9 @@ #include #include +#if defined(QT_PRINTSUPPORT_LIB) +#include +#endif QT_BEGIN_NAMESPACE class QPrinter; class QTextEdit; @@ -74,12 +77,11 @@ public: public slots: void on_clearAction_triggered(); void on_markAction_triggered(); -#if !defined(QT_NO_PRINTER) && !defined(QT_NO_PRINTDIALOG) + void on_unmarkAction_triggered(); + +#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printdialog) void on_printAction_triggered(); void on_printPreviewAction_triggered(); -#endif - void on_unmarkAction_triggered(); -#if !defined(QT_NO_PRINTER) && !defined(QT_NO_PRINTDIALOG) void printDocument(QPrinter *printer); void printPage(int index, QPainter *painter, QPrinter *printer); #endif From 048447346bc1b78992be3ce4bf3292fc272f7e1a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 8 Sep 2016 10:10:12 +0200 Subject: [PATCH 13/74] QPointerUniqueId: make fit for release - Declare as Q_MOVABLE_TYPE - Prevent QList from being instantiated (use QVector instead) - Add equality relational operators - Add qHash() overload - Replace non-default ctor with named ctor. - Add Q_DECL_NOTHROW. - Add Q_DECL_CONSTEXPR. - Rename numeric() -> numericId(). - Update docs. The extension vector for this class calls for additional properties to be added later, but these are not user- settable. It thus suffices to rely on the only data member, a qint64, which can be reinterpreted to an index into an array or hash with actual objects. This allows to make the class a Trivial Type (ie. no overhead over an int) while still supporting later extension. Cf. QSslEllipticCurve as another example of such a class. The extension has to maintain the following invariants, encoded into user code by way of being used in inline functions: - m_numericId == -1 <=> !isValid() This is trivial to support. An extension could not and still cannot reinterpret the qint64 member as a d-pointer, but a d-pointer is only necessary for user-settable properties where updating a central private data structure would cause too much contention. Add a test. Since this type is used in other modules, keep the existing functions, but mark them as deprecated with the expectation that these compat functions be removed before 5.8.0 final. Task-number: QTBUG-54616 Change-Id: Ia3ede0ecaeeef4cd3ffa94a72b1050bd409713a5 Reviewed-by: Shawn Rutledge --- src/gui/kernel/qevent.cpp | 82 +++++++++++++++++-- src/gui/kernel/qevent.h | 36 ++++++-- .../kernel/qtouchevent/tst_qtouchevent.cpp | 39 +++++++++ 3 files changed, 142 insertions(+), 15 deletions(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 254b8926c8..72cd374419 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -44,6 +44,7 @@ #include "qpa/qplatformdrag.h" #include "private/qevent_p.h" #include "qfile.h" +#include "qhashfunctions.h" #include "qmetaobject.h" #include "qmimedata.h" #include "private/qdnd_p.h" @@ -4474,7 +4475,7 @@ int QTouchEvent::TouchPoint::id() const \since 5.8 Returns the unique ID of this touch point or token, if any. - It is normally invalid (with a \l {QPointerUniqueId::numeric()} {numeric()} value of -1), + It is normally invalid (see \l {QPointerUniqueId::isValid()} {isValid()}), because touchscreens cannot uniquely identify fingers. But when the \l {TouchPoint::InfoFlag} {Token} flag is set, it is expected to uniquely identify a specific token (fiducial object). @@ -4757,7 +4758,7 @@ void QTouchEvent::TouchPoint::setUniqueId(qint64 uid) { if (d->ref.load() != 1) d = d->detach(); - d->uniqueId = QPointerUniqueId(uid); + d->uniqueId = QPointerUniqueId::fromNumericId(uid); } /*! \internal */ @@ -5184,28 +5185,91 @@ Qt::ApplicationState QApplicationStateChangeEvent::applicationState() const \brief QPointerUniqueId identifies a unique object, such as a tagged token or stylus, which is used with a pointing device. + QPointerUniqueIds can be compared for equality, and can be used as keys in a QHash. + You get access to the numerical ID via numericId(), if the device supports such IDs. + For future extensions, though, you should not use that function, but compare objects + of this type using the equality operator. + + This class is a thin wrapper around an integer ID. You pass it into and out of + functions by value. + + This type actively prevents you from holding it in a QList, because doing so would + be very inefficient. Use a QVector instead, which has the same API as QList, but more + efficient storage. + \sa QTouchEvent::TouchPoint */ /*! - Constructs a unique pointer ID with a numeric \a id provided by the hardware. - The default is -1, which means an invalid pointer ID. + \fn QPointerUniqueId::QPointerUniqueId() + Constructs an invalid unique pointer ID. */ -QPointerUniqueId::QPointerUniqueId(qint64 id) - : m_numericId(id) + +/*! + Constructs a unique pointer ID from numeric ID \a id. +*/ +QPointerUniqueId QPointerUniqueId::fromNumericId(qint64 id) { + QPointerUniqueId result; + result.m_numericId = id; + return result; } /*! - \property QPointerUniqueId::numeric + \fn bool QPointerUniqueId::isValid() + + Returns whether this unique pointer ID is valid, that is, it represents an actual + pointer. +*/ + +/*! + \property QPointerUniqueId::numericId \brief the numeric unique ID of the token represented by a touchpoint - This is the numeric unique ID if the device provides that type of ID; + If the device provides a numeric ID, isValid() returns true, and this + property provides the numeric ID; otherwise it is -1. + + You should not use the value of this property in portable code, but + instead rely on equality to identify pointers. + + \sa isValid() */ -qint64 QPointerUniqueId::numeric() const +qint64 QPointerUniqueId::numericId() const Q_DECL_NOTHROW { return m_numericId; } +/*! + \relates QPointerUniqueId + \since 5.8 + + Returns whether the two unique pointer IDs \a lhs and \a rhs identify the same pointer + (\c true) or not (\c false). +*/ +bool operator==(QPointerUniqueId lhs, QPointerUniqueId rhs) Q_DECL_NOTHROW +{ + return lhs.numericId() == rhs.numericId(); +} + +/*! + \fn bool operator!=(QPointerUniqueId lhs, QPointerUniqueId rhs) + \relates QPointerUniqueId + \since 5.8 + + Returns whether the two unique pointer IDs \a lhs and \a rhs identify different pointers + (\c true) or not (\c false). +*/ + +/*! + \relates QPointerUniqueId + \since 5.8 + + Returns the hash value for \a key, using \a seed to seed the calculation. +*/ +uint qHash(QPointerUniqueId key, uint seed) Q_DECL_NOTHROW +{ + return qHash(key.numericId(), seed); +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index a062331bd8..b7c0f3338e 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -793,21 +793,45 @@ inline bool operator==(QKeyEvent *e, QKeySequence::StandardKey key){return (e ? inline bool operator==(QKeySequence::StandardKey key, QKeyEvent *e){return (e ? e->matches(key) : false);} #endif // QT_NO_SHORTCUT -class QPointerUniqueIdPrivate; class Q_GUI_EXPORT QPointerUniqueId { Q_GADGET - Q_PROPERTY(qint64 numeric READ numeric CONSTANT) + // ### kept these to keep other modules compiling. Remove before 5.8.0 final! +#if QT_DEPRECATED_SINCE(5, 8) + Q_PROPERTY(qint64 numeric READ numericId CONSTANT) +#endif + Q_PROPERTY(qint64 numericId READ numericId CONSTANT) public: - explicit QPointerUniqueId(qint64 id = -1); + Q_ALWAYS_INLINE + Q_DECL_CONSTEXPR QPointerUniqueId() Q_DECL_NOTHROW : m_numericId(-1) {} + // compiler-generated copy/move ctor/assignment operators are ok! + // compiler-generated dtor is ok! - qint64 numeric() const; + static QPointerUniqueId fromNumericId(qint64 id); + Q_ALWAYS_INLINE Q_DECL_CONSTEXPR bool isValid() const Q_DECL_NOTHROW { return m_numericId != -1; } + qint64 numericId() const Q_DECL_NOTHROW; + + // ### kept these to keep other modules compiling. Remove before 5.8.0 final! +#if QT_DEPRECATED_SINCE(5, 8) + Q_ALWAYS_INLINE Q_DECL_DEPRECATED qint64 numeric() const { return numericId(); } + Q_ALWAYS_INLINE Q_DECL_DEPRECATED explicit QPointerUniqueId(qint64 id) : m_numericId(id) {} +#endif private: - // TODO for TUIO 2, or any other type of complex token ID, a d-pointer can replace - // m_numericId without changing the size of this class. + // TODO: for TUIO 2, or any other type of complex token ID, an internal + // array (or hash) can be added to hold additional properties. + // In this case, m_numericId will then turn into an index into that array (or hash). qint64 m_numericId; }; +Q_DECLARE_TYPEINFO(QPointerUniqueId, Q_MOVABLE_TYPE); +template <> class QList {}; // to prevent instantiation: use QVector instead + +Q_GUI_EXPORT bool operator==(QPointerUniqueId lhs, QPointerUniqueId rhs) Q_DECL_NOTHROW; +inline bool operator!=(QPointerUniqueId lhs, QPointerUniqueId rhs) Q_DECL_NOTHROW +{ return !operator==(lhs, rhs); } +Q_GUI_EXPORT uint qHash(QPointerUniqueId key, uint seed = 0) Q_DECL_NOTHROW; + + class QTouchEventTouchPointPrivate; class Q_GUI_EXPORT QTouchEvent : public QInputEvent diff --git a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp index e6fd67e3a8..02814b48e9 100644 --- a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp @@ -194,6 +194,7 @@ public: private slots: void cleanup(); + void qPointerUniqueId(); void touchDisabledByDefault(); void touchEventAcceptedByDefault(); void touchBeginPropagatesWhenIgnored(); @@ -224,6 +225,44 @@ void tst_QTouchEvent::cleanup() QVERIFY(QGuiApplication::topLevelWindows().isEmpty()); } +void tst_QTouchEvent::qPointerUniqueId() +{ + QPointerUniqueId id1, id2; + + QCOMPARE(id1.numericId(), Q_INT64_C(-1)); + QVERIFY(!id1.isValid()); + + QVERIFY( id1 == id2); + QVERIFY(!(id1 != id2)); + + QSet set; // compile test + set.insert(id1); + set.insert(id2); + QCOMPARE(set.size(), 1); + + + const auto id3 = QPointerUniqueId::fromNumericId(-1); + QCOMPARE(id3.numericId(), Q_INT64_C(-1)); + QVERIFY(!id3.isValid()); + + QVERIFY( id1 == id3); + QVERIFY(!(id1 != id3)); + + set.insert(id3); + QCOMPARE(set.size(), 1); + + + const auto id4 = QPointerUniqueId::fromNumericId(4); + QCOMPARE(id4.numericId(), Q_INT64_C(4)); + QVERIFY(id4.isValid()); + + QVERIFY( id1 != id4); + QVERIFY(!(id1 == id4)); + + set.insert(id4); + QCOMPARE(set.size(), 2); +} + void tst_QTouchEvent::touchDisabledByDefault() { // QWidget From 1658bcb1047ab04d500683f94ecda74bf660d2af Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Fri, 2 Dec 2016 09:51:52 +0100 Subject: [PATCH 14/74] qdoc: Ignore Q_ALWAYS_INLINE and QT_HAS_INCLUDE() Number of API changes in Qt 5.8 use these macros and QDoc needs to ignore them the correctly match the documentation to the function signatures. Task-number: QTBUG-57424 Change-Id: I0c3a0eb4deb2d9b348f24800591bc6f6b47cf458 Reviewed-by: Martin Smith Reviewed-by: Marc Mutz --- doc/global/qt-cpp-defines.qdocconf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/global/qt-cpp-defines.qdocconf b/doc/global/qt-cpp-defines.qdocconf index fe8b7fb87e..4aa9111853 100644 --- a/doc/global/qt-cpp-defines.qdocconf +++ b/doc/global/qt-cpp-defines.qdocconf @@ -20,6 +20,7 @@ defines += Q_QDOC \ Cpp.ignoretokens += \ ENGINIOCLIENT_EXPORT \ PHONON_EXPORT \ + Q_ALWAYS_INLINE \ Q_AUTOTEST_EXPORT \ Q_BLUETOOTH_EXPORT \ Q_COMPAT_EXPORT \ @@ -150,6 +151,7 @@ Cpp.ignoredirectives += \ Q_ENUMS \ Q_FLAG \ Q_FLAGS \ + QT_HAS_INCLUDE \ Q_INTERFACES \ Q_PRIVATE_PROPERTY \ QT_FORWARD_DECLARE_CLASS \ From 32a7efe22527d6c1fccd8f9a2b817e4ed4b0168c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 2 Dec 2016 21:24:44 -0800 Subject: [PATCH 15/74] Fix the warning number for ICC deprecated warnings That's what happens when you don't test and just rely on an the warning listing. ICC has two warning numbers for deprecated warnings: one that matches Q_DECL_DEPRECATED and one for Q_DECL_DEPRECATED_X. Change-Id: I73fa1e59a4844c43a109fffd148ca7a05eda8f13 Reviewed-by: Marc Mutz --- src/corelib/global/qcompilerdetection.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index d978c141a4..4142c17b42 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -1273,7 +1273,7 @@ # define QT_WARNING_DISABLE_INTEL(number) __pragma(warning(disable: number)) # define QT_WARNING_DISABLE_CLANG(text) # define QT_WARNING_DISABLE_GCC(text) -# define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_INTEL(1786) +# define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_INTEL(1478 1786) #elif defined(Q_CC_INTEL) /* icc: Intel compiler on Linux or OS X */ # define QT_WARNING_PUSH QT_DO_PRAGMA(warning(push)) @@ -1282,7 +1282,7 @@ # define QT_WARNING_DISABLE_MSVC(number) # define QT_WARNING_DISABLE_CLANG(text) # define QT_WARNING_DISABLE_GCC(text) -# define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_INTEL(1786) +# define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_INTEL(1478 1786) #elif defined(Q_CC_MSVC) && _MSC_VER >= 1500 && !defined(Q_CC_CLANG) # undef QT_DO_PRAGMA /* not needed */ # define QT_WARNING_PUSH __pragma(warning(push)) From 6ae9dc3f379728a1aaee818a169c03954d6a445c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 2 Dec 2016 20:24:11 -0800 Subject: [PATCH 16/74] Work around ICC compiler bug on template instantiation on ?: It doesn't like the access to the template instantiation in the ternary operator. error: operand types are incompatible ("FetchPixelFunc" and "") Intel-Issue-ID: 6000164201 Change-Id: I73fa1e59a4844c43a109fffd148ca452796eebb1 Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Marc Mutz --- src/gui/painting/qdrawhelper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 656b04fdf3..e1875d84b9 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1572,7 +1572,7 @@ static const uint *QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, if (bpp != QPixelLayout::BPPNone) // Like this to not ICE on GCC 5.3.1 Q_ASSERT(layout->bpp == bpp); // When templated 'fetch' should be inlined at compile time: - const FetchPixelFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : fetchPixel; + const FetchPixelFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : FetchPixelFunc(fetchPixel); uint *const end = buffer + length; uint *b = buffer; @@ -2519,8 +2519,8 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper if (bpp != QPixelLayout::BPPNone) // Like this to not ICE on GCC 5.3.1 Q_ASSERT(layout->bpp == bpp); // When templated 'fetch' should be inlined at compile time: - const FetchPixelsFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixels[layout->bpp] : fetchPixels; - const FetchPixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : fetchPixel; + const FetchPixelsFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixels[layout->bpp] : FetchPixelsFunc(fetchPixels); + const FetchPixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : FetchPixelFunc(fetchPixel); int image_width = data->texture.width; int image_height = data->texture.height; From 4f959b6b3004ecbd0d34b34f613ce9980ba42b55 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 28 Nov 2016 16:02:26 +0100 Subject: [PATCH 17/74] ~QHttpNetworkConnectionPrivate - disconnect from socket's signals We have a 'channel' object connected to a socket with Qt::DirectConnection. QHttpNetworkConnectionPrivate in its dtor (note, it's a private object destroyed after its 'q' - QHttpNetworkConnection - was destroyed) calls socket->close() and this can end up in socket setting an error and emitting (for example, in QSslSocket::transmit). The slot (QHttpNetworkConnectionChannel::_q_error) will access the now-dead/non-existing connection then. So disconnect the channel from the socket early, before closing the socket. Task-number: QTBUG-54167 Change-Id: I3ed4ba4b00650c3a39e5c1f33aa786e47bfbbc57 Reviewed-by: Konstantin Tokarev Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne Reviewed-by: Marc Mutz --- src/network/access/qhttpnetworkconnection.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 7f07403a73..1b1ecff21e 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -116,6 +116,7 @@ QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate() { for (int i = 0; i < channelCount; ++i) { if (channels[i].socket) { + QObject::disconnect(channels[i].socket, Q_NULLPTR, &channels[i], Q_NULLPTR); channels[i].socket->close(); delete channels[i].socket; } From 14ea8759da0d5eb1888664a5b0d08c2bf142a6a2 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 30 Nov 2016 15:32:02 +0100 Subject: [PATCH 18/74] winrt: Change the way tcp packets are handled Similar to the way datagrams are handled for udp sockets the worker now takes care of tcp data. Thus we avoid race conditions which stopped data processing. It could happen that data was read from the socket into the buffer and before readyRead was emitted the buffer was completely read. In this case readNotification is set to false and no new data is processed afterwards. Additionally the buffer was replaced by a vector of QByteArray. The buffer kept growing and was never cleared (and there is no obvious way for clearing the buffer), so that an overflow happened eventually. pendingReadOperations (and its mutex) could be removed as well. There is only one situation where they could clash and that's the initial read. Having two members is preferred over having a list of operations and a mutex. Task-number: QTBUG-56438 Change-Id: Idbad58e47785996023748c310530892163f24594 Reviewed-by: Maurice Kalinowski --- .../socket/qnativesocketengine_winrt.cpp | 456 +++++++++++------- .../socket/qnativesocketengine_winrt_p.h | 16 +- 2 files changed, 280 insertions(+), 192 deletions(-) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 8257eec9ea..8b36406c67 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -126,6 +126,33 @@ static HRESULT qt_winrt_try_create_thread_network_context(QString host, ComPtr= 1900 +typedef QHash TcpSocketHash; + +struct SocketHandler +{ + SocketHandler() : socketCount(0) {} + qintptr socketCount; + TcpSocketHash pendingTcpSockets; +}; + +Q_GLOBAL_STATIC(SocketHandler, gSocketHandler) + +struct SocketGlobal +{ + SocketGlobal() + { + HRESULT hr; + hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(), + &bufferFactory); + Q_ASSERT_SUCCEEDED(hr); + } + + ComPtr bufferFactory; +}; +Q_GLOBAL_STATIC(SocketGlobal, g) + +#define READ_BUFFER_SIZE 65536 + static inline QString qt_QStringFromHString(const HString &string) { UINT32 length; @@ -136,8 +163,43 @@ static inline QString qt_QStringFromHString(const HString &string) class SocketEngineWorker : public QObject { Q_OBJECT +public: + SocketEngineWorker(QNativeSocketEnginePrivate *engine) + : enginePrivate(engine) + { + } + + ~SocketEngineWorker() + { + if (Q_UNLIKELY(initialReadOp)) { + ComPtr info; + HRESULT hr = initialReadOp.As(&info); + Q_ASSERT_SUCCEEDED(hr); + if (info) { + hr = info->Cancel(); + Q_ASSERT_SUCCEEDED(hr); + hr = info->Close(); + Q_ASSERT_SUCCEEDED(hr); + } + } + + if (readOp) { + ComPtr info; + HRESULT hr = readOp.As(&info); + Q_ASSERT_SUCCEEDED(hr); + if (info) { + hr = info->Cancel(); + Q_ASSERT_SUCCEEDED(hr); + hr = info->Close(); + Q_ASSERT_SUCCEEDED(hr); + } + } + } + signals: void newDatagramsReceived(const QList &datagram); + void newDataReceived(const QVector &data); + void socketErrorOccured(QAbstractSocket::SocketError error); public slots: Q_INVOKABLE void notifyAboutNewDatagrams() @@ -148,7 +210,30 @@ public slots: emit newDatagramsReceived(datagrams); } + Q_INVOKABLE void notifyAboutNewData() + { + QMutexLocker locker(&mutex); + const QVector newData = std::move(pendingData); + pendingData.clear(); + emit newDataReceived(newData); + } + public: + void startReading() + { + ComPtr buffer; + HRESULT hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer); + Q_ASSERT_SUCCEEDED(hr); + ComPtr stream; + hr = tcpSocket->get_InputStream(&stream); + Q_ASSERT_SUCCEEDED(hr); + hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, initialReadOp.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); + enginePrivate->socketState = QAbstractSocket::ConnectedState; + hr = initialReadOp->put_Completed(Callback(this, &SocketEngineWorker::onReadyRead).Get()); + Q_ASSERT_SUCCEEDED(hr); + } + HRESULT OnNewDatagramReceived(IDatagramSocket *, IDatagramSocketMessageReceivedEventArgs *args) { WinRtDatagram datagram; @@ -184,9 +269,127 @@ public: return S_OK; } + HRESULT onReadyRead(IAsyncBufferOperation *asyncInfo, AsyncStatus status) + { + if (asyncInfo == initialReadOp.Get()) { + initialReadOp.Reset(); + } else if (asyncInfo == readOp.Get()) { + readOp.Reset(); + } else { + Q_ASSERT(false); + } + + // A read in UnconnectedState will close the socket and return -1 and thus tell the caller, + // that the connection was closed. The socket cannot be closed here, as the subsequent read + // might fail then. + if (status == Error || status == Canceled) { + emit socketErrorOccured(QAbstractSocket::RemoteHostClosedError); + return S_OK; + } + + ComPtr buffer; + HRESULT hr = asyncInfo->GetResults(&buffer); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get read results buffer"); + emit socketErrorOccured(QAbstractSocket::UnknownSocketError); + return S_OK; + } + + UINT32 bufferLength; + hr = buffer->get_Length(&bufferLength); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get buffer length"); + emit socketErrorOccured(QAbstractSocket::UnknownSocketError); + return S_OK; + } + // A zero sized buffer length signals, that the remote host closed the connection. The socket + // cannot be closed though, as the following read might have socket descriptor -1 and thus and + // the closing of the socket won't be communicated to the caller. So only the error is set. The + // actual socket close happens inside of read. + if (!bufferLength) { + emit socketErrorOccured(QAbstractSocket::RemoteHostClosedError); + return S_OK; + } + + ComPtr byteArrayAccess; + hr = buffer.As(&byteArrayAccess); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get cast buffer"); + emit socketErrorOccured(QAbstractSocket::UnknownSocketError); + return S_OK; + } + byte *data; + hr = byteArrayAccess->Buffer(&data); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to access buffer data"); + emit socketErrorOccured(QAbstractSocket::UnknownSocketError); + return S_OK; + } + + QByteArray newData(reinterpret_cast(data), qint64(bufferLength)); + QMutexLocker readLocker(&mutex); + if (pendingData.isEmpty()) + QMetaObject::invokeMethod(this, "notifyAboutNewData", Qt::QueuedConnection); + pendingData << newData; + readLocker.unlock(); + + hr = QEventDispatcherWinRT::runOnXamlThread([buffer, this]() { + UINT32 readBufferLength; + ComPtr stream; + HRESULT hr = tcpSocket->get_InputStream(&stream); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to obtain input stream"); + emit socketErrorOccured(QAbstractSocket::UnknownSocketError); + return S_OK; + } + + // Reuse the stream buffer + hr = buffer->get_Capacity(&readBufferLength); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get buffer capacity"); + emit socketErrorOccured(QAbstractSocket::UnknownSocketError); + return S_OK; + } + hr = buffer->put_Length(0); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to set buffer length"); + emit socketErrorOccured(QAbstractSocket::UnknownSocketError); + return S_OK; + } + + hr = stream->ReadAsync(buffer.Get(), readBufferLength, InputStreamOptions_Partial, &readOp); + if (FAILED(hr)) { + qErrnoWarning(hr, "onReadyRead(): Could not read into socket stream buffer."); + emit socketErrorOccured(QAbstractSocket::UnknownSocketError); + return S_OK; + } + hr = readOp->put_Completed(Callback(this, &SocketEngineWorker::onReadyRead).Get()); + if (FAILED(hr)) { + qErrnoWarning(hr, "onReadyRead(): Failed to set socket read callback."); + emit socketErrorOccured(QAbstractSocket::UnknownSocketError); + return S_OK; + } + return S_OK; + }); + Q_ASSERT_SUCCEEDED(hr); + return S_OK; + } + + void setTcpSocket(ComPtr socket) { tcpSocket = socket; } + private: + ComPtr tcpSocket; + QList pendingDatagrams; + QVector pendingData; + + // Protects pendingData/pendingDatagrams which are accessed from native callbacks QMutex mutex; + + ComPtr> initialReadOp; + ComPtr> readOp; + + QNativeSocketEnginePrivate *enginePrivate; }; static QByteArray socketDescription(const QAbstractSocketEngine *s) @@ -239,33 +442,6 @@ static QByteArray socketDescription(const QAbstractSocketEngine *s) } } while (0) #define Q_TR(a) QT_TRANSLATE_NOOP(QNativeSocketEngine, a) -typedef QHash TcpSocketHash; - -struct SocketHandler -{ - SocketHandler() : socketCount(0) {} - qintptr socketCount; - TcpSocketHash pendingTcpSockets; -}; - -Q_GLOBAL_STATIC(SocketHandler, gSocketHandler) - -struct SocketGlobal -{ - SocketGlobal() - { - HRESULT hr; - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(), - &bufferFactory); - Q_ASSERT_SUCCEEDED(hr); - } - - ComPtr bufferFactory; -}; -Q_GLOBAL_STATIC(SocketGlobal, g) - -#define READ_BUFFER_SIZE 65536 - template static AsyncStatus opStatus(const ComPtr &op) { @@ -315,6 +491,10 @@ QNativeSocketEngine::QNativeSocketEngine(QObject *parent) connect(this, SIGNAL(readReady()), SLOT(readNotification()), Qt::QueuedConnection); connect(this, SIGNAL(writeReady()), SLOT(writeNotification()), Qt::QueuedConnection); connect(d->worker, &SocketEngineWorker::newDatagramsReceived, this, &QNativeSocketEngine::handleNewDatagrams, Qt::QueuedConnection); + connect(d->worker, &SocketEngineWorker::newDataReceived, + this, &QNativeSocketEngine::handleNewData, Qt::QueuedConnection); + connect(d->worker, &SocketEngineWorker::socketErrorOccured, + this, &QNativeSocketEngine::handleTcpError, Qt::QueuedConnection); } QNativeSocketEngine::~QNativeSocketEngine() @@ -358,23 +538,9 @@ bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket:: // Start processing incoming data if (d->socketType == QAbstractSocket::TcpSocket) { - HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([d, socket, socketState, this]() { - ComPtr buffer; - HRESULT hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer); - RETURN_HR_IF_FAILED("initialize(): Could not create buffer"); - ComPtr stream; - hr = socket->get_InputStream(&stream); - RETURN_HR_IF_FAILED("initialize(): Could not obtain input stream"); - ComPtr readOp; - hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, readOp.GetAddressOf()); - RETURN_HR_IF_FAILED_WITH_ARGS("initialize(): Failed to read from the socket buffer (%s).", - socketDescription(this).constData()); - QMutexLocker locker(&d->readOperationsMutex); - d->pendingReadOps.append(readOp); - d->socketState = socketState; - hr = readOp->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); - RETURN_HR_IF_FAILED_WITH_ARGS("initialize(): Failed to set socket read callback (%s).", - socketDescription(this).constData()); + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([d, socket, this]() { + d->worker->setTcpSocket(socket); + d->worker->startReading(); return S_OK; }); if (FAILED(hr)) @@ -639,20 +805,6 @@ void QNativeSocketEngine::close() } #endif // _MSC_VER >= 1900 - QMutexLocker locker(&d->readOperationsMutex); - for (ComPtr readOp : d->pendingReadOps) { - ComPtr info; - hr = readOp.As(&info); - Q_ASSERT_SUCCEEDED(hr); - if (info) { - hr = info->Cancel(); - Q_ASSERT_SUCCEEDED(hr); - hr = info->Close(); - Q_ASSERT_SUCCEEDED(hr); - } - } - locker.unlock(); - if (d->socketDescriptor != -1) { ComPtr socket; if (d->socketType == QAbstractSocket::TcpSocket) { @@ -730,14 +882,32 @@ qint64 QNativeSocketEngine::read(char *data, qint64 maxlen) // happens and there isn't anything left in the buffer, we have to return -1 in order to signal // the closing of the socket. QMutexLocker mutexLocker(&d->readMutex); - if (d->readBytes.pos() == d->readBytes.size() && d->socketState != QAbstractSocket::ConnectedState) { + if (d->pendingData.isEmpty() && d->socketState != QAbstractSocket::ConnectedState) { close(); return -1; } - qint64 b = d->readBytes.read(data, maxlen); - d->bytesAvailable = d->readBytes.size() - d->readBytes.pos(); - return b; + QByteArray readData; + qint64 leftToMaxLen = maxlen; + while (leftToMaxLen > 0 && !d->pendingData.isEmpty()) { + QByteArray pendingData = d->pendingData.takeFirst(); + // Do not read the whole data. Put the rest of it back into the "queue" + if (leftToMaxLen < pendingData.length()) { + readData += pendingData.left(leftToMaxLen); + pendingData = pendingData.remove(0, maxlen); + d->pendingData.prepend(pendingData); + break; + } else { + readData += pendingData; + leftToMaxLen -= pendingData.length(); + } + } + const int copyLength = qMin(maxlen, qint64(readData.length())); + d->bytesAvailable -= copyLength; + mutexLocker.unlock(); + + memcpy(data, readData, copyLength); + return copyLength; } qint64 QNativeSocketEngine::write(const char *data, qint64 len) @@ -913,7 +1083,7 @@ bool QNativeSocketEngine::waitForRead(int msecs, bool *timedOut) // If we are a client, we are ready to read if our buffer has data QMutexLocker locker(&d->readMutex); - if (!d->readBytes.atEnd()) + if (!d->pendingData.isEmpty()) return true; // Nothing to do, wait for more events @@ -1001,21 +1171,8 @@ void QNativeSocketEngine::establishRead() HRESULT hr; hr = QEventDispatcherWinRT::runOnXamlThread([d]() { - ComPtr stream; - HRESULT hr = d->tcpSocket()->get_InputStream(&stream); - RETURN_HR_IF_FAILED("establishRead(): Failed to get socket input stream"); - - ComPtr buffer; - hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer); - RETURN_HR_IF_FAILED("establishRead(): Failed to create buffer"); - - ComPtr readOp; - hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, readOp.GetAddressOf()); - RETURN_HR_IF_FAILED("establishRead(): Failed to initiate socket read"); - QMutexLocker locker(&d->readOperationsMutex); - d->pendingReadOps.append(readOp); - hr = readOp->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); - RETURN_HR_IF_FAILED("establishRead(): Failed to register read callback"); + d->worker->setTcpSocket(d->tcpSocket()); + d->worker->startReading(); return S_OK; }); Q_ASSERT_SUCCEEDED(hr); @@ -1032,6 +1189,32 @@ void QNativeSocketEngine::handleNewDatagrams(const QList &datagra emit readReady(); } +void QNativeSocketEngine::handleNewData(const QVector &data) +{ + // Defer putting the data into the list until the next event loop iteration + // (where the readyRead signal is emitted as well) + QMetaObject::invokeMethod(this, "putIntoPendingData", Qt::QueuedConnection, + Q_ARG(QVector, data)); +} + +void QNativeSocketEngine::handleTcpError(QAbstractSocket::SocketError error) +{ + Q_D(QNativeSocketEngine); + QNativeSocketEnginePrivate::ErrorString errorString; + switch (error) { + case QAbstractSocket::RemoteHostClosedError: + errorString = QNativeSocketEnginePrivate::RemoteHostClosedErrorString; + break; + default: + errorString = QNativeSocketEnginePrivate::UnknownSocketErrorString; + } + + d->setError(error, errorString); + d->socketState = QAbstractSocket::UnconnectedState; + if (d->notifyOnRead) + emit readReady(); +} + void QNativeSocketEngine::putIntoPendingDatagramsList(const QList &datagrams) { Q_D(QNativeSocketEngine); @@ -1039,6 +1222,18 @@ void QNativeSocketEngine::putIntoPendingDatagramsList(const QList d->pendingDatagrams.append(datagrams); } +void QNativeSocketEngine::putIntoPendingData(const QVector &data) +{ + Q_D(QNativeSocketEngine); + QMutexLocker locker(&d->readMutex); + d->pendingData.append(data); + for (const QByteArray &newData : data) + d->bytesAvailable += newData.length(); + locker.unlock(); + if (d->notifyOnRead) + readNotification(); +} + bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol &socketProtocol) { Q_UNUSED(socketProtocol); @@ -1093,7 +1288,7 @@ QNativeSocketEnginePrivate::QNativeSocketEnginePrivate() , notifyOnException(false) , closingDown(false) , socketDescriptor(-1) - , worker(new SocketEngineWorker) + , worker(new SocketEngineWorker(this)) , sslSocket(Q_NULLPTR) , connectionToken( { -1 } ) { @@ -1481,109 +1676,6 @@ HRESULT QNativeSocketEnginePrivate::handleConnectOpFinished(IAsyncAction *action return S_OK; } -HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *asyncInfo, AsyncStatus status) -{ - if (closingDown || wasDeleted || isDeletingChildren - || socketState == QAbstractSocket::UnconnectedState) { - return S_OK; - } - - Q_Q(QNativeSocketEngine); - QMutexLocker locker(&readOperationsMutex); - for (int i = 0; i < pendingReadOps.count(); ++i) { - if (pendingReadOps.at(i).Get() == asyncInfo) { - pendingReadOps.takeAt(i); - break; - } - } - locker.unlock(); - - // A read in UnconnectedState will close the socket and return -1 and thus tell the caller, - // that the connection was closed. The socket cannot be closed here, as the subsequent read - // might fail then. - if (status == Error || status == Canceled) { - setError(QAbstractSocket::RemoteHostClosedError, RemoteHostClosedErrorString); - socketState = QAbstractSocket::UnconnectedState; - if (notifyOnRead) - emit q->readReady(); - return S_OK; - } - - ComPtr buffer; - HRESULT hr = asyncInfo->GetResults(&buffer); - RETURN_OK_IF_FAILED("Failed to get read results buffer"); - - UINT32 bufferLength; - hr = buffer->get_Length(&bufferLength); - Q_ASSERT_SUCCEEDED(hr); - // A zero sized buffer length signals, that the remote host closed the connection. The socket - // cannot be closed though, as the following read might have socket descriptor -1 and thus and - // the closing of the socket won't be communicated to the caller. So only the error is set. The - // actual socket close happens inside of read. - if (!bufferLength) { - setError(QAbstractSocket::RemoteHostClosedError, RemoteHostClosedErrorString); - socketState = QAbstractSocket::UnconnectedState; - if (notifyOnRead) - emit q->readReady(); - return S_OK; - } - - ComPtr byteArrayAccess; - hr = buffer.As(&byteArrayAccess); - Q_ASSERT_SUCCEEDED(hr); - byte *data; - hr = byteArrayAccess->Buffer(&data); - Q_ASSERT_SUCCEEDED(hr); - - QMutexLocker readLocker(&readMutex); - if (readBytes.atEnd()) // Everything has been read; the buffer is safe to reset - readBytes.close(); - if (!readBytes.isOpen()) - readBytes.open(QBuffer::ReadWrite|QBuffer::Truncate); - qint64 readPos = readBytes.pos(); - readBytes.seek(readBytes.size()); - Q_ASSERT(readBytes.atEnd()); - readBytes.write(reinterpret_cast(data), qint64(bufferLength)); - readBytes.seek(readPos); - bytesAvailable = readBytes.size() - readBytes.pos(); - readLocker.unlock(); - - if (notifyOnRead) - emit q->readReady(); - - hr = QEventDispatcherWinRT::runOnXamlThread([buffer, q, this]() { - UINT32 readBufferLength; - ComPtr stream; - HRESULT hr = tcpSocket()->get_InputStream(&stream); - RETURN_HR_IF_FAILED("handleReadyRead(): Could not obtain input stream"); - - // Reuse the stream buffer - hr = buffer->get_Capacity(&readBufferLength); - RETURN_HR_IF_FAILED("handleReadyRead(): Could not obtain buffer capacity"); - hr = buffer->put_Length(0); - RETURN_HR_IF_FAILED("handleReadyRead(): Could not set buffer length"); - - ComPtr readOp; - hr = stream->ReadAsync(buffer.Get(), readBufferLength, InputStreamOptions_Partial, &readOp); - if (FAILED(hr)) { - qErrnoWarning(hr, "handleReadyRead(): Could not read into socket stream buffer (%s).", - socketDescription(q).constData()); - return S_OK; - } - QMutexLocker locker(&readOperationsMutex); - pendingReadOps.append(readOp); - hr = readOp->put_Completed(Callback(this, &QNativeSocketEnginePrivate::handleReadyRead).Get()); - if (FAILED(hr)) { - qErrnoWarning(hr, "handleReadyRead(): Failed to set socket read callback (%s).", - socketDescription(q).constData()); - return S_OK; - } - return S_OK; - }); - Q_ASSERT_SUCCEEDED(hr); - return S_OK; -} - HRESULT QNativeSocketEnginePrivate::handleNewDatagram(IDatagramSocket *socket, IDatagramSocketMessageReceivedEventArgs *args) { Q_Q(QNativeSocketEngine); diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index 085704275c..9758310902 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -144,9 +144,12 @@ signals: private slots: void establishRead(); void handleNewDatagrams(const QList &datagram); + void handleNewData(const QVector &data); + void handleTcpError(QAbstractSocket::SocketError error); private: Q_INVOKABLE void putIntoPendingDatagramsList(const QList &datagrams); + Q_INVOKABLE void putIntoPendingData(const QVector &data); Q_DECLARE_PRIVATE(QNativeSocketEngine) Q_DISABLE_COPY(QNativeSocketEngine) @@ -215,23 +218,17 @@ private: Microsoft::WRL::ComPtr tcpListener; Microsoft::WRL::ComPtr connectOp; - // Protected by readOperationsMutex. Written in handleReadyRead (native callback) - QVector>> pendingReadOps; - - // Protected by readMutex. Written in handleReadyRead (native callback) - QBuffer readBytes; - // In case of TCP readMutex protects readBytes and bytesAvailable. In case of UDP it is // pendingDatagrams. They are written inside native callbacks (handleReadyRead and // handleNewDatagrams/putIntoPendingDatagramsList) mutable QMutex readMutex; - // As pendingReadOps is changed inside handleReadyRead(native callback) it has to be protected - QMutex readOperationsMutex; - // Protected by readMutex. Written in handleReadyRead (native callback) QAtomicInteger bytesAvailable; + // Protected by readMutex. Written in handleNewData/putIntoPendingData (native callback) + QVector pendingData; + // Protected by readMutex. Written in handleNewDatagrams/putIntoPendingDatagramsList QList pendingDatagrams; @@ -246,7 +243,6 @@ private: HRESULT handleClientConnection(ABI::Windows::Networking::Sockets::IStreamSocketListener *tcpListener, ABI::Windows::Networking::Sockets::IStreamSocketListenerConnectionReceivedEventArgs *args); HRESULT handleConnectOpFinished(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus); - HRESULT handleReadyRead(ABI::Windows::Foundation::IAsyncOperationWithProgress *asyncInfo, ABI::Windows::Foundation::AsyncStatus); }; QT_END_NAMESPACE From 019c932ca9bf7c274fd8a402c2af200b5b0cbc59 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 2 Dec 2016 19:53:47 +0100 Subject: [PATCH 19/74] unbreak "aux" template for mingw & msvc, take 3 eliminating everying TARGET-related was a nice try, but in the real world (e.g., qttranslations), extra compilers are activated by PRE_TARGETDEPS, which of course doesn't work when TARGET is entirely gone. so instead, let it act as a phony target. this is consistent with the unix generator. supersedes 0810d48bc in amending af2847260. Task-number: QTBUG-57423 Change-Id: I3d2ecc4ff42b37ffe5f71f5c20d17c06b31f4da2 Reviewed-by: Jake Petroules Reviewed-by: Oliver Wolff --- qmake/generators/win32/mingw_make.cpp | 6 +++--- qmake/generators/win32/msvc_nmake.cpp | 5 ++--- qmake/generators/win32/winmakefile.cpp | 3 +++ 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index e3d76cd76e..8d5a9a7d0f 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -308,13 +308,13 @@ void MingwMakefileGenerator::writeBuildRulesPart(QTextStream &t) { t << "first: all\n"; t << "all: " << escapeDependencyPath(fileFixify(Option::output.fileName())) - << ' ' << depVar("ALL_DEPS"); + << ' ' << depVar("ALL_DEPS") << " $(DESTDIR_TARGET)\n\n"; + t << "$(DESTDIR_TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS"); if (project->first("TEMPLATE") == "aux") { t << "\n\n"; return; } - t << " $(DESTDIR_TARGET)\n\n"; - t << "$(DESTDIR_TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS"); + if(!project->isEmpty("QMAKE_PRE_LINK")) t << "\n\t" <isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") { diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index c3ac097a98..746746b9f6 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -549,13 +549,12 @@ void NmakeMakefileGenerator::writeBuildRulesPart(QTextStream &t) t << "first: all\n"; t << "all: " << escapeDependencyPath(fileFixify(Option::output.fileName())) - << ' ' << depVar("ALL_DEPS"); + << ' ' << depVar("ALL_DEPS") << " $(DESTDIR_TARGET)\n\n"; + t << "$(DESTDIR_TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS"); if (templateName == "aux") { t << "\n\n"; return; } - t << " $(DESTDIR_TARGET)\n\n"; - t << "$(DESTDIR_TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS"); if(!project->isEmpty("QMAKE_PRE_LINK")) t << "\n\t" <first("TEMPLATE").endsWith("aux")) + return; + project->values("QMAKE_ORIG_TARGET") = project->values("TARGET"); if (project->isEmpty("QMAKE_PROJECT_NAME")) project->values("QMAKE_PROJECT_NAME") = project->values("QMAKE_ORIG_TARGET"); From b9e800cd996e1401d3157a0cdb9e6ee6b05fd3a5 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 6 Dec 2016 16:00:14 +0100 Subject: [PATCH 20/74] fix qlalr invocation in silent builds Change-Id: I8cd5da01dcbcdebe29815a80cc0f65365727465d Reviewed-by: Alex Blasche Reviewed-by: Jake Petroules --- mkspecs/features/qlalr.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/qlalr.prf b/mkspecs/features/qlalr.prf index 941bfe0d9f..54d8b583c6 100644 --- a/mkspecs/features/qlalr.prf +++ b/mkspecs/features/qlalr.prf @@ -25,7 +25,7 @@ for (s, QLALRSOURCES) { $${base}.variable_out = GENERATED_SOURCES $${base}.depends += $$QMAKE_QLALR_EXE $${base}.commands = $$QMAKE_QLALR $$QMAKE_QLALRFLAGS ${QMAKE_FILE_IN} - silent: $${base}.commands = @echo qlalr ${QMAKE_FILE_IN} && $${base}.commands + silent: $${base}.commands = @echo qlalr ${QMAKE_FILE_IN} && $$eval($${base}.commands) $${base}.name = QLALR ${QMAKE_FILE_IN} $${base}_h.input = $$invar From 7df0c7a309ada7f9ab70a2c20f86c0707288e31e Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 1 Dec 2016 12:47:55 +0100 Subject: [PATCH 21/74] rename QPointerUniqueId -> QPointingDeviceUniqueId Several people agreed that the name was confusing and that this one is better. Task-number: QTBUG-54616 Change-Id: I31cf057f4bc818332b0551a27d1711599440207c Reviewed-by: Marc Mutz Reviewed-by: Sune Vuorela --- src/gui/kernel/qevent.cpp | 36 +++++++++---------- src/gui/kernel/qevent.h | 20 +++++------ src/gui/kernel/qevent_p.h | 2 +- src/gui/kernel/qwindowsysteminterface.h | 2 +- .../kernel/qtouchevent/tst_qtouchevent.cpp | 8 ++--- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 72cd374419..b198fa0832 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -4475,14 +4475,14 @@ int QTouchEvent::TouchPoint::id() const \since 5.8 Returns the unique ID of this touch point or token, if any. - It is normally invalid (see \l {QPointerUniqueId::isValid()} {isValid()}), + It is normally invalid (see \l {QPointingDeviceUniqueId::isValid()} {isValid()}), because touchscreens cannot uniquely identify fingers. But when the \l {TouchPoint::InfoFlag} {Token} flag is set, it is expected to uniquely identify a specific token (fiducial object). \sa flags */ -QPointerUniqueId QTouchEvent::TouchPoint::uniqueId() const +QPointingDeviceUniqueId QTouchEvent::TouchPoint::uniqueId() const { return d->uniqueId; } @@ -4758,7 +4758,7 @@ void QTouchEvent::TouchPoint::setUniqueId(qint64 uid) { if (d->ref.load() != 1) d = d->detach(); - d->uniqueId = QPointerUniqueId::fromNumericId(uid); + d->uniqueId = QPointingDeviceUniqueId::fromNumericId(uid); } /*! \internal */ @@ -5177,15 +5177,15 @@ Qt::ApplicationState QApplicationStateChangeEvent::applicationState() const } /*! - \class QPointerUniqueId + \class QPointingDeviceUniqueId \since 5.8 \ingroup events \inmodule QtGui - \brief QPointerUniqueId identifies a unique object, such as a tagged token + \brief QPointingDeviceUniqueId identifies a unique object, such as a tagged token or stylus, which is used with a pointing device. - QPointerUniqueIds can be compared for equality, and can be used as keys in a QHash. + QPointingDeviceUniqueIds can be compared for equality, and can be used as keys in a QHash. You get access to the numerical ID via numericId(), if the device supports such IDs. For future extensions, though, you should not use that function, but compare objects of this type using the equality operator. @@ -5201,29 +5201,29 @@ Qt::ApplicationState QApplicationStateChangeEvent::applicationState() const */ /*! - \fn QPointerUniqueId::QPointerUniqueId() + \fn QPointingDeviceUniqueId::QPointingDeviceUniqueId() Constructs an invalid unique pointer ID. */ /*! Constructs a unique pointer ID from numeric ID \a id. */ -QPointerUniqueId QPointerUniqueId::fromNumericId(qint64 id) +QPointingDeviceUniqueId QPointingDeviceUniqueId::fromNumericId(qint64 id) { - QPointerUniqueId result; + QPointingDeviceUniqueId result; result.m_numericId = id; return result; } /*! - \fn bool QPointerUniqueId::isValid() + \fn bool QPointingDeviceUniqueId::isValid() Returns whether this unique pointer ID is valid, that is, it represents an actual pointer. */ /*! - \property QPointerUniqueId::numericId + \property QPointingDeviceUniqueId::numericId \brief the numeric unique ID of the token represented by a touchpoint If the device provides a numeric ID, isValid() returns true, and this @@ -5235,26 +5235,26 @@ QPointerUniqueId QPointerUniqueId::fromNumericId(qint64 id) \sa isValid() */ -qint64 QPointerUniqueId::numericId() const Q_DECL_NOTHROW +qint64 QPointingDeviceUniqueId::numericId() const Q_DECL_NOTHROW { return m_numericId; } /*! - \relates QPointerUniqueId + \relates QPointingDeviceUniqueId \since 5.8 Returns whether the two unique pointer IDs \a lhs and \a rhs identify the same pointer (\c true) or not (\c false). */ -bool operator==(QPointerUniqueId lhs, QPointerUniqueId rhs) Q_DECL_NOTHROW +bool operator==(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) Q_DECL_NOTHROW { return lhs.numericId() == rhs.numericId(); } /*! - \fn bool operator!=(QPointerUniqueId lhs, QPointerUniqueId rhs) - \relates QPointerUniqueId + \fn bool operator!=(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) + \relates QPointingDeviceUniqueId \since 5.8 Returns whether the two unique pointer IDs \a lhs and \a rhs identify different pointers @@ -5262,12 +5262,12 @@ bool operator==(QPointerUniqueId lhs, QPointerUniqueId rhs) Q_DECL_NOTHROW */ /*! - \relates QPointerUniqueId + \relates QPointingDeviceUniqueId \since 5.8 Returns the hash value for \a key, using \a seed to seed the calculation. */ -uint qHash(QPointerUniqueId key, uint seed) Q_DECL_NOTHROW +uint qHash(QPointingDeviceUniqueId key, uint seed) Q_DECL_NOTHROW { return qHash(key.numericId(), seed); } diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index b7c0f3338e..7d5b719e09 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -793,7 +793,7 @@ inline bool operator==(QKeyEvent *e, QKeySequence::StandardKey key){return (e ? inline bool operator==(QKeySequence::StandardKey key, QKeyEvent *e){return (e ? e->matches(key) : false);} #endif // QT_NO_SHORTCUT -class Q_GUI_EXPORT QPointerUniqueId +class Q_GUI_EXPORT QPointingDeviceUniqueId { Q_GADGET // ### kept these to keep other modules compiling. Remove before 5.8.0 final! @@ -803,11 +803,11 @@ class Q_GUI_EXPORT QPointerUniqueId Q_PROPERTY(qint64 numericId READ numericId CONSTANT) public: Q_ALWAYS_INLINE - Q_DECL_CONSTEXPR QPointerUniqueId() Q_DECL_NOTHROW : m_numericId(-1) {} + Q_DECL_CONSTEXPR QPointingDeviceUniqueId() Q_DECL_NOTHROW : m_numericId(-1) {} // compiler-generated copy/move ctor/assignment operators are ok! // compiler-generated dtor is ok! - static QPointerUniqueId fromNumericId(qint64 id); + static QPointingDeviceUniqueId fromNumericId(qint64 id); Q_ALWAYS_INLINE Q_DECL_CONSTEXPR bool isValid() const Q_DECL_NOTHROW { return m_numericId != -1; } qint64 numericId() const Q_DECL_NOTHROW; @@ -815,7 +815,7 @@ public: // ### kept these to keep other modules compiling. Remove before 5.8.0 final! #if QT_DEPRECATED_SINCE(5, 8) Q_ALWAYS_INLINE Q_DECL_DEPRECATED qint64 numeric() const { return numericId(); } - Q_ALWAYS_INLINE Q_DECL_DEPRECATED explicit QPointerUniqueId(qint64 id) : m_numericId(id) {} + Q_ALWAYS_INLINE Q_DECL_DEPRECATED explicit QPointingDeviceUniqueId(qint64 id) : m_numericId(id) {} #endif private: // TODO: for TUIO 2, or any other type of complex token ID, an internal @@ -823,13 +823,13 @@ private: // In this case, m_numericId will then turn into an index into that array (or hash). qint64 m_numericId; }; -Q_DECLARE_TYPEINFO(QPointerUniqueId, Q_MOVABLE_TYPE); -template <> class QList {}; // to prevent instantiation: use QVector instead +Q_DECLARE_TYPEINFO(QPointingDeviceUniqueId, Q_MOVABLE_TYPE); +template <> class QList {}; // to prevent instantiation: use QVector instead -Q_GUI_EXPORT bool operator==(QPointerUniqueId lhs, QPointerUniqueId rhs) Q_DECL_NOTHROW; -inline bool operator!=(QPointerUniqueId lhs, QPointerUniqueId rhs) Q_DECL_NOTHROW +Q_GUI_EXPORT bool operator==(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) Q_DECL_NOTHROW; +inline bool operator!=(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) Q_DECL_NOTHROW { return !operator==(lhs, rhs); } -Q_GUI_EXPORT uint qHash(QPointerUniqueId key, uint seed = 0) Q_DECL_NOTHROW; +Q_GUI_EXPORT uint qHash(QPointingDeviceUniqueId key, uint seed = 0) Q_DECL_NOTHROW; @@ -868,7 +868,7 @@ public: { qSwap(d, other.d); } int id() const; - QPointerUniqueId uniqueId() const; + QPointingDeviceUniqueId uniqueId() const; Qt::TouchPointState state() const; diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index 7e82b9c654..898ad16cf6 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -80,7 +80,7 @@ public: QAtomicInt ref; int id; - QPointerUniqueId uniqueId; + QPointingDeviceUniqueId uniqueId; Qt::TouchPointStates state; QRectF rect, sceneRect, screenRect; QPointF normalizedPos, diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index 3be3c3188c..a28d1c93df 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -129,7 +129,7 @@ public: TouchPoint() : id(0), uniqueId(-1), pressure(0), rotation(0), state(Qt::TouchPointStationary) { } int id; // for application use qint64 uniqueId; // for TUIO: object/token ID; otherwise empty - // TODO for TUIO 2.0: add registerPointerUniqueID(QPointerUniqueId) + // TODO for TUIO 2.0: add registerPointerUniqueID(QPointingDeviceUniqueId) QPointF normalPosition; // touch device coordinates, (0 to 1, 0 to 1) QRectF area; // the touched area, centered at position in screen coordinates qreal pressure; // 0 to 1 diff --git a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp index 02814b48e9..364b9332af 100644 --- a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp @@ -227,7 +227,7 @@ void tst_QTouchEvent::cleanup() void tst_QTouchEvent::qPointerUniqueId() { - QPointerUniqueId id1, id2; + QPointingDeviceUniqueId id1, id2; QCOMPARE(id1.numericId(), Q_INT64_C(-1)); QVERIFY(!id1.isValid()); @@ -235,13 +235,13 @@ void tst_QTouchEvent::qPointerUniqueId() QVERIFY( id1 == id2); QVERIFY(!(id1 != id2)); - QSet set; // compile test + QSet set; // compile test set.insert(id1); set.insert(id2); QCOMPARE(set.size(), 1); - const auto id3 = QPointerUniqueId::fromNumericId(-1); + const auto id3 = QPointingDeviceUniqueId::fromNumericId(-1); QCOMPARE(id3.numericId(), Q_INT64_C(-1)); QVERIFY(!id3.isValid()); @@ -252,7 +252,7 @@ void tst_QTouchEvent::qPointerUniqueId() QCOMPARE(set.size(), 1); - const auto id4 = QPointerUniqueId::fromNumericId(4); + const auto id4 = QPointingDeviceUniqueId::fromNumericId(4); QCOMPARE(id4.numericId(), Q_INT64_C(4)); QVERIFY(id4.isValid()); From 3695c2ee11876fddc090db4d0e8ffa315c5b4dac Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 4 Dec 2016 21:29:06 -0800 Subject: [PATCH 22/74] Disable ICC warning 3373 This warning does not make sense. it seems to trigger when in code like the following in template functions: auto x = 1, y = 2; 3373: nonstandard use of "auto" to both deduce the type from an initializer and to announce a trailing return type Other reports on the Internet indicate that no one understands what triggers this warning and have just worked around it. Additionally, the same warning exists on other compilers with the same text, so it's likely come from the EDG front-end. This has been reported to Intel. Change-Id: I73fa1e59a4844c43a109fffd148d45065ab69eff Intel-Issue-ID: 6000164202 Reviewed-by: Marc Mutz --- mkspecs/linux-icc/qmake.conf | 2 +- mkspecs/macx-icc/qmake.conf | 2 +- mkspecs/win32-icc/qmake.conf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf index 495fd15e80..2c66e80db4 100644 --- a/mkspecs/linux-icc/qmake.conf +++ b/mkspecs/linux-icc/qmake.conf @@ -14,7 +14,7 @@ QMAKE_YACCFLAGS = -d QMAKE_CFLAGS = QMAKE_CFLAGS_APP = -fPIC QMAKE_CFLAGS_DEPS = -M -QMAKE_CFLAGS_WARN_ON = -w1 -Wall -Wcheck -wd1572,873,2259,2261 +QMAKE_CFLAGS_WARN_ON = -w1 -Wall -Wcheck -wd1572,873,2259,2261,3373 QMAKE_CFLAGS_WARN_OFF = -w QMAKE_CFLAGS_RELEASE = -O2 -falign-functions=16 -ansi-alias -fstrict-aliasing QMAKE_CFLAGS_DEBUG = -O0 -g diff --git a/mkspecs/macx-icc/qmake.conf b/mkspecs/macx-icc/qmake.conf index 35e55f799e..0a94ae472d 100644 --- a/mkspecs/macx-icc/qmake.conf +++ b/mkspecs/macx-icc/qmake.conf @@ -14,7 +14,7 @@ QMAKE_COMPILER = gcc clang intel_icc # icc pretends to be gcc and cla QMAKE_CC = icc QMAKE_CFLAGS = QMAKE_CFLAGS_DEPS = -M -QMAKE_CFLAGS_WARN_ON = -w1 -Wcheck -wd654,1572,411,873,1125,2259,2261,3280 +QMAKE_CFLAGS_WARN_ON = -w1 -Wcheck -wd654,1572,411,873,1125,2259,2261,3280,3373 QMAKE_CFLAGS_WARN_OFF = -w QMAKE_CFLAGS_RELEASE = QMAKE_CFLAGS_DEBUG = -g diff --git a/mkspecs/win32-icc/qmake.conf b/mkspecs/win32-icc/qmake.conf index dd54131526..cfd8399a3c 100644 --- a/mkspecs/win32-icc/qmake.conf +++ b/mkspecs/win32-icc/qmake.conf @@ -19,7 +19,7 @@ QMAKE_LEX = flex QMAKE_LEXFLAGS = QMAKE_YACC = bison -y QMAKE_YACCFLAGS = -d -QMAKE_CFLAGS = -nologo -Zm200 /Qprec /Qwd1744,1738,809 +QMAKE_CFLAGS = -nologo -Zm200 /Qprec /Qwd1744,1738,809,3373 QMAKE_CFLAGS_WARN_ON = -W3 /Qwd673 QMAKE_CFLAGS_WARN_OFF = -W0 /Qwd673 QMAKE_CFLAGS_RELEASE = -O2 -MD From 630f8e7ad6e94c703f85fa11a9926ba83c478e72 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 2 Dec 2016 14:22:55 +0100 Subject: [PATCH 23/74] Document 3rd party code in qimagetransform.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I685d3964617e3984b938bd9aafa0626acd75656f Reviewed-by: Topi Reiniö --- src/gui/image/qimage.cpp | 31 ---------- src/gui/painting/QIMAGETRANSFORM_LICENSE.txt | 60 ++++++++++++++++++++ src/gui/painting/qt_attribution.json | 43 +++++++++----- 3 files changed, 90 insertions(+), 44 deletions(-) create mode 100644 src/gui/painting/QIMAGETRANSFORM_LICENSE.txt diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 9e911bdcea..9e9f01a46a 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -596,37 +596,6 @@ bool QImageData::checkForAlphaPixels() const \endtable - \target qimage-legalese - \section1 Legal Information - - For smooth scaling, the transformed() functions use code based on - smooth scaling algorithm by Daniel M. Duley. - - \badcode - Copyright (C) 2004, 2005 Daniel M. Duley - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. 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. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - \endcode - \sa QImageReader, QImageWriter, QPixmap, QSvgRenderer, {Image Composition Example}, {Image Viewer Example}, {Scribble Example}, {Pixelator Example} */ diff --git a/src/gui/painting/QIMAGETRANSFORM_LICENSE.txt b/src/gui/painting/QIMAGETRANSFORM_LICENSE.txt new file mode 100644 index 0000000000..67c910826a --- /dev/null +++ b/src/gui/painting/QIMAGETRANSFORM_LICENSE.txt @@ -0,0 +1,60 @@ +qimagetransform.cpp was contributed by Daniel M. Duley based on code from Imlib2. + +Copyright (C) 2004, 2005 Daniel M. Duley + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. 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. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + + + +Imlib2 License + +Copyright (C) 2000 Carsten Haitzler and various contributors (see +AUTHORS) + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies of the Software and its Copyright notices. In addition +publicly documented acknowledgment must be given that this software has +been used if no source code of this software is made available publicly. +This includes acknowledgments in either Copyright notices, Manuals, +Publicity and Marketing documents or any documentation provided with any +product containing this software. This License does not apply to any +software that links to the libraries provided by this software +(statically or dynamically), but only to the software provided. + +Please see the COPYING.PLAIN for a plain-english explanation of this +notice and it's intent. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/src/gui/painting/qt_attribution.json b/src/gui/painting/qt_attribution.json index f635cf98ac..06a62d9d66 100644 --- a/src/gui/painting/qt_attribution.json +++ b/src/gui/painting/qt_attribution.json @@ -1,14 +1,31 @@ -{ - "Id": "grayraster", - "Name": "Anti-aliasing rasterizer from FreeType 2", - "QDocModule": "qtgui", - "QtUsage": "Used in Qt GUI.", - "Path": "qgrayraster.c", +[ + { + "Id": "grayraster", + "Name": "Anti-aliasing rasterizer from FreeType 2", + "QDocModule": "qtgui", + "QtUsage": "Used in Qt GUI.", + "Path": "qgrayraster.c", - "Description": "FreeType is a freely available software library to render fonts.", - "Homepage": "http://www.freetype.org", - "License": "Freetype Project License or GNU General Public License v2.0 only", - "LicenseId": "FTL or GPL-2.0", - "LicenseFile": "../../3rdparty/freetype/docs/LICENSE.TXT", - "Copyright": "Copyright 2006-2015 by David Turner, Robert Wilhelm, and Werner Lemberg." -} + "Description": "FreeType is a freely available software library to render fonts.", + "Homepage": "http://www.freetype.org", + "License": "Freetype Project License or GNU General Public License v2.0 only", + "LicenseId": "FTL or GPL-2.0", + "LicenseFile": "../../3rdparty/freetype/docs/LICENSE.TXT", + "Copyright": "Copyright 2006-2015 by David Turner, Robert Wilhelm, and Werner Lemberg." + }, + { + "Id": "smooth-scaling-algorithm", + "Name": "Smooth Scaling Algorithm", + "QDocModule": "qtgui", + "QtUsage": "Used in Qt Gui (QImage::transformed() functions).", + "Files": "qimagescale.cpp", + + "Description": "Normal smoothscale method, based on Imlib2's smoothscale.", + "LicenseId": "BSD-2-Clause AND Imlib2", + "License": "BSD 2-clause \"Simplified\" License and Imlib2 License", + "LicenseFile": "QIMAGETRANSFORM_LICENSE.txt", + "Copyright": "Copyright (C) 2004, 2005 Daniel M. Duley. + (C) Carsten Haitzler and various contributors. + (C) Willem Monsuwe " + } +] From 4077fcc6153493284b5e2b0812ff215b49e8c8b7 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 29 Nov 2016 15:30:52 +0100 Subject: [PATCH 24/74] QHostAddress: fix assignment operators QHostAddress allowed assignment from a QString, but the respective constructor is explicit, and rightfully so. So it does not make sense that the assignment operator is provided, because of the asymmetry caused between QHostAddress addr = funcReturningQString(); // ERROR addr = funcReturningQString(); // OK (until now) By the same token, since SpecialAddress is implicitly convertible to QHostAddress, provide the missing assignment operator from that enum. Add tests, rewriting the _data() function to use the enum instead of an int to pass SpecialAddress values, and to test !=, too. Added setAddress(SpecialAddress), since a) it was missing and b) to share code between the ctor and the assignment operator. Change-Id: Ief64c493be13ada8c6968801d9ed083b267fa902 Reviewed-by: Thiago Macieira --- src/network/kernel/qhostaddress.cpp | 28 +++++++++ src/network/kernel/qhostaddress.h | 5 ++ .../kernel/qhostaddress/tst_qhostaddress.cpp | 63 +++++++++++-------- 3 files changed, 71 insertions(+), 25 deletions(-) diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index 7e3d2c5d6e..8fac76f86a 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -517,6 +517,19 @@ QHostAddress::QHostAddress(const QHostAddress &address) QHostAddress::QHostAddress(SpecialAddress address) : d(new QHostAddressPrivate) { + setAddress(address); +} + +/*! + \overload + \since 5.8 + + Sets the special address specified by \a address. +*/ +void QHostAddress::setAddress(SpecialAddress address) +{ + d->clear(); + Q_IPV6ADDR ip6; memset(&ip6, 0, sizeof ip6); quint32 ip4 = INADDR_ANY; @@ -567,6 +580,7 @@ QHostAddress &QHostAddress::operator=(const QHostAddress &address) return *this; } +#if QT_DEPRECATED_SINCE(5, 8) /*! Assigns the host address \a address to this object, and returns a reference to this object. @@ -578,6 +592,20 @@ QHostAddress &QHostAddress::operator=(const QString &address) setAddress(address); return *this; } +#endif + +/*! + \since 5.8 + Assigns the special address \a address to this object, and returns a + reference to this object. + + \sa setAddress() +*/ +QHostAddress &QHostAddress::operator=(SpecialAddress address) +{ + setAddress(address); + return *this; +} /*! \fn bool QHostAddress::operator!=(const QHostAddress &other) const diff --git a/src/network/kernel/qhostaddress.h b/src/network/kernel/qhostaddress.h index 58af14ee33..10fe33f6fa 100644 --- a/src/network/kernel/qhostaddress.h +++ b/src/network/kernel/qhostaddress.h @@ -108,7 +108,11 @@ public: #endif QHostAddress &operator=(const QHostAddress &other); +#if QT_DEPRECATED_SINCE(5, 8) + QT_DEPRECATED_X("use = QHostAddress(string) instead") QHostAddress &operator=(const QString &address); +#endif + QHostAddress &operator=(SpecialAddress address); void swap(QHostAddress &other) Q_DECL_NOTHROW { d.swap(other.d); } @@ -118,6 +122,7 @@ public: void setAddress(const Q_IPV6ADDR &ip6Addr); void setAddress(const sockaddr *address); bool setAddress(const QString &address); + void setAddress(SpecialAddress address); QAbstractSocket::NetworkLayerProtocol protocol() const; quint32 toIPv4Address() const; // ### Qt6: merge with next overload diff --git a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp index 419c781aab..364e435d3d 100644 --- a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp +++ b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp @@ -46,6 +46,8 @@ # include #endif +Q_DECLARE_METATYPE(QHostAddress::SpecialAddress) + class tst_QHostAddress : public QObject { Q_OBJECT @@ -232,51 +234,55 @@ void tst_QHostAddress::setAddress_QString() void tst_QHostAddress::specialAddresses_data() { QTest::addColumn("text"); - QTest::addColumn("address"); + QTest::addColumn("address"); QTest::addColumn("result"); - QTest::newRow("localhost_1") << QString("127.0.0.1") << (int)QHostAddress::LocalHost << true; - QTest::newRow("localhost_2") << QString("127.0.0.2") << (int)QHostAddress::LocalHost << false; - QTest::newRow("localhost_3") << QString("127.0.0.2") << (int)QHostAddress::LocalHostIPv6 << false; + QTest::newRow("localhost_1") << QString("127.0.0.1") << QHostAddress::LocalHost << true; + QTest::newRow("localhost_2") << QString("127.0.0.2") << QHostAddress::LocalHost << false; + QTest::newRow("localhost_3") << QString("127.0.0.2") << QHostAddress::LocalHostIPv6 << false; - QTest::newRow("localhost_ipv6_4") << QString("::1") << (int)QHostAddress::LocalHostIPv6 << true; - QTest::newRow("localhost_ipv6_5") << QString("::2") << (int)QHostAddress::LocalHostIPv6 << false; - QTest::newRow("localhost_ipv6_6") << QString("::1") << (int)QHostAddress::LocalHost << false; + QTest::newRow("localhost_ipv6_4") << QString("::1") << QHostAddress::LocalHostIPv6 << true; + QTest::newRow("localhost_ipv6_5") << QString("::2") << QHostAddress::LocalHostIPv6 << false; + QTest::newRow("localhost_ipv6_6") << QString("::1") << QHostAddress::LocalHost << false; - QTest::newRow("null_1") << QString("") << (int)QHostAddress::Null << true; - QTest::newRow("null_2") << QString("bjarne") << (int)QHostAddress::Null << true; + QTest::newRow("null_1") << QString("") << QHostAddress::Null << true; + QTest::newRow("null_2") << QString("bjarne") << QHostAddress::Null << true; - QTest::newRow("compare_from_null") << QString("") << (int)QHostAddress::Broadcast << false; + QTest::newRow("compare_from_null") << QString("") << QHostAddress::Broadcast << false; - QTest::newRow("broadcast_1") << QString("255.255.255.255") << (int)QHostAddress::Any << false; - QTest::newRow("broadcast_2") << QString("255.255.255.255") << (int)QHostAddress::Broadcast << true; + QTest::newRow("broadcast_1") << QString("255.255.255.255") << QHostAddress::Any << false; + QTest::newRow("broadcast_2") << QString("255.255.255.255") << QHostAddress::Broadcast << true; - QTest::newRow("any_ipv6") << QString("::") << (int)QHostAddress::AnyIPv6 << true; - QTest::newRow("any_ipv4") << QString("0.0.0.0") << (int)QHostAddress::AnyIPv4 << true; + QTest::newRow("any_ipv6") << QString("::") << QHostAddress::AnyIPv6 << true; + QTest::newRow("any_ipv4") << QString("0.0.0.0") << QHostAddress::AnyIPv4 << true; - QTest::newRow("dual_not_ipv6") << QString("::") << (int)QHostAddress::Any << false; - QTest::newRow("dual_not_ipv4") << QString("0.0.0.0") << (int)QHostAddress::Any << false; + QTest::newRow("dual_not_ipv6") << QString("::") << QHostAddress::Any << false; + QTest::newRow("dual_not_ipv4") << QString("0.0.0.0") << QHostAddress::Any << false; } void tst_QHostAddress::specialAddresses() { QFETCH(QString, text); - QFETCH(int, address); + QFETCH(QHostAddress::SpecialAddress, address); QFETCH(bool, result); - QVERIFY((QHostAddress(text) == (QHostAddress::SpecialAddress)address) == result); + QCOMPARE(QHostAddress(text) == address, result); //check special address equal to itself (QTBUG-22898), note two overloads of operator== - QVERIFY(QHostAddress((QHostAddress::SpecialAddress)address) == QHostAddress((QHostAddress::SpecialAddress)address)); - QVERIFY(QHostAddress((QHostAddress::SpecialAddress)address) == (QHostAddress::SpecialAddress)address); + QVERIFY(QHostAddress(address) == QHostAddress(address)); + QVERIFY(QHostAddress(address) == address); + QVERIFY(!(QHostAddress(address) != QHostAddress(address))); + QVERIFY(!(QHostAddress(address) != address)); + + { + QHostAddress ha; + ha.setAddress(address); + QVERIFY(ha == address); + } QHostAddress setter; setter.setAddress(text); - if (result) { - QVERIFY(setter == (QHostAddress::SpecialAddress) address); - } else { - QVERIFY(!((QHostAddress::SpecialAddress) address == setter)); - } + QCOMPARE(setter == address, result); } @@ -359,6 +365,11 @@ void tst_QHostAddress::isEqual() QCOMPARE(second.isEqual(first, QHostAddress::ConversionModeFlag(flags)), result); } +QT_WARNING_PUSH +#ifdef QT_WARNING_DISABLE_DEPRECATED +QT_WARNING_DISABLE_DEPRECATED +#endif + void tst_QHostAddress::assignment() { QHostAddress address; @@ -379,6 +390,8 @@ void tst_QHostAddress::assignment() #endif // !Q_OS_WINRT } +QT_WARNING_POP + void tst_QHostAddress::scopeId() { QHostAddress address("fe80::2e0:4cff:fefb:662a%eth0"); From b2f78b796b5b73d4f0732975ffd66f8aa392c001 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 5 Dec 2016 14:21:40 -0800 Subject: [PATCH 25/74] QCocoaMenu: Avoid exception when inserting item already in this menu This should not happen, but it's clearly not the user's fault. So we should try to carry on as gracefully as possible instead of letting Cocoa abort the application. The patch also factors the repeated calls to QCocoaMenuItem:: nsItem() in QCocoaMenu::insertNative() and improves a warning from QCocoaMenuIten::sync(). Change-Id: Id00135c219aaf40fb565b19a65cab68f6d9863b2 Task-number: QTBUG-57404 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/cocoa/qcocoamenu.mm | 20 +++++++++----- src/plugins/platforms/cocoa/qcocoamenuitem.mm | 2 +- .../widgets/widgets/qmenubar/tst_qmenubar.cpp | 27 +++++++++++++++++++ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 88ffd48538..915463a52a 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -331,11 +331,12 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem * void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem) { - item->nsItem().target = m_nativeMenu.delegate; - item->nsItem().action = @selector(itemFired:); + NSMenuItem *nativeItem = item->nsItem(); + nativeItem.target = m_nativeMenu.delegate; + nativeItem.action = @selector(itemFired:); // Someone's adding new items after aboutToShow() was emitted - if (isOpen() && item->menu() && item->nsItem()) - item->menu()->setAttachedItem(item->nsItem()); + if (isOpen() && nativeItem) + item->menu()->setAttachedItem(nativeItem); item->setParentEnabled(isEnabled()); @@ -348,15 +349,20 @@ void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem) beforeItem = itemOrNull(m_menuItems.indexOf(beforeItem) + 1); } + if (nativeItem.menu) { + qWarning() << "Menu item" << item->text() << "already in menu" << QString::fromNSString(nativeItem.menu.title); + return; + } + if (beforeItem) { if (beforeItem->isMerged()) { qWarning("No non-merged before menu item found"); return; } - NSUInteger nativeIndex = [m_nativeMenu indexOfItem:beforeItem->nsItem()]; - [m_nativeMenu insertItem: item->nsItem() atIndex: nativeIndex]; + const NSInteger nativeIndex = [m_nativeMenu indexOfItem:beforeItem->nsItem()]; + [m_nativeMenu insertItem:nativeItem atIndex:nativeIndex]; } else { - [m_nativeMenu addItem: item->nsItem()]; + [m_nativeMenu addItem:nativeItem]; } item->setMenuParent(this); } diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index e32ff26ff5..21f2b4de85 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -288,7 +288,7 @@ NSMenuItem *QCocoaMenuItem::sync() } default: - qWarning() << "menu item" << m_text << "has unsupported role" << (int)m_role; + qWarning() << "Menu item" << m_text << "has unsupported role" << m_role; } if (mergeItem) { diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp index 3a4c4545df..2c20d03066 100644 --- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp @@ -132,6 +132,7 @@ private slots: void taskQTBUG53205_crashReparentNested(); #ifdef Q_OS_MACOS void taskQTBUG56275_reinsertMenuInParentlessQMenuBar(); + void QTBUG_57404_existingMenuItemException(); #endif void platformMenu(); @@ -1539,6 +1540,32 @@ void tst_QMenuBar::taskQTBUG56275_reinsertMenuInParentlessQMenuBar() QVERIFY(tst_qmenubar_taskQTBUG56275(&menubar)); } + +void tst_QMenuBar::QTBUG_57404_existingMenuItemException() +{ + QMainWindow mw1; + QMainWindow mw2; + mw1.show(); + mw2.show(); + + QMenuBar *mb = new QMenuBar(&mw1); + mw1.setMenuBar(mb); + mb->show(); + QMenu *editMenu = new QMenu(QLatin1String("Edit"), &mw1); + mb->addMenu(editMenu); + QAction *copyAction = editMenu->addAction("&Copy"); + copyAction->setShortcut(QKeySequence("Ctrl+C")); + QTest::ignoreMessage(QtWarningMsg, "Menu item \"&Copy\" has unsupported role QPlatformMenuItem::MenuRole(NoRole)"); + copyAction->setMenuRole(QAction::NoRole); + + QVERIFY(QTest::qWaitForWindowExposed(&mw2)); + QTest::qWait(100); + QTest::ignoreMessage(QtWarningMsg, "Menu item \"&Copy\" already in menu \"Edit\""); + mw2.close(); + mw1.activateWindow(); + QTest::qWait(100); + // No crash, all fine. +} #endif // Q_OS_MACOS QTEST_MAIN(tst_QMenuBar) From 093e1111ef68a8a83e42d5d82fc9d5c93d47071b Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 5 Dec 2016 14:38:12 -0800 Subject: [PATCH 26/74] QCocoaMenu: Don't rely on tags when we can get the actual NSMenuItem -[NSMenu itemWithTag:] clearly states that it'll return the first item with that tag. Furthermore, when and item has been synced more than once, it could be that more than one such item exists in the same menu (e.g. lately changing the role of Edit->Copy). Change-Id: I95a4f0a151659ae273ba03a3cab4a720b781fc3a Task-number: QTBUG-57404 Reviewed-by: Jake Petroules --- src/plugins/platforms/cocoa/qcocoamenu.mm | 5 ++--- tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 915463a52a..81db919627 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -419,9 +419,8 @@ void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem) return; } - bool wasMerged = cocoaItem->isMerged(); - NSMenu *oldMenu = wasMerged ? [[QCocoaMenuLoader sharedMenuLoader] applicationMenu] : m_nativeMenu; - NSMenuItem *oldItem = [oldMenu itemWithTag:(NSInteger) cocoaItem]; + const bool wasMerged = cocoaItem->isMerged(); + NSMenuItem *oldItem = cocoaItem->nsItem(); if (cocoaItem->sync() != oldItem) { // native item was changed for some reason diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp index 2c20d03066..d863f70125 100644 --- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp @@ -1560,11 +1560,10 @@ void tst_QMenuBar::QTBUG_57404_existingMenuItemException() QVERIFY(QTest::qWaitForWindowExposed(&mw2)); QTest::qWait(100); - QTest::ignoreMessage(QtWarningMsg, "Menu item \"&Copy\" already in menu \"Edit\""); mw2.close(); mw1.activateWindow(); QTest::qWait(100); - // No crash, all fine. + // No crash, all fine. Ideally, there should be only one warning. } #endif // Q_OS_MACOS From e1a70ce495928e8d81e80b11d7dbd4c4913ee438 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 6 Dec 2016 17:54:47 -0800 Subject: [PATCH 27/74] moc: force the Microsoft compiler not to define _MSC_EXTENSIONS This re-fixes commit d72ac3f35f4c6d6405e9675d54124b3ddb8d80ab, which simply removed the #define but did so at the wrong place. Instead of forcing the macro to be removed, let's simply not have it defined in the first place. Change-Id: Ie6dbad9bbbd9488887e8fffd148dd67d9a31b32e Reviewed-by: Jake Petroules --- mkspecs/features/moc.prf | 4 ++-- src/tools/moc/main.cpp | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index 4d3632531a..825c706950 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -31,10 +31,10 @@ if(gcc|intel_icl|msvc):!rim_qcc:!uikit { moc_predefs.name = "Generate moc_predefs.h" moc_predefs.CONFIG = no_link gcc: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -dM -E -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} - else:intel_icl: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -QdM -P -Fi${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} + else:intel_icl: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -QdM -P -Za -Fi${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} else:msvc { moc_predefs.commands += $$QMAKE_CXX -Bx$$shell_quote($$shell_path($$QMAKE_QMAKE)) $$QMAKE_CXXFLAGS \ - -E ${QMAKE_FILE_IN} 2>NUL >${QMAKE_FILE_OUT} + -E -Za ${QMAKE_FILE_IN} 2>NUL >${QMAKE_FILE_OUT} } else: error("Oops, I messed up") moc_predefs.output = $$MOC_DIR/moc_predefs.h moc_predefs.input = MOC_PREDEF_FILE diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp index 55cf7ed872..6128d5490b 100644 --- a/src/tools/moc/main.cpp +++ b/src/tools/moc/main.cpp @@ -477,9 +477,6 @@ int runMoc(int argc, char **argv) } moc.symbols += pp.preprocessed(moc.filename, &in); - // We obviously do not support MS extensions - pp.macros.remove("_MSC_EXTENSIONS"); - if (!pp.preprocessOnly) { // 2. parse moc.parse(); From 10143ea8030e6754b2021c84c30859ade79dc570 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 8 Dec 2016 10:00:21 +0100 Subject: [PATCH 28/74] QPointingDeviceUniqueId: remove deprecated numeric() and constructor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Followup to 0484473: this is all new stuff for 5.8 and we don't need to release it with pre-deprecated functions. Task-number: QTBUG-54616 Change-Id: If17a4bec6fc36ca78d87517992374f101ae13b4f Reviewed-by: Jan Arve Sæther --- src/gui/kernel/qevent.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 7d5b719e09..7881df205a 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -796,10 +796,6 @@ inline bool operator==(QKeySequence::StandardKey key, QKeyEvent *e){return (e ? class Q_GUI_EXPORT QPointingDeviceUniqueId { Q_GADGET - // ### kept these to keep other modules compiling. Remove before 5.8.0 final! -#if QT_DEPRECATED_SINCE(5, 8) - Q_PROPERTY(qint64 numeric READ numericId CONSTANT) -#endif Q_PROPERTY(qint64 numericId READ numericId CONSTANT) public: Q_ALWAYS_INLINE @@ -812,11 +808,6 @@ public: Q_ALWAYS_INLINE Q_DECL_CONSTEXPR bool isValid() const Q_DECL_NOTHROW { return m_numericId != -1; } qint64 numericId() const Q_DECL_NOTHROW; - // ### kept these to keep other modules compiling. Remove before 5.8.0 final! -#if QT_DEPRECATED_SINCE(5, 8) - Q_ALWAYS_INLINE Q_DECL_DEPRECATED qint64 numeric() const { return numericId(); } - Q_ALWAYS_INLINE Q_DECL_DEPRECATED explicit QPointingDeviceUniqueId(qint64 id) : m_numericId(id) {} -#endif private: // TODO: for TUIO 2, or any other type of complex token ID, an internal // array (or hash) can be added to hold additional properties. From 181860e1afa2f071a9cfcbf4d39b8526e9330ae2 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 24 Nov 2016 15:09:25 +0100 Subject: [PATCH 29/74] winrt: Fix input grabbing Beside its usage in widgets, mouse grabs are required for QML menus to work. Task-number: QTBUG-57079 Change-Id: I306cb68624186da69725470e147bc7b979dac8e4 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 76 +++++++++++++++++++- src/plugins/platforms/winrt/qwinrtscreen.h | 7 ++ src/plugins/platforms/winrt/qwinrtwindow.cpp | 23 ++++++ src/plugins/platforms/winrt/qwinrtwindow.h | 3 + 4 files changed, 106 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 6d4edcc8dc..f87ae9fd24 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -486,6 +486,9 @@ public: QHash view2Tokens; ComPtr view2; #endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + QAtomicPointer mouseGrabWindow; + QAtomicPointer keyboardGrabWindow; + QWindow *currentPressWindow = 0; }; // To be called from the XAML thread @@ -877,6 +880,44 @@ void QWinRTScreen::lower(QWindow *window) handleExpose(); } +bool QWinRTScreen::setMouseGrabWindow(QWinRTWindow *window, bool grab) +{ + Q_D(QWinRTScreen); + qCDebug(lcQpaWindows) << __FUNCTION__ << window + << "(" << window->window()->objectName() << "):" << grab; + + if (!grab || window == nullptr) + d->mouseGrabWindow = nullptr; + else if (d->mouseGrabWindow != window) + d->mouseGrabWindow = window; + return grab; +} + +QWinRTWindow *QWinRTScreen::mouseGrabWindow() const +{ + Q_D(const QWinRTScreen); + return d->mouseGrabWindow; +} + +bool QWinRTScreen::setKeyboardGrabWindow(QWinRTWindow *window, bool grab) +{ + Q_D(QWinRTScreen); + qCDebug(lcQpaWindows) << __FUNCTION__ << window + << "(" << window->window()->objectName() << "):" << grab; + + if (!grab || window == nullptr) + d->keyboardGrabWindow = nullptr; + else if (d->keyboardGrabWindow != window) + d->keyboardGrabWindow = window; + return grab; +} + +QWinRTWindow *QWinRTScreen::keyboardGrabWindow() const +{ + Q_D(const QWinRTScreen); + return d->keyboardGrabWindow; +} + void QWinRTScreen::updateWindowTitle(const QString &title) { Q_D(QWinRTScreen); @@ -1022,7 +1063,11 @@ HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args) pointerPoint->get_Position(&point); QPoint pos(point.X * d->scaleFactor, point.Y * d->scaleFactor); - QWindowSystemInterface::handleEnterEvent(topWindow(), pos, pos); + QWindow *targetWindow = topWindow(); + if (d->mouseGrabWindow) + targetWindow = d->mouseGrabWindow.load()->window(); + + QWindowSystemInterface::handleEnterEvent(targetWindow, pos, pos); } return S_OK; } @@ -1041,7 +1086,11 @@ HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *args) d->touchPoints.remove(id); - QWindowSystemInterface::handleLeaveEvent(0); + QWindow *targetWindow = nullptr; + if (d->mouseGrabWindow) + targetWindow = d->mouseGrabWindow.load()->window(); + + QWindowSystemInterface::handleLeaveEvent(targetWindow); return S_OK; } @@ -1063,7 +1112,12 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) QPointF localPos = pos; const QPoint posPoint = pos.toPoint(); - QWindow *targetWindow = windowAt(posPoint); + QWindow *windowUnderPointer = windowAt(posPoint); + QWindow *targetWindow = windowUnderPointer; + + if (d->mouseGrabWindow) + targetWindow = d->mouseGrabWindow.load()->window(); + if (targetWindow) { const QPointF globalPosDelta = pos - posPoint; localPos = targetWindow->mapFromGlobal(posPoint) + globalPosDelta; @@ -1127,6 +1181,22 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) if (isPressed) buttons |= Qt::XButton2; + // In case of a mouse grab we have to store the target of a press event + // to be able to send one additional release event to this target when the mouse + // button is released. This is a similar approach to AutoMouseCapture in the + // windows qpa backend. Otherwise the release might not be propagated and the original + // press event receiver considers a button to still be pressed, as in Qt Quick Controls 1 + // menus. + if (buttons != Qt::NoButton && d->currentPressWindow == nullptr && !d->mouseGrabWindow) + d->currentPressWindow = windowUnderPointer; + if (!isPressed && d->currentPressWindow && d->mouseGrabWindow) { + const QPointF globalPosDelta = pos - posPoint; + const QPointF localPressPos = d->currentPressWindow->mapFromGlobal(posPoint) + globalPosDelta; + + QWindowSystemInterface::handleMouseEvent(d->currentPressWindow, localPressPos, pos, buttons, mods); + d->currentPressWindow = nullptr; + } + QWindowSystemInterface::handleMouseEvent(targetWindow, localPos, pos, buttons, mods); break; diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index e489e208d5..04ab985699 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -83,6 +83,7 @@ class QTouchDevice; class QWinRTCursor; class QWinRTInputContext; class QWinRTScreenPrivate; +class QWinRTWindow; class QWinRTScreen : public QPlatformScreen { public: @@ -110,6 +111,12 @@ public: void raise(QWindow *window); void lower(QWindow *window); + bool setMouseGrabWindow(QWinRTWindow *window, bool grab); + QWinRTWindow* mouseGrabWindow() const; + + bool setKeyboardGrabWindow(QWinRTWindow *window, bool grab); + QWinRTWindow* keyboardGrabWindow() const; + void updateWindowTitle(const QString &title); ABI::Windows::UI::Core::ICoreWindow *coreWindow() const; diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index 297e6618d1..8f3b86ff3b 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -191,6 +191,11 @@ QWinRTWindow::~QWinRTWindow() }); RETURN_VOID_IF_FAILED("Failed to completely destroy window resources, likely because the application is shutting down"); + if (d->screen->mouseGrabWindow() == this) + d->screen->setMouseGrabWindow(this, false); + if (d->screen->keyboardGrabWindow() == this) + d->screen->setKeyboardGrabWindow(this, false); + d->screen->removeWindow(window()); if (!d->surface) @@ -384,6 +389,24 @@ void QWinRTWindow::setWindowState(Qt::WindowState state) d->state = state; } +bool QWinRTWindow::setMouseGrabEnabled(bool grab) +{ + Q_D(QWinRTWindow); + if (!isActive() && grab) { + qWarning("%s: Not setting mouse grab for invisible window %s/'%s'", + __FUNCTION__, window()->metaObject()->className(), + qPrintable(window()->objectName())); + return false; + } + return d->screen->setMouseGrabWindow(this, grab); +} + +bool QWinRTWindow::setKeyboardGrabEnabled(bool grab) +{ + Q_D(QWinRTWindow); + return d->screen->setKeyboardGrabWindow(this, grab); +} + EGLSurface QWinRTWindow::eglSurface() const { Q_D(const QWinRTWindow); diff --git a/src/plugins/platforms/winrt/qwinrtwindow.h b/src/plugins/platforms/winrt/qwinrtwindow.h index 48e092d455..35a4c493b6 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.h +++ b/src/plugins/platforms/winrt/qwinrtwindow.h @@ -70,6 +70,9 @@ public: qreal devicePixelRatio() const Q_DECL_OVERRIDE; void setWindowState(Qt::WindowState state) Q_DECL_OVERRIDE; + bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE; + bool setKeyboardGrabEnabled(bool grab) Q_DECL_OVERRIDE; + EGLSurface eglSurface() const; void createEglSurface(EGLDisplay display, EGLConfig config); From 84ea00d47049d882f2fabf1446ec6c6eb5fe3038 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 6 Dec 2016 16:30:31 +0100 Subject: [PATCH 30/74] QGtk3Dialog: don't crash on Wayland Check if it's an X11 window before calling XSetTransientForHint(). No transient parent will be set for GTK+ dialogs on Wayland. That has to be implemented separately. Task-number: QTBUG-55583 Change-Id: Iabc2a72681c8157bb2f2fe500892853aa397106b Reviewed-by: Dmitry Shachnev Reviewed-by: Shawn Rutledge --- src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp index ba5089a8bc..699b058932 100644 --- a/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp +++ b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp @@ -135,10 +135,12 @@ bool QGtk3Dialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWind GdkWindow *gdkWindow = gtk_widget_get_window(gtkWidget); if (parent) { - GdkDisplay *gdkDisplay = gdk_window_get_display(gdkWindow); - XSetTransientForHint(gdk_x11_display_get_xdisplay(gdkDisplay), - gdk_x11_window_get_xid(gdkWindow), - parent->winId()); + if (GDK_IS_X11_WINDOW(gdkWindow)) { + GdkDisplay *gdkDisplay = gdk_window_get_display(gdkWindow); + XSetTransientForHint(gdk_x11_display_get_xdisplay(gdkDisplay), + gdk_x11_window_get_xid(gdkWindow), + parent->winId()); + } } if (modality != Qt::NonModal) { From c483945cf45547d3533674527470788809c79bfb Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 8 Dec 2016 12:31:58 +0100 Subject: [PATCH 31/74] REG: Fix missing glyphs with DirectWrite and stretch == QFont::AnyStretch A stretch equal to 0 is since 5.8 defined as "accept the stretch of the font", and this needs to be accounted for in the font engines. Task-number: QTBUG-57491 Change-Id: Idabbe44677c4b92cbd8ad8278b054de53e9cc7f9 Reviewed-by: Simon Hausmann Reviewed-by: Alessandro Portale Reviewed-by: Allan Sandfeld Jensen --- .../fontdatabases/windows/qwindowsfontenginedirectwrite.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp index 6130107cc8..683b7f65ad 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp @@ -663,7 +663,7 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t, glyphRun.glyphOffsets = &glyphOffset; QTransform xform = originalTransform; - if (fontDef.stretch != 100) + if (fontDef.stretch != 100 && fontDef.stretch != QFont::AnyStretch) xform.scale(fontDef.stretch / 100.0, 1.0); DWRITE_MATRIX transform; @@ -933,7 +933,7 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph Q_UNUSED(format); QTransform matrix = originalTransform; - if (fontDef.stretch != 100) + if (fontDef.stretch != 100 && fontDef.stretch != QFont::AnyStretch) matrix.scale(fontDef.stretch / 100.0, 1.0); glyph_metrics_t bbox = QFontEngine::boundingBox(glyph, matrix); // To get transformed advance From 2d1378836c90ab245290e4b4884bc1ad9e256d5c Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 7 Dec 2016 10:51:39 +0200 Subject: [PATCH 32/74] Android: remove unused variable Fix compilation with -Werror Change-Id: Iae6068f9eeb92dd1a96b11f6bb7017b97a8486fb Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/android/androidjniaccessibility.cpp | 1 - src/plugins/platforms/android/androidjnimain.cpp | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index a987092862..3b1ce6d21d 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -54,7 +54,6 @@ static const char m_qtTag[] = "Qt A11Y"; static const char m_classErrorMsg[] = "Can't find class \"%s\""; -static const char m_methodErrorMsg[] = "Can't find method \"%s%s\""; QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index df8883ab34..1f681cc1a3 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -122,8 +122,6 @@ static int m_desktopHeightPixels = 0; static double m_scaledDensity = 0; static double m_density = 1.0; -static volatile bool m_pauseApplication; - static AndroidAssetsFileEngineHandler *m_androidAssetsFileEngineHandler = nullptr; From a76579d95654c75228058bbc62df9b9c7dc04d9b Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Sun, 27 Nov 2016 11:00:50 +0300 Subject: [PATCH 33/74] Android: Add missing override Change-Id: I70b802517d8f7d129ffb71dc3e92cb2458a55acc Reviewed-by: BogDan Vatra (cherry picked from commit e3ad43843a6ddb20c901b6fba85c12fb0e6c5651) Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../android/androidplatformplugin.cpp | 2 +- .../qandroidassetsfileenginehandler.cpp | 34 +++++++++---------- .../android/qandroidassetsfileenginehandler.h | 2 +- .../android/qandroideventdispatcher.h | 2 +- .../platforms/android/qandroidinputcontext.h | 22 ++++++------ .../android/qandroidplatformaccessibility.h | 2 +- .../android/qandroidplatformbackingstore.h | 8 ++--- .../android/qandroidplatformclipboard.h | 6 ++-- .../android/qandroidplatformdialoghelpers.h | 8 ++--- .../android/qandroidplatformfontdatabase.h | 10 +++--- .../android/qandroidplatformintegration.h | 34 +++++++++---------- .../platforms/android/qandroidplatformmenu.h | 28 +++++++-------- .../android/qandroidplatformmenubar.h | 10 +++--- .../android/qandroidplatformmenuitem.h | 28 +++++++-------- .../android/qandroidplatformopenglcontext.h | 6 ++-- .../android/qandroidplatformopenglwindow.h | 8 ++--- .../android/qandroidplatformscreen.h | 22 ++++++------ .../android/qandroidplatformservices.h | 6 ++-- .../platforms/android/qandroidplatformtheme.h | 18 +++++----- .../android/qandroidplatformwindow.h | 22 ++++++------ .../platforms/android/qandroidsystemlocale.h | 4 +-- 21 files changed, 141 insertions(+), 141 deletions(-) diff --git a/src/plugins/platforms/android/androidplatformplugin.cpp b/src/plugins/platforms/android/androidplatformplugin.cpp index 8e365e9a59..297e167f47 100644 --- a/src/plugins/platforms/android/androidplatformplugin.cpp +++ b/src/plugins/platforms/android/androidplatformplugin.cpp @@ -47,7 +47,7 @@ class QAndroidPlatformIntegrationPlugin: public QPlatformIntegrationPlugin Q_OBJECT Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "android.json") public: - QPlatformIntegration *create(const QString &key, const QStringList ¶mList); + QPlatformIntegration *create(const QString &key, const QStringList ¶mList) override; }; diff --git a/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp b/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp index 7e8e1ba9c5..e1dcebfa4c 100644 --- a/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp +++ b/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp @@ -75,12 +75,12 @@ public: m_path = path; } - virtual QFileInfo currentFileInfo() const + QFileInfo currentFileInfo() const override { return QFileInfo(currentFilePath()); } - virtual QString currentFileName() const + QString currentFileName() const override { if (m_index < 0 || m_index >= m_items.size()) return QString(); @@ -95,12 +95,12 @@ public: return m_path + currentFileName(); } - virtual bool hasNext() const + bool hasNext() const override { return m_items.size() && (m_index < m_items.size() - 1); } - virtual QString next() + QString next() override { if (!hasNext()) return QString(); @@ -137,12 +137,12 @@ public: close(); } - virtual bool open(QIODevice::OpenMode openMode) + bool open(QIODevice::OpenMode openMode) override { return m_assetFile != 0 && (openMode & QIODevice::WriteOnly) == 0; } - virtual bool close() + bool close() override { if (m_assetFile) { AAsset_close(m_assetFile); @@ -152,50 +152,50 @@ public: return false; } - virtual qint64 size() const + qint64 size() const override { if (m_assetFile) return AAsset_getLength(m_assetFile); return -1; } - virtual qint64 pos() const + qint64 pos() const override { if (m_assetFile) return AAsset_seek(m_assetFile, 0, SEEK_CUR); return -1; } - virtual bool seek(qint64 pos) + bool seek(qint64 pos) override { if (m_assetFile) return pos == AAsset_seek(m_assetFile, pos, SEEK_SET); return false; } - virtual qint64 read(char *data, qint64 maxlen) + qint64 read(char *data, qint64 maxlen) override { if (m_assetFile) return AAsset_read(m_assetFile, data, maxlen); return -1; } - virtual bool isSequential() const + bool isSequential() const override { return false; } - virtual bool caseSensitive() const + bool caseSensitive() const override { return true; } - virtual bool isRelativePath() const + bool isRelativePath() const override { return false; } - virtual FileFlags fileFlags(FileFlags type = FileInfoAll) const + FileFlags fileFlags(FileFlags type = FileInfoAll) const override { FileFlags flags(ReadOwnerPerm|ReadUserPerm|ReadGroupPerm|ReadOtherPerm|ExistsFlag); if (m_assetFile) @@ -206,7 +206,7 @@ public: return type & flags; } - virtual QString fileName(FileName file = DefaultName) const + QString fileName(FileName file = DefaultName) const override { int pos; switch (file) { @@ -231,7 +231,7 @@ public: } } - virtual void setFileName(const QString &file) + void setFileName(const QString &file) override { if (file == m_fileName) return; @@ -243,7 +243,7 @@ public: close(); } - virtual Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) + Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) override { if (!m_assetDir.isNull()) return new AndroidAbstractFileEngineIterator(filters, filterNames, m_assetDir, m_fileName); diff --git a/src/plugins/platforms/android/qandroidassetsfileenginehandler.h b/src/plugins/platforms/android/qandroidassetsfileenginehandler.h index b09d8090a4..f99dc9a11a 100644 --- a/src/plugins/platforms/android/qandroidassetsfileenginehandler.h +++ b/src/plugins/platforms/android/qandroidassetsfileenginehandler.h @@ -55,7 +55,7 @@ class AndroidAssetsFileEngineHandler: public QAbstractFileEngineHandler public: AndroidAssetsFileEngineHandler(); virtual ~AndroidAssetsFileEngineHandler(); - QAbstractFileEngine *create(const QString &fileName) const; + QAbstractFileEngine *create(const QString &fileName) const override; private: void prepopulateCache() const; diff --git a/src/plugins/platforms/android/qandroideventdispatcher.h b/src/plugins/platforms/android/qandroideventdispatcher.h index 86a7e460b3..057a1660c9 100644 --- a/src/plugins/platforms/android/qandroideventdispatcher.h +++ b/src/plugins/platforms/android/qandroideventdispatcher.h @@ -56,7 +56,7 @@ public: void goingToStop(bool stop); protected: - bool processEvents(QEventLoop::ProcessEventsFlags flags); + bool processEvents(QEventLoop::ProcessEventsFlags flags) override; private: QAtomicInt m_stopRequest; diff --git a/src/plugins/platforms/android/qandroidinputcontext.h b/src/plugins/platforms/android/qandroidinputcontext.h index 8a33ff71cc..ce0ec8724c 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.h +++ b/src/plugins/platforms/android/qandroidinputcontext.h @@ -80,21 +80,21 @@ public: QAndroidInputContext(); ~QAndroidInputContext(); static QAndroidInputContext * androidInputContext(); - bool isValid() const { return true; } + bool isValid() const override { return true; } - void reset(); - void commit(); - void update(Qt::InputMethodQueries queries); - void invokeAction(QInputMethod::Action action, int cursorPosition); - QRectF keyboardRect() const; - bool isAnimating() const; - void showInputPanel(); - void hideInputPanel(); - bool isInputPanelVisible() const; + void reset() override; + void commit() override; + void update(Qt::InputMethodQueries queries) override; + void invokeAction(QInputMethod::Action action, int cursorPosition) override; + QRectF keyboardRect() const override; + bool isAnimating() const override; + void showInputPanel() override; + void hideInputPanel() override; + bool isInputPanelVisible() const override; bool isComposing() const; void clear(); - void setFocusObject(QObject *object); + void setFocusObject(QObject *object) override; void sendShortcut(const QKeySequence &); //---------------// diff --git a/src/plugins/platforms/android/qandroidplatformaccessibility.h b/src/plugins/platforms/android/qandroidplatformaccessibility.h index 3a428ca1ad..8216c05fa6 100644 --- a/src/plugins/platforms/android/qandroidplatformaccessibility.h +++ b/src/plugins/platforms/android/qandroidplatformaccessibility.h @@ -51,7 +51,7 @@ public: QAndroidPlatformAccessibility(); ~QAndroidPlatformAccessibility(); - virtual void notifyAccessibilityUpdate(QAccessibleEvent *event); + void notifyAccessibilityUpdate(QAccessibleEvent *event) override; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/qandroidplatformbackingstore.h b/src/plugins/platforms/android/qandroidplatformbackingstore.h index e4a161d608..a3a65aa30e 100644 --- a/src/plugins/platforms/android/qandroidplatformbackingstore.h +++ b/src/plugins/platforms/android/qandroidplatformbackingstore.h @@ -50,10 +50,10 @@ class QAndroidPlatformBackingStore : public QPlatformBackingStore { public: explicit QAndroidPlatformBackingStore(QWindow *window); - virtual QPaintDevice *paintDevice(); - virtual void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); - virtual void resize(const QSize &size, const QRegion &staticContents); - QImage toImage() const { return m_image; } + QPaintDevice *paintDevice() override; + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) override; + void resize(const QSize &size, const QRegion &staticContents) override; + QImage toImage() const override { return m_image; } void setBackingStore(QWindow *window); protected: QImage m_image; diff --git a/src/plugins/platforms/android/qandroidplatformclipboard.h b/src/plugins/platforms/android/qandroidplatformclipboard.h index 47976c1693..dfc3629c10 100644 --- a/src/plugins/platforms/android/qandroidplatformclipboard.h +++ b/src/plugins/platforms/android/qandroidplatformclipboard.h @@ -51,9 +51,9 @@ class QAndroidPlatformClipboard: public QPlatformClipboard public: QAndroidPlatformClipboard(); - virtual QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard); - virtual void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard); - virtual bool supportsMode(QClipboard::Mode mode) const; + QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) override; + void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) override; + bool supportsMode(QClipboard::Mode mode) const override; private: QMimeData m_mimeData; diff --git a/src/plugins/platforms/android/qandroidplatformdialoghelpers.h b/src/plugins/platforms/android/qandroidplatformdialoghelpers.h index 5c3aef2bc1..694b4c7580 100644 --- a/src/plugins/platforms/android/qandroidplatformdialoghelpers.h +++ b/src/plugins/platforms/android/qandroidplatformdialoghelpers.h @@ -53,11 +53,11 @@ class QAndroidPlatformMessageDialogHelper: public QPlatformMessageDialogHelper Q_OBJECT public: QAndroidPlatformMessageDialogHelper(); - void exec(); + void exec() override; bool show(Qt::WindowFlags windowFlags, - Qt::WindowModality windowModality, - QWindow *parent); - void hide(); + Qt::WindowModality windowModality, + QWindow *parent) override; + void hide() override; public slots: void dialogResult(int buttonID); diff --git a/src/plugins/platforms/android/qandroidplatformfontdatabase.h b/src/plugins/platforms/android/qandroidplatformfontdatabase.h index b20fd75cb2..533d6e50a9 100644 --- a/src/plugins/platforms/android/qandroidplatformfontdatabase.h +++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.h @@ -47,12 +47,12 @@ QT_BEGIN_NAMESPACE class QAndroidPlatformFontDatabase: public QBasicFontDatabase { public: - QString fontDir() const; - void populateFontDatabase(); + QString fontDir() const override; + void populateFontDatabase() override; QStringList fallbacksForFamily(const QString &family, - QFont::Style style, - QFont::StyleHint styleHint, - QChar::Script script) const; + QFont::Style style, + QFont::StyleHint styleHint, + QChar::Script script) const override; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h index bda0bee9ad..2337801250 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.h +++ b/src/plugins/platforms/android/qandroidplatformintegration.h @@ -63,7 +63,7 @@ struct AndroidStyle; class QAndroidPlatformNativeInterface: public QPlatformNativeInterface { public: - void *nativeResourceForIntegration(const QByteArray &resource); + void *nativeResourceForIntegration(const QByteArray &resource) override; std::shared_ptr m_androidStyle; }; @@ -75,39 +75,39 @@ public: QAndroidPlatformIntegration(const QStringList ¶mList); ~QAndroidPlatformIntegration(); - bool hasCapability(QPlatformIntegration::Capability cap) const; + bool hasCapability(QPlatformIntegration::Capability cap) const override; - QPlatformWindow *createPlatformWindow(QWindow *window) const; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; - QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; - QAbstractEventDispatcher *createEventDispatcher() const; + QPlatformWindow *createPlatformWindow(QWindow *window) const override; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override; + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; + QAbstractEventDispatcher *createEventDispatcher() const override; QAndroidPlatformScreen *screen() { return m_primaryScreen; } - QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const; + QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override; virtual void setDesktopSize(int width, int height); virtual void setDisplayMetrics(int width, int height); void setScreenSize(int width, int height); bool isVirtualDesktop() { return true; } - QPlatformFontDatabase *fontDatabase() const; + QPlatformFontDatabase *fontDatabase() const override; #ifndef QT_NO_CLIPBOARD - QPlatformClipboard *clipboard() const; + QPlatformClipboard *clipboard() const override; #endif - QPlatformInputContext *inputContext() const; - QPlatformNativeInterface *nativeInterface() const; - QPlatformServices *services() const; + QPlatformInputContext *inputContext() const override; + QPlatformNativeInterface *nativeInterface() const override; + QPlatformServices *services() const override; #ifndef QT_NO_ACCESSIBILITY - virtual QPlatformAccessibility *accessibility() const; + virtual QPlatformAccessibility *accessibility() const override; #endif - QVariant styleHint(StyleHint hint) const; - Qt::WindowState defaultWindowState(Qt::WindowFlags flags) const; + QVariant styleHint(StyleHint hint) const override; + Qt::WindowState defaultWindowState(Qt::WindowFlags flags) const override; - QStringList themeNames() const; - QPlatformTheme *createPlatformTheme(const QString &name) const; + QStringList themeNames() const override; + QPlatformTheme *createPlatformTheme(const QString &name) const override; static void setDefaultDisplayMetrics(int gw, int gh, int sw, int sh, int width, int height); static void setDefaultDesktopSize(int gw, int gh); diff --git a/src/plugins/platforms/android/qandroidplatformmenu.h b/src/plugins/platforms/android/qandroidplatformmenu.h index cb1b431d31..00968672c5 100644 --- a/src/plugins/platforms/android/qandroidplatformmenu.h +++ b/src/plugins/platforms/android/qandroidplatformmenu.h @@ -56,25 +56,25 @@ public: QAndroidPlatformMenu(); ~QAndroidPlatformMenu(); - void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before); - void removeMenuItem(QPlatformMenuItem *menuItem); - void syncMenuItem(QPlatformMenuItem *menuItem); - void syncSeparatorsCollapsible(bool enable); + void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) override; + void removeMenuItem(QPlatformMenuItem *menuItem) override; + void syncMenuItem(QPlatformMenuItem *menuItem) override; + void syncSeparatorsCollapsible(bool enable) override; - void setTag(quintptr tag); - quintptr tag() const; - void setText(const QString &text); + void setTag(quintptr tag) override; + quintptr tag() const override; + void setText(const QString &text) override; QString text() const; - void setIcon(const QIcon &icon); + void setIcon(const QIcon &icon) override; QIcon icon() const; - void setEnabled(bool enabled); - bool isEnabled() const; - void setVisible(bool visible); + void setEnabled(bool enabled) override; + bool isEnabled() const override; + void setVisible(bool visible) override; bool isVisible() const; - void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item); + void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) override; - QPlatformMenuItem *menuItemAt(int position) const; - QPlatformMenuItem *menuItemForTag(quintptr tag) const; + QPlatformMenuItem *menuItemAt(int position) const override; + QPlatformMenuItem *menuItemForTag(quintptr tag) const override; PlatformMenuItemsType menuItems() const; QMutex *menuItemsMutex(); diff --git a/src/plugins/platforms/android/qandroidplatformmenubar.h b/src/plugins/platforms/android/qandroidplatformmenubar.h index d98d02d5de..0316ea9362 100644 --- a/src/plugins/platforms/android/qandroidplatformmenubar.h +++ b/src/plugins/platforms/android/qandroidplatformmenubar.h @@ -55,11 +55,11 @@ public: QAndroidPlatformMenuBar(); ~QAndroidPlatformMenuBar(); - void insertMenu(QPlatformMenu *menu, QPlatformMenu *before); - void removeMenu(QPlatformMenu *menu); - void syncMenu(QPlatformMenu *menu); - void handleReparent(QWindow *newParentWindow); - QPlatformMenu *menuForTag(quintptr tag) const; + void insertMenu(QPlatformMenu *menu, QPlatformMenu *before) override; + void removeMenu(QPlatformMenu *menu) override; + void syncMenu(QPlatformMenu *menu) override; + void handleReparent(QWindow *newParentWindow) override; + QPlatformMenu *menuForTag(quintptr tag) const override; QWindow *parentWindow() const; PlatformMenusType menus() const; diff --git a/src/plugins/platforms/android/qandroidplatformmenuitem.h b/src/plugins/platforms/android/qandroidplatformmenuitem.h index e843c9eedc..be5240cfa6 100644 --- a/src/plugins/platforms/android/qandroidplatformmenuitem.h +++ b/src/plugins/platforms/android/qandroidplatformmenuitem.h @@ -49,41 +49,41 @@ class QAndroidPlatformMenuItem: public QPlatformMenuItem { public: QAndroidPlatformMenuItem(); - void setTag(quintptr tag); - quintptr tag() const; + void setTag(quintptr tag) override; + quintptr tag() const override; - void setText(const QString &text); + void setText(const QString &text) override; QString text() const; - void setIcon(const QIcon &icon); + void setIcon(const QIcon &icon) override; QIcon icon() const; - void setMenu(QPlatformMenu *menu); + void setMenu(QPlatformMenu *menu) override; QAndroidPlatformMenu *menu() const; - void setVisible(bool isVisible); + void setVisible(bool isVisible) override; bool isVisible() const; - void setIsSeparator(bool isSeparator); + void setIsSeparator(bool isSeparator) override; bool isSeparator() const; - void setFont(const QFont &font); + void setFont(const QFont &font) override; - void setRole(MenuRole role); + void setRole(MenuRole role) override; MenuRole role() const; - void setCheckable(bool checkable); + void setCheckable(bool checkable) override; bool isCheckable() const; - void setChecked(bool isChecked); + void setChecked(bool isChecked) override; bool isChecked() const; - void setShortcut(const QKeySequence &shortcut); + void setShortcut(const QKeySequence &shortcut) override; - void setEnabled(bool enabled); + void setEnabled(bool enabled) override; bool isEnabled() const; - void setIconSize(int size); + void setIconSize(int size) override; private: quintptr m_tag; diff --git a/src/plugins/platforms/android/qandroidplatformopenglcontext.h b/src/plugins/platforms/android/qandroidplatformopenglcontext.h index d3f6cf13a4..87a0829655 100644 --- a/src/plugins/platforms/android/qandroidplatformopenglcontext.h +++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.h @@ -49,11 +49,11 @@ class QAndroidPlatformOpenGLContext : public QEGLPlatformContext { public: QAndroidPlatformOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display); - void swapBuffers(QPlatformSurface *surface); - bool makeCurrent(QPlatformSurface *surface); + void swapBuffers(QPlatformSurface *surface) override; + bool makeCurrent(QPlatformSurface *surface) override; private: - virtual EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface); + EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) override; static bool needsFBOReadBackWorkaround(); }; diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.h b/src/plugins/platforms/android/qandroidplatformopenglwindow.h index c7cb881973..12e86b3db4 100644 --- a/src/plugins/platforms/android/qandroidplatformopenglwindow.h +++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.h @@ -56,18 +56,18 @@ public: explicit QAndroidPlatformOpenGLWindow(QWindow *window, EGLDisplay display); ~QAndroidPlatformOpenGLWindow(); - void setGeometry(const QRect &rect); + void setGeometry(const QRect &rect) override; EGLSurface eglSurface(EGLConfig config); - QSurfaceFormat format() const; + QSurfaceFormat format() const override; bool checkNativeSurface(EGLConfig config); - void applicationStateChanged(Qt::ApplicationState); + void applicationStateChanged(Qt::ApplicationState) override; void repaint(const QRegion ®ion) Q_DECL_OVERRIDE; protected: - virtual void surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h); + void surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h) override; void createEgl(EGLConfig config); void clearEgl(); diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h index 6e601d5f87..923c9e8832 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.h +++ b/src/plugins/platforms/android/qandroidplatformscreen.h @@ -63,14 +63,14 @@ public: QAndroidPlatformScreen(); ~QAndroidPlatformScreen(); - QRect geometry() const { return QRect(QPoint(), m_size); } - QRect availableGeometry() const { return m_availableGeometry; } - int depth() const { return m_depth; } - QImage::Format format() const { return m_format; } - QSizeF physicalSize() const { return m_physicalSize; } + QRect geometry() const override { return QRect(QPoint(), m_size); } + QRect availableGeometry() const override { return m_availableGeometry; } + int depth() const override { return m_depth; } + QImage::Format format() const override { return m_format; } + QSizeF physicalSize() const override { return m_physicalSize; } inline QWindow *topWindow() const; - QWindow *topLevelAt(const QPoint & p) const; + QWindow *topLevelAt(const QPoint & p) const override; // compositor api void addWindow(QAndroidPlatformWindow *window); @@ -100,11 +100,11 @@ protected: QSizeF m_physicalSize; private: - QDpi logicalDpi() const; - qreal pixelDensity() const; - Qt::ScreenOrientation orientation() const; - Qt::ScreenOrientation nativeOrientation() const; - void surfaceChanged(JNIEnv *env, jobject surface, int w, int h); + QDpi logicalDpi() const override; + qreal pixelDensity() const override; + Qt::ScreenOrientation orientation() const override; + Qt::ScreenOrientation nativeOrientation() const override; + void surfaceChanged(JNIEnv *env, jobject surface, int w, int h) override; void releaseSurface(); void applicationStateChanged(Qt::ApplicationState); diff --git a/src/plugins/platforms/android/qandroidplatformservices.h b/src/plugins/platforms/android/qandroidplatformservices.h index 5cdc3e95b2..6f2f0a394f 100644 --- a/src/plugins/platforms/android/qandroidplatformservices.h +++ b/src/plugins/platforms/android/qandroidplatformservices.h @@ -49,9 +49,9 @@ class QAndroidPlatformServices: public QPlatformServices { public: QAndroidPlatformServices(); - bool openUrl(const QUrl &url); - bool openDocument(const QUrl &url); - QByteArray desktopEnvironment() const; + bool openUrl(const QUrl &url) override; + bool openDocument(const QUrl &url) override; + QByteArray desktopEnvironment() const override; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/qandroidplatformtheme.h b/src/plugins/platforms/android/qandroidplatformtheme.h index b4d8fa35b1..7405c3cdbd 100644 --- a/src/plugins/platforms/android/qandroidplatformtheme.h +++ b/src/plugins/platforms/android/qandroidplatformtheme.h @@ -65,16 +65,16 @@ class QAndroidPlatformTheme: public QPlatformTheme { public: QAndroidPlatformTheme(QAndroidPlatformNativeInterface * androidPlatformNativeInterface); - virtual QPlatformMenuBar *createPlatformMenuBar() const; - virtual QPlatformMenu *createPlatformMenu() const; - virtual QPlatformMenuItem *createPlatformMenuItem() const; - virtual void showPlatformMenuBar(); - virtual const QPalette *palette(Palette type = SystemPalette) const; - virtual const QFont *font(Font type = SystemFont) const; - virtual QVariant themeHint(ThemeHint hint) const; + QPlatformMenuBar *createPlatformMenuBar() const override; + QPlatformMenu *createPlatformMenu() const override; + QPlatformMenuItem *createPlatformMenuItem() const override; + void showPlatformMenuBar() override; + const QPalette *palette(Palette type = SystemPalette) const override; + const QFont *font(Font type = SystemFont) const override; + QVariant themeHint(ThemeHint hint) const override; QString standardButtonText(int button) const Q_DECL_OVERRIDE; - virtual bool usePlatformNativeDialog(DialogType type) const; - virtual QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const; + bool usePlatformNativeDialog(DialogType type) const override; + QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const override; private: diff --git a/src/plugins/platforms/android/qandroidplatformwindow.h b/src/plugins/platforms/android/qandroidplatformwindow.h index 8d69532d08..87e5cbaa4f 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.h +++ b/src/plugins/platforms/android/qandroidplatformwindow.h @@ -54,21 +54,21 @@ class QAndroidPlatformWindow: public QPlatformWindow public: explicit QAndroidPlatformWindow(QWindow *window); - void lower(); - void raise(); + void lower() override; + void raise() override; - void setVisible(bool visible); + void setVisible(bool visible) override; - void setWindowState(Qt::WindowState state); - void setWindowFlags(Qt::WindowFlags flags); + void setWindowState(Qt::WindowState state) override; + void setWindowFlags(Qt::WindowFlags flags) override; Qt::WindowFlags windowFlags() const; - void setParent(const QPlatformWindow *window); - WId winId() const { return m_windowId; } + void setParent(const QPlatformWindow *window) override; + WId winId() const override { return m_windowId; } QAndroidPlatformScreen *platformScreen() const; - void propagateSizeHints(); - void requestActivateWindow(); + void propagateSizeHints() override; + void requestActivateWindow() override; void updateStatusBarVisibility(); inline bool isRaster() const { if ((window()->flags() & Qt::ForeignWindow) == Qt::ForeignWindow) @@ -77,7 +77,7 @@ public: return window()->surfaceType() == QSurface::RasterSurface || window()->surfaceType() == QSurface::RasterGLSurface; } - bool isExposed() const; + bool isExposed() const override; virtual void applicationStateChanged(Qt::ApplicationState); @@ -87,7 +87,7 @@ public: virtual void repaint(const QRegion &) { } protected: - void setGeometry(const QRect &rect); + void setGeometry(const QRect &rect) override; protected: Qt::WindowFlags m_windowFlags; diff --git a/src/plugins/platforms/android/qandroidsystemlocale.h b/src/plugins/platforms/android/qandroidsystemlocale.h index 26af1ee51d..bc96d2e8f6 100644 --- a/src/plugins/platforms/android/qandroidsystemlocale.h +++ b/src/plugins/platforms/android/qandroidsystemlocale.h @@ -50,8 +50,8 @@ class QAndroidSystemLocale : public QSystemLocale public: QAndroidSystemLocale(); - virtual QVariant query(QueryType type, QVariant in) const; - virtual QLocale fallbackUiLocale() const; + QVariant query(QueryType type, QVariant in) const override; + QLocale fallbackUiLocale() const override; private: void getLocaleFromJava() const; From 5b8957247f5e2845dd9f59545ba567d051c4e436 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Fri, 9 Dec 2016 12:34:33 +0100 Subject: [PATCH 34/74] Doc: QPointingDeviceUniqueId: Fix documentation warning Fix the following warning by adding a const qualifier: warning: No documentation for 'QPointingDeviceUniqueId::isValid()' Change-Id: I1ebeda8f45e88efb7cb844b67409352c695e6354 Reviewed-by: Shawn Rutledge --- src/gui/kernel/qevent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index b198fa0832..219f782737 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -5216,7 +5216,7 @@ QPointingDeviceUniqueId QPointingDeviceUniqueId::fromNumericId(qint64 id) } /*! - \fn bool QPointingDeviceUniqueId::isValid() + \fn bool QPointingDeviceUniqueId::isValid() const Returns whether this unique pointer ID is valid, that is, it represents an actual pointer. From 4c0760d327e390a37d0d6ce2016d3a8c5b87a119 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 30 Nov 2016 15:29:45 -0800 Subject: [PATCH 35/74] Re-fix the build with ICC and cmath & math.h Commit c35fef9d3b8bb77a7f303e3cd62c86cd00e57f5b wasn't sufficient. The problem is that there's a complex combination of libc headers (math.h), C++ headers (cmath), which may be provided by three different sources on Linux (glibc, gcc and ICC). On some combinations, the isnan macro leaks from math.h or cmath and that's what the the commit above tried to fix. On some other combinations, there's no macro but there's an ::isnan function defined. When we do "using namespace std; return isnan(x);", that causes a compilation error. This commit solves that by detecting whether there is a macro defined. error: more than one instance of overloaded function "isnan" matches the argument list function "isnan(double)" function "std::isnan(double)" argument types are: (double) Change-Id: Iaeecaffe26af4535b416fffd148bf71826541bdd Reviewed-by: Thiago Macieira --- src/corelib/global/qnumeric_p.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index 23fcf340f1..01b8772ee1 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -68,7 +68,8 @@ #if !defined(Q_CC_MSVC) && (defined(Q_OS_QNX) || defined(Q_CC_INTEL) || !defined(__cplusplus)) # include -# define QT_MATH_H_DEFINES_MACROS +# ifdef isnan +# define QT_MATH_H_DEFINES_MACROS QT_BEGIN_NAMESPACE namespace qnumeric_std_wrapper { // the 'using namespace std' below is cases where the stdlib already put the math.h functions in the std namespace and undefined the macros. @@ -81,10 +82,11 @@ static inline bool math_h_isfinite(float f) { using namespace std; return isfini } QT_END_NAMESPACE // These macros from math.h conflict with the real functions in the std namespace. -#undef signbit -#undef isnan -#undef isinf -#undef isfinite +# undef signbit +# undef isnan +# undef isinf +# undef isfinite +# endif // defined(isnan) #endif QT_BEGIN_NAMESPACE From bb0f29f82b934b489f1679b7b72f094aa287be3c Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 12 Dec 2016 23:53:22 +0100 Subject: [PATCH 36/74] Fix gcc 6.4 builds The builtins clzs and ctzs have been removed. Additionally they were never proper internal GCC builtins and shouldn't have been used in a constexpr function in the first place. This patch removes the assumption that they exist when BMI is available, and let GCC fall back to using __builtin_clz and __builtin_ctz. Change-Id: I3e0b4e246098bb9ce6ede28b311948260ef881b9 Task-number: QTBUG-56813 Reviewed-by: Thiago Macieira --- src/corelib/tools/qalgorithms.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h index 303374b06d..51f73c3368 100644 --- a/src/corelib/tools/qalgorithms.h +++ b/src/corelib/tools/qalgorithms.h @@ -535,7 +535,7 @@ QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessItera # define QT_HAS_BUILTIN_CTZS Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_ctzs(quint16 v) Q_DECL_NOTHROW { -# if QT_HAS_BUILTIN(__builtin_ctzs) || defined(__BMI__) +# if QT_HAS_BUILTIN(__builtin_ctzs) return __builtin_ctzs(v); # else return __builtin_ctz(v); @@ -544,7 +544,7 @@ Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_ctzs(quint16 v) Q_DECL_NOTHROW #define QT_HAS_BUILTIN_CLZS Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_clzs(quint16 v) Q_DECL_NOTHROW { -# if QT_HAS_BUILTIN(__builtin_clzs) || defined(__BMI__) +# if QT_HAS_BUILTIN(__builtin_clzs) return __builtin_clzs(v); # else return __builtin_clz(v) - 16U; From 36e4b13e29ef055c2b05a526cb65529d88b03582 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 8 Dec 2016 13:42:16 +0200 Subject: [PATCH 37/74] Android: fix (partially) text deletion when the cursor is moved - wait until the handle location changes the cursor position - don't update cursor position if: * a batchEdit is in progress * the UpdateSelection is blocked - finish the composing before update the cursor - add the missing .java files There are still corner situations when the text gets deleted/moved, but those are pretty rare and they will be fix in another patch. Task-number: QTBUG-57507 Change-Id: I230d7f64625fb556e1be3069694a71e9bc91323a Reviewed-by: Paul Olav Tvete --- src/android/jar/jar.pri | 4 +++- src/plugins/platforms/android/androidjniinput.cpp | 2 +- src/plugins/platforms/android/qandroidinputcontext.cpp | 5 +++++ src/plugins/platforms/android/qandroidinputcontext.h | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/android/jar/jar.pri b/src/android/jar/jar.pri index 58caacb837..4535880536 100644 --- a/src/android/jar/jar.pri +++ b/src/android/jar/jar.pri @@ -17,7 +17,9 @@ JAVASOURCES += \ $$PATHPREFIX/QtNativeLibrariesDir.java \ $$PATHPREFIX/QtSurface.java \ $$PATHPREFIX/ExtractStyle.java \ - $$PATHPREFIX/QtServiceDelegate.java + $$PATHPREFIX/EditMenu.java \ + $$PATHPREFIX/EditPopupMenu.java \ + $$PATHPREFIX/CursorHandle.java # install target.path = $$[QT_INSTALL_PREFIX]/jar diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp index 5f05ab395e..d3bb089aa4 100644 --- a/src/plugins/platforms/android/androidjniinput.cpp +++ b/src/plugins/platforms/android/androidjniinput.cpp @@ -810,7 +810,7 @@ namespace QtAndroidInput #endif QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext(); if (inputContext && qGuiApp) - QMetaObject::invokeMethod(inputContext, "handleLocationChanged", + QMetaObject::invokeMethod(inputContext, "handleLocationChanged", Qt::BlockingQueuedConnection, Q_ARG(int, id), Q_ARG(int, x), Q_ARG(int, y)); } diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index 2656d45d5f..12e85046f8 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -578,6 +578,11 @@ void QAndroidInputContext::updateSelectionHandles() */ void QAndroidInputContext::handleLocationChanged(int handleId, int x, int y) { + if (m_batchEditNestingLevel.load() || m_blockUpdateSelection) + return; + + finishComposingText(); + auto im = qGuiApp->inputMethod(); auto leftRect = im->cursorRectangle(); // The handle is down of the cursor, but we want the position in the middle. diff --git a/src/plugins/platforms/android/qandroidinputcontext.h b/src/plugins/platforms/android/qandroidinputcontext.h index ce0ec8724c..e7692bf720 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.h +++ b/src/plugins/platforms/android/qandroidinputcontext.h @@ -152,7 +152,7 @@ private: CursorHandleShowPopup = 3 }; CursorHandleShowMode m_cursorHandleShown; - int m_batchEditNestingLevel; + QAtomicInt m_batchEditNestingLevel; QObject *m_focusObject; }; From c0842aceaf9881caba798f2569e6e1cf03ce7f70 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Thu, 8 Dec 2016 12:08:12 +0100 Subject: [PATCH 38/74] Make size grip work with high dpi scaling Task-number: QTBUG-53389 Change-Id: I6e922f0555ae296f3152d4df2598534fa73fb584 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/xcb/qxcbwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 5fa8541f26..ff01fa019e 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2738,7 +2738,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE); if (!connection()->wmSupport()->isSupportedByWM(moveResize)) return false; - const QPoint globalPos = window()->mapToGlobal(pos); + const QPoint globalPos = QHighDpi::toNativePixels(window()->mapToGlobal(pos), window()->screen()); #ifdef XCB_USE_XINPUT22 if (connection()->startSystemResizeForTouchBegin(m_window, globalPos, corner)) return true; From 80e63223f80643a93255cde9e0a4e82c705b2262 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 25 Nov 2016 20:41:20 +0100 Subject: [PATCH 39/74] make qmake abort when $$prompt() gets EOF otherwise, infinite loops can result, as amply demonstrated by the new configure (which duly replicated the old configures' behavior ...). QMakeEvaluator::evaluateBuiltinExpand() now returns a VisitReturn like all other evaluate*() functions. the string list return value is now an out parameter; i used a reference instead of a pointer to avoid adjusting 56 usages of it. Task-number: QTBUG-13964 Change-Id: I51ca7df8d694c6ffe9d9899cba414b1b46f5ce95 Reviewed-by: Lars Knoll --- qmake/library/qmakebuiltins.cpp | 13 ++++++++----- qmake/library/qmakeevaluator.cpp | 3 +-- qmake/library/qmakeevaluator.h | 2 +- qmake/project.cpp | 8 ++++++-- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index 02c910fe46..7648b9373d 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -560,11 +560,9 @@ void QMakeEvaluator::populateDeps( } } -ProStringList QMakeEvaluator::evaluateBuiltinExpand( - int func_t, const ProKey &func, const ProStringList &args) +QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( + int func_t, const ProKey &func, const ProStringList &args, ProStringList &ret) { - ProStringList ret; - traceMsg("calling built-in $$%s(%s)", dbgKey(func), dbgSepStrList(args)); switch (func_t) { @@ -1110,6 +1108,11 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( if (qfile.open(stdin, QIODevice::ReadOnly)) { QTextStream t(&qfile); const QString &line = t.readLine(); + if (t.atEnd()) { + fputs("\n", stderr); + evalError(fL1S("Unexpected EOF.")); + return ReturnError; + } ret = split_value_list(QStringRef(&line)); } } @@ -1279,7 +1282,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( break; } - return ret; + return ReturnTrue; } QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index 017fc3434c..cc57aa7f2b 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -1774,8 +1774,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateExpandFunction( ProStringList args; if (expandVariableReferences(tokPtr, 5, &args, true) == ReturnError) return ReturnError; - *ret = evaluateBuiltinExpand(func_t, func, args); - return ReturnTrue; + return evaluateBuiltinExpand(func_t, func, args, *ret); } QHash::ConstIterator it = diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index 3f2a22c567..544c257f07 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -212,7 +212,7 @@ public: VisitReturn evaluateExpandFunction(const ProKey &function, const ushort *&tokPtr, ProStringList *ret); VisitReturn evaluateConditionalFunction(const ProKey &function, const ushort *&tokPtr); - ProStringList evaluateBuiltinExpand(int func_t, const ProKey &function, const ProStringList &args); + VisitReturn evaluateBuiltinExpand(int func_t, const ProKey &function, const ProStringList &args, ProStringList &ret); VisitReturn evaluateBuiltinConditional(int func_t, const ProKey &function, const ProStringList &args); VisitReturn evaluateConditional(const QStringRef &cond, const QString &where, int line = -1); diff --git a/qmake/project.cpp b/qmake/project.cpp index 2f8411d52f..3a073b0954 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -99,8 +99,12 @@ QStringList QMakeProject::expand(const ProKey &func, const QList { m_current.clear(); - if (int func_t = statics.expands.value(func)) - return evaluateBuiltinExpand(func_t, func, prepareBuiltinArgs(args)).toQStringList(); + if (int func_t = statics.expands.value(func)) { + ProStringList ret; + if (evaluateBuiltinExpand(func_t, func, prepareBuiltinArgs(args), ret) == ReturnError) + exit(3); + return ret.toQStringList(); + } QHash::ConstIterator it = m_functionDefs.replaceFunctions.constFind(func); From 2dcc1a8e4636c754d51370c84a0aa8270e412389 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 17 Nov 2016 19:24:35 +0100 Subject: [PATCH 40/74] move preparation of configure test build dir to qmake-based system Change-Id: I650fb92cfa858bf6d7ff5756aa0efe182f036a55 Reviewed-by: Lars Knoll --- configure | 5 ----- mkspecs/features/qt_configure.prf | 1 + tools/configure/configureapp.cpp | 20 -------------------- tools/configure/configureapp.h | 1 - tools/configure/main.cpp | 5 ----- 5 files changed, 1 insertion(+), 31 deletions(-) diff --git a/configure b/configure index 48dea87fb7..9fcf066928 100755 --- a/configure +++ b/configure @@ -452,11 +452,6 @@ fi # initalize variables #------------------------------------------------------------------------------- -# Use CC/CXX to run config.tests -mkdir -p "$outpath/config.tests" -rm -f "$outpath/config.tests/.qmake.cache" -: > "$outpath/config.tests/.qmake.cache" - # QTDIR may be set and point to an old or system-wide Qt installation unset QTDIR diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 74ad611ee5..7f3f710585 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -770,6 +770,7 @@ defineTest(qtConfTest_compile) { QMAKE_MAKE = "$$QMAKE_MAKE clean && $$QMAKE_MAKE" mkpath($$test_out_dir)|error() + write_file($$test_out_dir/.qmake.cache)|error() # add possible command line args qmake_args += $$qtConfPrepareArgs($$eval($${1}.args)) $$eval($${1}.literal_args) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index fc66220335..cfba57272f 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -93,7 +93,6 @@ Configure::Configure(int& argc, char** argv) QDir(buildPath).mkpath("bin"); buildDir.mkpath("mkspecs"); - buildDir.mkpath("config.tests"); } dictionary[ "QT_INSTALL_PREFIX" ] = installPath; @@ -479,25 +478,6 @@ void Configure::parseCmdLine() } } -void Configure::prepareConfigTests() -{ - // Generate an empty .qmake.cache file for config.tests - QDir buildDir(buildPath); - bool success = true; - if (!buildDir.exists("config.tests")) - success = buildDir.mkdir("config.tests"); - - QString fileName(buildPath + "/config.tests/.qmake.cache"); - QFile cacheFile(fileName); - success &= cacheFile.open(QIODevice::WriteOnly); - cacheFile.close(); - - if (!success) { - cout << "Failed to create file " << qPrintable(QDir::toNativeSeparators(fileName)) << endl; - dictionary[ "DONE" ] = "error"; - } -} - void Configure::generateQDevicePri() { FileWriter deviceStream(buildPath + "/mkspecs/qdevice.pri"); diff --git a/tools/configure/configureapp.h b/tools/configure/configureapp.h index b007f3c487..8d11f07457 100644 --- a/tools/configure/configureapp.h +++ b/tools/configure/configureapp.h @@ -52,7 +52,6 @@ public: void generateHeaders(); void generateQDevicePri(); - void prepareConfigTests(); bool isDone(); bool isOk(); diff --git a/tools/configure/main.cpp b/tools/configure/main.cpp index f6c2722529..3fce934da5 100644 --- a/tools/configure/main.cpp +++ b/tools/configure/main.cpp @@ -63,11 +63,6 @@ int runConfigure( int argc, char** argv ) if (!app.isOk()) return 3; - // Prepare the config test build directory. - app.prepareConfigTests(); - if (!app.isOk()) - return 3; - // run qmake based configure app.configure(); if (!app.isOk()) From 24cb1580e2bdb9eace8a419dcc44bffe13ed1550 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 23 Nov 2016 18:41:48 +0100 Subject: [PATCH 41/74] make handling of built-in configure options data-driven Change-Id: I08b226b6c9255b60393734e8ffcb745ccb63c597 Reviewed-by: Lars Knoll --- mkspecs/features/configure.prf | 2 ++ mkspecs/features/configure_base.prf | 2 -- mkspecs/features/data/configure.json | 21 +++++++++++++ mkspecs/features/qt_configure.prf | 46 +++++++++++----------------- 4 files changed, 41 insertions(+), 30 deletions(-) create mode 100644 mkspecs/features/data/configure.json diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf index 4ca7c6ba07..934a18a924 100644 --- a/mkspecs/features/configure.prf +++ b/mkspecs/features/configure.prf @@ -4,6 +4,8 @@ cache() load(configure_base) +isEmpty(QMAKE_CONFIG_VERBOSE): QMAKE_CONFIG_VERBOSE = false + QMAKE_CONFIG_LOG = $$dirname(_QMAKE_CACHE_)/config.log recheck: write_file($$QMAKE_CONFIG_LOG, "") diff --git a/mkspecs/features/configure_base.prf b/mkspecs/features/configure_base.prf index dd1f4e5bfc..41f429e204 100644 --- a/mkspecs/features/configure_base.prf +++ b/mkspecs/features/configure_base.prf @@ -22,8 +22,6 @@ QMAKE_MAKE = $$(MAKE) # Make sure we don't inherit MAKEFLAGS - -i in particular is fatal. QMAKE_MAKE = "$${SETENV_PFX}MAKEFLAGS=$$SETENV_SFX $$QMAKE_MAKE" -isEmpty(QMAKE_CONFIG_VERBOSE): QMAKE_CONFIG_VERBOSE = false - defineTest(qtLog) { write_file($$QMAKE_CONFIG_LOG, 1, append) $$QMAKE_CONFIG_VERBOSE: for (l, 1): log("$$l$$escape_expand(\\n)") diff --git a/mkspecs/features/data/configure.json b/mkspecs/features/data/configure.json new file mode 100644 index 0000000000..a937f79b99 --- /dev/null +++ b/mkspecs/features/data/configure.json @@ -0,0 +1,21 @@ +{ + "files": { + }, + + "commandline": { + "options": { + "v": { "type": "enum", "name": "verbose", "values": { "yes": "true", "no": "false" } }, + "verbose": { "type": "enum", "values": { "yes": "true", "no": "false" } }, + + "recheck": { "type": "void", "name": "cache_use", "value": "positive" }, + "recheck-all": { "type": "void", "name": "cache_use", "value": "none" }, + } + + }, + + "features": { + "builtins": { + "output": [ "builtins" ] + } + } +} diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 7f3f710585..1be92a8b43 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -194,29 +194,6 @@ defineTest(qtConfParseCommandLine) { c = $$qtConfGetNextCommandlineArg() isEmpty(c): break() - # handle options to turn on verbose logging - contains(c, "^-v")|contains(c, "^--?verbose") { - QMAKE_CONFIG_VERBOSE = true - export(QMAKE_CONFIG_VERBOSE) - next() - } - contains(c, "^-no-v")|contains(c, "^--?no-verbose") { - QMAKE_CONFIG_VERBOSE = false - export(QMAKE_CONFIG_VERBOSE) - next() - } - - contains(c, "^--?recheck") { - QMAKE_CONFIG_CACHE_USE = positive - export(QMAKE_CONFIG_CACHE_USE) - next() - } - contains(c, "^--?recheck-all") { - QMAKE_CONFIG_CACHE_USE = none - export(QMAKE_CONFIG_CACHE_USE) - next() - } - didCustomCall = false for (customCall, customCalls) { $${customCall}($$c) { @@ -1619,6 +1596,19 @@ defineTest(qtConfOutput_privateFeature) { } } +# command line built-ins post-processing +defineTest(qtConfOutput_builtins) { + QMAKE_CONFIG_VERBOSE = $$eval(config.input.verbose) + isEmpty(QMAKE_CONFIG_VERBOSE): \ + QMAKE_CONFIG_VERBOSE = false + export(QMAKE_CONFIG_VERBOSE) + + QMAKE_CONFIG_CACHE_USE = $$eval(config.input.cache_use) + isEmpty(QMAKE_CONFIG_CACHE_USE): \ + QMAKE_CONFIG_CACHE_USE = all + export(QMAKE_CONFIG_CACHE_USE) +} + defineTest(qtConfProcessOneOutput) { feature = $${1} fpfx = $${currentConfig}.features.$${feature} @@ -1654,7 +1644,7 @@ defineTest(qtConfProcessOutput) { module = $$eval($${currentConfig}.module) # write it to the output files - isEmpty($${currentConfig}.files._KEYS_) { + !defined($${currentConfig}.files._KEYS_, var) { # set defaults that should work for most Qt modules isEmpty(module): \ error("Neither module nor files section specified in configuration file.") @@ -1727,6 +1717,8 @@ isEmpty(configsToProcess): \ load(configure_base) QMAKE_POST_CONFIGURE = +config.builtins.dir = $$PWD/data +configsToProcess = builtins $$configsToProcess allConfigs = for(ever) { isEmpty(configsToProcess): \ @@ -1760,14 +1752,12 @@ for(ever) { for (currentConfig, allConfigs): \ qtConfSetupLibraries() +qtConfParseCommandLine() + !isEmpty(_QMAKE_SUPER_CACHE_): \ QMAKE_CONFIG_CACHE = $$dirname(_QMAKE_SUPER_CACHE_)/config.cache else: \ QMAKE_CONFIG_CACHE = $$dirname(_QMAKE_CACHE_)/config.cache -QMAKE_CONFIG_CACHE_USE = all - -qtConfParseCommandLine() - !equals(QMAKE_CONFIG_CACHE_USE, none) { include($$QMAKE_CONFIG_CACHE, , true) # this crudely determines when to discard the cache. this also catches the case From 8ebc7e967c5d245ffab5dcbf666fc01a4df4fe6a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 15 Nov 2016 20:49:43 +0100 Subject: [PATCH 42/74] move configure -redo handling (mostly) to qmake-based system the qmake bootstrap uses some of the options, so the configures still read config.opt for their own purposes, but the general handling is entirely in the new system now. Change-Id: I2c6c657d4da01c8d520ac74795454747bb224bdd Reviewed-by: Lars Knoll --- configure | 55 ++-------------------------- configure.pri | 24 ++++++++++++ mkspecs/features/data/configure.json | 2 + mkspecs/features/qt_configure.prf | 23 ++++++++++-- tools/configure/configureapp.cpp | 52 ++------------------------ tools/configure/configureapp.h | 3 +- 6 files changed, 53 insertions(+), 106 deletions(-) diff --git a/configure b/configure index 9fcf066928..2fa44880c3 100755 --- a/configure +++ b/configure @@ -84,9 +84,8 @@ if [ x"$1" = x"-top-level" ]; then shift fi -CFG_REDO=no -OPT_CMDLINE= # excluding -verbose (for config.opt) -QMAKE_CMDLINE= # including -verbose (for actual parsing) +OPT_CMDLINE= # expanded version for the script +QMAKE_CMDLINE= # verbatim version for qmake call set -f # suppress globbing in for loop SAVED_IFS=$IFS IFS=' @@ -104,14 +103,8 @@ for i in "$@"; do fi for a in `cat $optfile`; do OPT_CMDLINE="$OPT_CMDLINE -$a" - QMAKE_CMDLINE="$QMAKE_CMDLINE $a" done - CFG_REDO=yes # suppress repeated config.opt writeout - continue - ;; - -v|-verbose|--verbose|-no-v|-no-verbose|--no-verbose) ;; *) OPT_CMDLINE="$OPT_CMDLINE @@ -122,7 +115,7 @@ $i" $i" done set -- -for i in $QMAKE_CMDLINE; do +for i in $OPT_CMDLINE; do set -- "$@" "$i" done set +f @@ -466,13 +459,11 @@ XPLATFORM_WATCHOS=no # Whether target platform is watchOS XPLATFORM_ANDROID=no XPLATFORM_MINGW=no # Whether target platform is MinGW (win32-g++*) PLATFORM= -OPT_CONFIRM_LICENSE=no OPT_SHADOW=maybe OPT_VERBOSE=no OPT_HELP= CFG_SILENT=no OPT_MAC_SDK= -COMMERCIAL_USER=ask CFG_DEV=no # initalize variables used for installation @@ -726,19 +717,6 @@ while [ "$#" -gt 0 ]; do developer-build) CFG_DEV="yes" ;; - commercial) - COMMERCIAL_USER="yes" - ;; - opensource) - COMMERCIAL_USER="no" - ;; - confirm-license) - if [ "$VAL" = "yes" ]; then - OPT_CONFIRM_LICENSE="$VAL" - else - UNKNOWN_OPT=yes - fi - ;; h|help) if [ "$VAL" = "yes" ]; then OPT_HELP="$VAL" @@ -1645,33 +1623,6 @@ fi "$CFG_QMAKE_PATH" -qtconf "$QTCONFFILE" "$relpathMangled" -- "$@" || exit -#------------------------------------------------------------------------------- -# finally save the executed command to another script -#------------------------------------------------------------------------------- -if [ $CFG_REDO = no ]; then - if [ "$COMMERCIAL_USER" = "ask" ]; then - if grep '^QT_EDITION = OpenSource$' "$outpath/mkspecs/qconfig.pri" >/dev/null 2>&1; then - OPT_CMDLINE="$OPT_CMDLINE --opensource" - else - OPT_CMDLINE="$OPT_CMDLINE --commercial" - fi - fi - if [ "$OPT_CONFIRM_LICENSE" = "no" ]; then - OPT_CMDLINE="$OPT_CMDLINE --confirm-license" - fi - - # skip first line, as it's always empty due to unconditional field separation - echo "$OPT_CMDLINE" | tail -n +2 > config.opt - - [ -f "config.status" ] && rm -f config.status - echo "#!/bin/sh" > config.status - echo "$relpathMangled/$relconf -redo \"\$@\"" >> config.status - chmod +x config.status -fi - #------------------------------------------------------------------------------- # final notes for the user #------------------------------------------------------------------------------- diff --git a/configure.pri b/configure.pri index 526b09e965..e19861b533 100644 --- a/configure.pri +++ b/configure.pri @@ -91,11 +91,14 @@ defineReplace(qtConfFunc_licenseCheck) { val = $$lower($$prompt("Which edition of Qt do you want to use? ", false)) equals(val, c) { commercial = yes + QMAKE_SAVED_ARGS += -commercial } else: equals(val, o) { commercial = no + QMAKE_SAVED_ARGS += -opensource } else { next() } + export(QMAKE_SAVED_ARGS) break() } } else { @@ -206,6 +209,8 @@ defineReplace(qtConfFunc_licenseCheck) { val = $$lower($$prompt("Do you accept the terms of $$affix license? ", false)) equals(val, y)|equals(val, yes) { logn() + QMAKE_SAVED_ARGS += -confirm-license + export(QMAKE_SAVED_ARGS) return(true) } else: equals(val, n)|equals(val, no) { return(false) @@ -722,3 +727,22 @@ discard_from($$[QT_HOST_DATA/get]/mkspecs/qmodule.pri) QMAKE_POST_CONFIGURE += \ "include(\$\$[QT_HOST_DATA/get]/mkspecs/qconfig.pri)" \ "include(\$\$[QT_HOST_DATA/get]/mkspecs/qmodule.pri)" + +defineTest(createConfigStatus) { + $$QMAKE_REDO_CONFIG: return() + cfg = $$relative_path($$_PRO_FILE_PWD_/configure, $$OUT_PWD) + ext = + equals(QMAKE_HOST.os, Windows) { + ext = .bat + cont = \ + "$$system_quote($$system_path($$cfg)$$ext) -redo %*" + } else { + cont = \ + "$${LITERAL_HASH}!/bin/sh" \ + "exec $$system_quote($$cfg) -redo \"$@\"" + } + write_file($$OUT_PWD/config.status$$ext, cont, exe)|error() +} + +QMAKE_POST_CONFIGURE += \ + "createConfigStatus()" diff --git a/mkspecs/features/data/configure.json b/mkspecs/features/data/configure.json index a937f79b99..20a83025e6 100644 --- a/mkspecs/features/data/configure.json +++ b/mkspecs/features/data/configure.json @@ -9,6 +9,8 @@ "recheck": { "type": "void", "name": "cache_use", "value": "positive" }, "recheck-all": { "type": "void", "name": "cache_use", "value": "none" }, + + "redo": { "type": "redo" } } }, diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 1be92a8b43..936a563b9e 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -177,6 +177,17 @@ defineTest(qtConfCommandline_addString) { export(config.input.$$opt) } +defineTest(qtConfCommandline_redo) { + !exists($$OUT_PWD/config.opt) { + qtConfAddError("No config.opt present - cannot redo configuration.") + return() + } + QMAKE_EXTRA_ARGS = $$cat($$OUT_PWD/config.opt, lines) $$QMAKE_EXTRA_ARGS + export(QMAKE_EXTRA_ARGS) + QMAKE_REDO_CONFIG = true + export(QMAKE_REDO_CONFIG) +} + defineTest(qtConfParseCommandLine) { customCalls = for (cc, allConfigs) { @@ -1752,6 +1763,8 @@ for(ever) { for (currentConfig, allConfigs): \ qtConfSetupLibraries() +QMAKE_SAVED_ARGS = $$QMAKE_EXTRA_ARGS +QMAKE_REDO_CONFIG = false qtConfParseCommandLine() !isEmpty(_QMAKE_SUPER_CACHE_): \ @@ -1829,13 +1842,17 @@ for (currentConfig, allConfigs) { !isEmpty(QT_CONFIGURE_SKIPPED_MODULES): \ qtConfAddNote("The following modules are not being compiled in this configuration:" $$QT_CONFIGURE_SKIPPED_MODULES) +logn("Done running configuration tests.") +logn() + +!$$QMAKE_REDO_CONFIG { + write_file($$OUT_PWD/config.opt, QMAKE_SAVED_ARGS)|error() +} + # these come from the pri files loaded above. for (p, QMAKE_POST_CONFIGURE): \ eval($$p) -logn("Done running configuration tests.") -logn() - logn("Configure summary:") logn() qtConfPrintReport() diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index cfba57272f..49dab2fcd4 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -107,10 +107,6 @@ Configure::Configure(int& argc, char** argv) //Only used when cross compiling. dictionary[ "QT_INSTALL_SETTINGS" ] = "/etc/xdg"; - dictionary[ "REDO" ] = "no"; - - dictionary[ "BUILDTYPE" ] = "none"; - QString tmp = dictionary[ "QMAKESPEC" ]; if (tmp.contains("\\")) { tmp = tmp.mid(tmp.lastIndexOf("\\") + 1); @@ -145,6 +141,7 @@ void Configure::parseCmdLine() sourcePathMangled = QFileInfo(sourcePath).path(); buildPathMangled = QFileInfo(buildPath).path(); } + qmakeCmdLine = configCmdLine; int argCount = configCmdLine.size(); int i = 0; @@ -152,7 +149,6 @@ void Configure::parseCmdLine() // Look first for -redo for (int k = 0 ; k < argCount; ++k) { if (configCmdLine.at(k) == "-redo") { - dictionary["REDO"] = "yes"; configCmdLine.removeAt(k); if (!reloadCmdLine(k)) { dictionary["DONE"] = "error"; @@ -178,13 +174,7 @@ void Configure::parseCmdLine() } for (; i dictionary; - QStringList configCmdLine; + QStringList configCmdLine, qmakeCmdLine; QString outputLine; @@ -80,7 +80,6 @@ private: QString formatPath(const QString &path); bool reloadCmdLine(int idx); - void saveCmdLine(); }; class FileWriter : public QTextStream From d004e086a26529bcd1cc950341f71f77953c3866 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 18 Nov 2016 21:10:36 +0100 Subject: [PATCH 43/74] move definition of configure -continue switch to builtins ... where it actually belongs, as it should work in each repo in a modular build. Change-Id: I5463f0bcacb239900bed0b0f7be9cf32a3eab04e Reviewed-by: Lars Knoll --- configure.json | 1 - mkspecs/features/data/configure.json | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.json b/configure.json index 5a5536936a..92b6f659ad 100644 --- a/configure.json +++ b/configure.json @@ -64,7 +64,6 @@ "commercial": "void", "compile-examples": { "type": "boolean", "name": "compile_examples" }, "confirm-license": "void", - "continue": "void", "dbus": { "type": "optionalString", "values": [ "no", "yes", "linked", "runtime" ] }, "dbus-linked": { "type": "void", "name": "dbus", "value": "linked" }, "dbus-runtime": { "type": "void", "name": "dbus", "value": "runtime" }, diff --git a/mkspecs/features/data/configure.json b/mkspecs/features/data/configure.json index 20a83025e6..8e5ff5f0a4 100644 --- a/mkspecs/features/data/configure.json +++ b/mkspecs/features/data/configure.json @@ -7,6 +7,8 @@ "v": { "type": "enum", "name": "verbose", "values": { "yes": "true", "no": "false" } }, "verbose": { "type": "enum", "values": { "yes": "true", "no": "false" } }, + "continue": "void", + "recheck": { "type": "void", "name": "cache_use", "value": "positive" }, "recheck-all": { "type": "void", "name": "cache_use", "value": "none" }, From 1510c19aff2496e3560312cbd9a1cd2853f90c24 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 23 Nov 2016 20:48:12 +0100 Subject: [PATCH 44/74] don't scope QMAKE_MAC_SDK assignment in qdevice.pri any more host builds are using qhost.pri since c23a086e4. Change-Id: I312a7fdbdf8a392d74905d52d02bcb77459063cc Reviewed-by: Lars Knoll --- configure | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/configure b/configure index 2fa44880c3..ae7ca50e7c 100755 --- a/configure +++ b/configure @@ -188,12 +188,6 @@ BEGIN { values["LITERAL_WHITESPACE"] = " " values["LITERAL_DOLLAR"] = "$" } -/^!?host_build:/ { - scopeStart = index($0, ":") + 1 - condition = substr($0, 0, scopeStart - 2) - if (condition != "'"$1"'") { next } - $0 = substr($0, scopeStart) -} /^[_A-Z0-9.]+[ \t]*\+?=/ { valStart = index($0, "=") + 1 @@ -318,7 +312,7 @@ macSDKify() getQMakeConf() { if [ -z "$specvals" ]; then - specvals=`expandQMakeConf "$QMAKESPEC/qmake.conf" "$HOST_VARS_FILE" | extractQMakeVariables "host_build"` + specvals=`expandQMakeConf "$QMAKESPEC/qmake.conf" "$HOST_VARS_FILE" | extractQMakeVariables` if [ "$BUILD_ON_MAC" = "yes" ]; then specvals=$(macSDKify "$specvals"); fi fi getSingleQMakeVariable "$1" "$specvals" @@ -327,7 +321,7 @@ getQMakeConf() getXQMakeConf() { if [ -z "$xspecvals" ]; then - xspecvals=`expandQMakeConf "$XQMAKESPEC/qmake.conf" "$DEVICE_VARS_FILE" | extractQMakeVariables "!host_build"` + xspecvals=`expandQMakeConf "$XQMAKESPEC/qmake.conf" "$DEVICE_VARS_FILE" | extractQMakeVariables` if [ "$XPLATFORM_MAC" = "yes" ]; then xspecvals=$(macSDKify "$xspecvals"); fi fi getSingleQMakeVariable "$1" "$xspecvals" @@ -683,7 +677,7 @@ while [ "$#" -gt 0 ]; do ;; sdk) if [ "$BUILD_ON_MAC" = "yes" ]; then - DeviceVar set !host_build:QMAKE_MAC_SDK "$VAL" + DeviceVar set QMAKE_MAC_SDK "$VAL" OPT_MAC_SDK="$VAL" else UNKNOWN_OPT=yes From e2eab15e34181d81bac26613ab72c03240402bf8 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 23 Nov 2016 21:11:11 +0100 Subject: [PATCH 45/74] write HOST_QT_TOOLS to qmodule.pri instead of qhost.pri its only consumer is qt_tool.prf, which is an internal api. Change-Id: Iae90b079c5af60efad2ded70d6ea481212e5353a Reviewed-by: Lars Knoll --- configure | 1 - configure.pri | 9 +++++++++ mkspecs/features/qt_tool.prf | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/configure b/configure index ae7ca50e7c..9f1a3a0412 100755 --- a/configure +++ b/configure @@ -667,7 +667,6 @@ while [ "$#" -gt 0 ]; do ;; external-hostbindir) CFG_HOST_QT_TOOLS_PATH="$VAL" - HostVar set HOST_QT_TOOLS "$VAL" ;; bindir) QT_INSTALL_BINS="$VAL" diff --git a/configure.pri b/configure.pri index e19861b533..93e2fe894a 100644 --- a/configure.pri +++ b/configure.pri @@ -648,6 +648,15 @@ defineReplace(qtConfOutputPostProcess_publicPro) { return($$output) } +defineReplace(qtConfOutputPostProcess_privatePro) { + output = $$1 + + !isEmpty(config.input.external-hostbindir): \ + output += "HOST_QT_TOOLS = $$val_escape(config.input.external-hostbindir)" + + return($$output) +} + defineReplace(qtConfOutputPostProcess_publicHeader) { qt_version = $$[QT_VERSION] output = \ diff --git a/mkspecs/features/qt_tool.prf b/mkspecs/features/qt_tool.prf index 4b73b4b8f7..a8d589f0fa 100644 --- a/mkspecs/features/qt_tool.prf +++ b/mkspecs/features/qt_tool.prf @@ -27,7 +27,7 @@ DEFINES *= QT_USE_QSTRINGBUILDER vars = binary depends - isEmpty(HOST_QT_TOOLS) { + !host_build|isEmpty(HOST_QT_TOOLS) { load(resolve_target) !host_build|!force_bootstrap: MODULE_DEPENDS = $$replace(QT, -private$, _private) From e58eb3d6f953c224c2d47cd344bc41ba9f499223 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 23 Nov 2016 20:11:17 +0100 Subject: [PATCH 46/74] move device spec validation to configure instead of letting the specs validate themselves on each call, let them only define a callback for use by the verifyspec configure test. this is somewhat faster, and allows them to be loaded before qdevice.pri is populated. Change-Id: I2b60d006b33bbf42c28949f10ad429520ed32f46 Reviewed-by: Laszlo Agocs Reviewed-by: Lars Knoll --- config.tests/common/verifyspec/verifyspec.pro | 36 +++++++++++++++++++ mkspecs/devices/common/linux_device_post.conf | 6 ++-- .../devices/linux-archos-gen8-g++/qmake.conf | 6 ++-- .../linux-arm-amlogic-8726M-g++/qmake.conf | 6 ++-- .../linux-arm-trident-pnx8473-g++/qmake.conf | 18 ++++++---- .../qmake.conf | 16 +++++---- .../linux-sh4-stmicro-ST7108-g++/qmake.conf | 6 ++-- .../linux-sh4-stmicro-ST7540-g++/qmake.conf | 6 ++-- mkspecs/devices/linux-snowball-g++/qmake.conf | 6 ++-- mkspecs/features/device_config.prf | 33 ----------------- 10 files changed, 81 insertions(+), 58 deletions(-) diff --git a/config.tests/common/verifyspec/verifyspec.pro b/config.tests/common/verifyspec/verifyspec.pro index d78ed2985a..11a280e4ce 100644 --- a/config.tests/common/verifyspec/verifyspec.pro +++ b/config.tests/common/verifyspec/verifyspec.pro @@ -1 +1,37 @@ SOURCES = verifyspec.cpp + +# Provide a function to be used by mkspecs +defineTest(deviceSanityCheckCompiler) { + equals(QMAKE_HOST.os, Windows): \ + sfx = .exe + else: \ + sfx = + + # Build the compiler filename using the first value in QMAKE_CXX in order to + # support tools like ccache, which give QMAKE_CXX values of the form: + # ccache + compiler = $$first(QMAKE_CXX)$$sfx + + # Check if the binary exists with an absolute path. Do this check + # before the CROSS_COMPILE empty check below to allow the mkspec + # to derive the compiler path from other device options. + exists($$compiler): return() + + # Check for possible reasons of failure + # check if CROSS_COMPILE device-option is set + isEmpty(CROSS_COMPILE): \ + error("CROSS_COMPILE needs to be set via -device-option CROSS_COMPILE=") + + # Check if QMAKE_CXX points to an executable. + ensurePathEnv() + for (dir, QMAKE_PATH_ENV) { + exists($$dir/$${compiler}): \ + return() + } + + # QMAKE_CXX does not point to a compiler. + error("Compiler $$QMAKE_CXX not found. Check the value of CROSS_COMPILE -device-option") +} + +defined(qtConfSanitizeMkspec, test): \ + qtConfSanitizeMkspec() diff --git a/mkspecs/devices/common/linux_device_post.conf b/mkspecs/devices/common/linux_device_post.conf index 88fa31d805..cf1608f32b 100644 --- a/mkspecs/devices/common/linux_device_post.conf +++ b/mkspecs/devices/common/linux_device_post.conf @@ -1,3 +1,7 @@ +defineTest(qtConfSanitizeMkspec) { + deviceSanityCheckCompiler() +} + contains(DISTRO_OPTS, deb-multi-arch) { QMAKE_LFLAGS += -Wl,-rpath-link,$$[QT_SYSROOT]/usr/lib/$${GCC_MACHINE_DUMP} \ -Wl,-rpath-link,$$[QT_SYSROOT]/lib/$${GCC_MACHINE_DUMP} @@ -10,5 +14,3 @@ contains(DISTRO_OPTS, boot2qt) { QMAKE_CFLAGS += $$COMPILER_FLAGS QMAKE_CXXFLAGS += $$COMPILER_FLAGS QMAKE_LFLAGS += $$LINKER_FLAGS - -deviceSanityCheckCompiler() diff --git a/mkspecs/devices/linux-archos-gen8-g++/qmake.conf b/mkspecs/devices/linux-archos-gen8-g++/qmake.conf index 891559f3bf..66662f90ca 100644 --- a/mkspecs/devices/linux-archos-gen8-g++/qmake.conf +++ b/mkspecs/devices/linux-archos-gen8-g++/qmake.conf @@ -16,6 +16,10 @@ include(../../common/g++-unix.conf) load(device_config) +defineTest(qtConfSanitizeMkspec) { + deviceSanityCheckCompiler() +} + QT_QPA_DEFAULT_PLATFORM = eglfs # modifications to g++.conf @@ -51,6 +55,4 @@ QMAKE_LIBS_EGL = -lEGL -lIMGegl -lsrv_um QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 $${QMAKE_LIBS_EGL} QMAKE_LIBS_OPENVG = -lOpenVG $${QMAKE_LIBS_EGL} -deviceSanityCheckCompiler() - load(qt_config) diff --git a/mkspecs/devices/linux-arm-amlogic-8726M-g++/qmake.conf b/mkspecs/devices/linux-arm-amlogic-8726M-g++/qmake.conf index da2e046d08..74eaf0dd09 100644 --- a/mkspecs/devices/linux-arm-amlogic-8726M-g++/qmake.conf +++ b/mkspecs/devices/linux-arm-amlogic-8726M-g++/qmake.conf @@ -12,6 +12,10 @@ include(../../common/g++-unix.conf) load(device_config) +defineTest(qtConfSanitizeMkspec) { + deviceSanityCheckCompiler() +} + QMAKE_CC = $${CROSS_COMPILE}gcc QMAKE_CXX = $${CROSS_COMPILE}g++ QMAKE_LINK = $${QMAKE_CXX} @@ -25,8 +29,6 @@ QMAKE_STRIP = $${CROSS_COMPILE}strip QMAKE_CFLAGS += -mfloat-abi=softfp -mfpu=neon -mcpu=cortex-a9 QMAKE_CXXFLAGS += $$QMAKE_CFLAGS -deviceSanityCheckCompiler() - EGLFS_PLATFORM_HOOKS_SOURCES = $$PWD/qeglfshooks_8726m.cpp QT_QPA_DEFAULT_PLATFORM = eglfs diff --git a/mkspecs/devices/linux-arm-trident-pnx8473-g++/qmake.conf b/mkspecs/devices/linux-arm-trident-pnx8473-g++/qmake.conf index 3bbb7b6db9..b131f65a79 100644 --- a/mkspecs/devices/linux-arm-trident-pnx8473-g++/qmake.conf +++ b/mkspecs/devices/linux-arm-trident-pnx8473-g++/qmake.conf @@ -14,11 +14,17 @@ include(../../common/g++-unix.conf) load(device_config) -# Sanity checks -isEmpty(TRIDENT_SHINER_SDK_BUILDTREE): error("TRIDENT_SHINER_SDK_BUILDTREE needs to be set via -device-option TRIDENT_SHINER_SDK_BUILDTREE=") -isEmpty(TRIDENT_SHINER_SDK_BUILDSPEC): error("TRIDENT_SHINER_SDK_BUILDSPEC needs to be set via -device-option TRIDENT_SHINER_SDK_BUILDSPEC=") -isEmpty(TRIDENT_SHINER_SDK_INCDIR_EGL_OPENGL_ES2): error("TRIDENT_SHINER_SDK_INCDIR_EGL_OPENGL_ES2 needs to be set via -device-option TRIDENT_SHINER_SDK_INCDIR_EGL_OPENGL_ES2=") -isEmpty(TRIDENT_SHINER_SDK_LIBDIR_EGL_OPENGL_ES2): error("TRIDENT_SHINER_SDK_LIBDIR_EGL_OPENGL_ES2 needs to be set via -device-option TRIDENT_SHINER_SDK_LIBDIR_EGL_OPENGL_ES2=") +defineTest(qtConfSanitizeMkspec) { + isEmpty(TRIDENT_SHINER_SDK_BUILDTREE): \ + error("TRIDENT_SHINER_SDK_BUILDTREE needs to be set via -device-option TRIDENT_SHINER_SDK_BUILDTREE=") + isEmpty(TRIDENT_SHINER_SDK_BUILDSPEC): \ + error("TRIDENT_SHINER_SDK_BUILDSPEC needs to be set via -device-option TRIDENT_SHINER_SDK_BUILDSPEC=") + isEmpty(TRIDENT_SHINER_SDK_INCDIR_EGL_OPENGL_ES2): \ + error("TRIDENT_SHINER_SDK_INCDIR_EGL_OPENGL_ES2 needs to be set via -device-option TRIDENT_SHINER_SDK_INCDIR_EGL_OPENGL_ES2=") + isEmpty(TRIDENT_SHINER_SDK_LIBDIR_EGL_OPENGL_ES2): \ + error("TRIDENT_SHINER_SDK_LIBDIR_EGL_OPENGL_ES2 needs to be set via -device-option TRIDENT_SHINER_SDK_LIBDIR_EGL_OPENGL_ES2=") + deviceSanityCheckCompiler() +} QMAKE_CC = $${CROSS_COMPILE}gcc QMAKE_CXX = $${CROSS_COMPILE}g++ @@ -35,8 +41,6 @@ QMAKE_CFLAGS += --sysroot=$${TRIDENT_SHINER_SDK_BUILDTREE}/open_source QMAKE_CXXFLAGS += --sysroot=$${TRIDENT_SHINER_SDK_BUILDTREE}/open_source_archive/linux/toolchains/gcc-4.5.2_uclibc/ QMAKE_LFLAGS += --sysroot=$${TRIDENT_SHINER_SDK_BUILDTREE}/open_source_archive/linux/toolchains/gcc-4.5.2_uclibc/ -deviceSanityCheckCompiler() - QMAKE_CFLAGS = -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard QMAKE_CXXFLAGS = $$QMAKE_CFLAGS diff --git a/mkspecs/devices/linux-mipsel-broadcom-97425-g++/qmake.conf b/mkspecs/devices/linux-mipsel-broadcom-97425-g++/qmake.conf index e196f279d7..9211551daf 100644 --- a/mkspecs/devices/linux-mipsel-broadcom-97425-g++/qmake.conf +++ b/mkspecs/devices/linux-mipsel-broadcom-97425-g++/qmake.conf @@ -12,6 +12,16 @@ include(../../common/g++-unix.conf) load(device_config) +defineTest(qtConfSanitizeMkspec) { + isEmpty(B_REFSW_DEBUG): \ + error("B_REFSW_DEBUG needs to be set via -device-option B_REFSW_DEBUG=(y|n)") + isEmpty(BRCM_ROCKFORD_PATH): \ + error("BRCM_ROCKFORD_PATH needs to be set via -device-option BRCM_ROCKFORD_PATH=") + isEmpty(BRCM_APPLIBS_PATH): \ + error("BRCM_APPLIBS_PATH needs to be set via -device-option BRCM_APPLIBS_PATH=") + deviceSanityCheckCompiler() +} + # Modify the defaults we loaded above CROSS_COMPILE = mipsel-linux- QMAKE_CC = $${CROSS_COMPILE}gcc @@ -31,12 +41,6 @@ QMAKE_STRIP = $${CROSS_COMPILE}strip BRCM_PLATFORM = 97425 -# Sanity checks -deviceSanityCheckCompiler() -isEmpty(B_REFSW_DEBUG):error("B_REFSW_DEBUG needs to be set via -device-option B_REFSW_DEBUG=(y|n).") -isEmpty(BRCM_ROCKFORD_PATH):error("BRCM_ROCKFORD_PATH needs to be set via -device-option BRCM_ROCKFORD_PATH=path.") -isEmpty(BRCM_APPLIBS_PATH):error("BRCM_APPLIBS_PATH needs to be set via -device-option BRCM_APPLIBS_PATH=path.") - # Figure the kind of directfb build used. BRCM_BUILD_TYPE = debug contains(B_REFSW_DEBUG, [Nn]) { diff --git a/mkspecs/devices/linux-sh4-stmicro-ST7108-g++/qmake.conf b/mkspecs/devices/linux-sh4-stmicro-ST7108-g++/qmake.conf index 18d07dad63..8dab1ea287 100644 --- a/mkspecs/devices/linux-sh4-stmicro-ST7108-g++/qmake.conf +++ b/mkspecs/devices/linux-sh4-stmicro-ST7108-g++/qmake.conf @@ -14,6 +14,10 @@ include(../../common/g++-unix.conf) load(device_config) +defineTest(qtConfSanitizeMkspec) { + deviceSanityCheckCompiler() +} + QMAKE_CC = $${CROSS_COMPILE}gcc QMAKE_CXX = $${CROSS_COMPILE}g++ QMAKE_LINK = $${QMAKE_CXX} @@ -24,8 +28,6 @@ QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy QMAKE_NM = $${CROSS_COMPILE}nm -P QMAKE_STRIP = $${CROSS_COMPILE}strip -deviceSanityCheckCompiler() - QMAKE_LIBS_EGL += -lMali QT_QPA_DEFAULT_PLATFORM = eglfs diff --git a/mkspecs/devices/linux-sh4-stmicro-ST7540-g++/qmake.conf b/mkspecs/devices/linux-sh4-stmicro-ST7540-g++/qmake.conf index 5672829da9..04b0a80d1f 100644 --- a/mkspecs/devices/linux-sh4-stmicro-ST7540-g++/qmake.conf +++ b/mkspecs/devices/linux-sh4-stmicro-ST7540-g++/qmake.conf @@ -14,6 +14,10 @@ include(../../common/g++-unix.conf) load(device_config) +defineTest(qtConfSanitizeMkspec) { + deviceSanityCheckCompiler() +} + QMAKE_CC = $${CROSS_COMPILE}gcc QMAKE_CXX = $${CROSS_COMPILE}g++ QMAKE_LINK = $${QMAKE_CXX} @@ -24,8 +28,6 @@ QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy QMAKE_NM = $${CROSS_COMPILE}nm -P QMAKE_STRIP = $${CROSS_COMPILE}strip -deviceSanityCheckCompiler() - QMAKE_INCDIR_EGL += $$[QT_SYSROOT]/root/modules/include/ QMAKE_LIBDIR_EGL += $$[QT_SYSROOT]/root/modules/ diff --git a/mkspecs/devices/linux-snowball-g++/qmake.conf b/mkspecs/devices/linux-snowball-g++/qmake.conf index 3520c7a922..9791119363 100644 --- a/mkspecs/devices/linux-snowball-g++/qmake.conf +++ b/mkspecs/devices/linux-snowball-g++/qmake.conf @@ -12,6 +12,10 @@ include(../../common/g++-unix.conf) load(device_config) +defineTest(qtConfSanitizeMkspec) { + deviceSanityCheckCompiler() +} + QMAKE_CC = $${CROSS_COMPILE}gcc QMAKE_CXX = $${CROSS_COMPILE}g++ QMAKE_LINK = $${QMAKE_CXX} @@ -26,6 +30,4 @@ QMAKE_STRIP = $${CROSS_COMPILE}strip QMAKE_LFLAGS += -Wl,-rpath-link,$$[QT_SYSROOT]/usr/lib/arm-linux-gnueabihf \ -Wl,-rpath-link,$$[QT_SYSROOT]/lib/arm-linux-gnueabihf -deviceSanityCheckCompiler() - load(qt_config) diff --git a/mkspecs/features/device_config.prf b/mkspecs/features/device_config.prf index 9281d3e407..5c5b094a9c 100644 --- a/mkspecs/features/device_config.prf +++ b/mkspecs/features/device_config.prf @@ -10,36 +10,3 @@ unset(DEVICE_PRI) # this variable can be persisted via qmake -set CROSS_COMPILE /foo !host_build:isEmpty(CROSS_COMPILE): CROSS_COMPILE = $$[CROSS_COMPILE] - -# Provide a function to be used by mkspecs -defineTest(deviceSanityCheckCompiler) { - equals(QMAKE_HOST.os, Windows): \ - sfx = .exe - else: \ - sfx = - - # Build the compiler filename using the first value in QMAKE_CXX in order to - # support tools like ccache, which give QMAKE_CXX values of the form: - # ccache - compiler = $$first(QMAKE_CXX)$$sfx - - # Check if the binary exists with an absolute path. Do this check - # before the CROSS_COMPILE empty check below to allow the mkspec - # to derive the compiler path from other device options. - exists($$compiler):return() - - # Check for possible reasons of failure - # check if CROSS_COMPILE device-option is set - isEmpty(CROSS_COMPILE):error("CROSS_COMPILE needs to be set via -device-option CROSS_COMPILE=") - - # Check if QMAKE_CXX points to an executable. - ensurePathEnv() - for (dir, QMAKE_PATH_ENV) { - exists($$dir/$${compiler}): \ - return() - } - - # QMAKE_CXX does not point to a compiler. - error("Compiler $$QMAKE_CXX not found. Check the value of CROSS_COMPILE -device-option") -} - From 42196f4061263d6d0e453c0561f7604cadc6d0a3 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 24 Nov 2016 17:36:38 +0100 Subject: [PATCH 47/74] nuke configure -host-option in its current form, it was introduced only in 5.7, mostly as a side effect of -external-hostbindir (which is now handled differently). it only ever worked for the macOS and MinGW specs, as a side effect of them supporting -sdk and -device-option (for good reasons), and was supported only by the unix configure. it's not believed to be really useful and complicates matters somewhat, so get rid of it again. should it ever become actually relevant, it can be re-introduced properly, probably along with a -host-sdk option for macOS. Change-Id: Ib078469ea39deb821c7b6a8c67fda9e1a95fedf5 Reviewed-by: Lars Knoll --- config_help.txt | 1 - configure | 42 +++--------------------------- configure.json | 1 - mkspecs/features/device_config.prf | 12 ++++----- qtbase.pro | 3 +-- 5 files changed, 11 insertions(+), 48 deletions(-) diff --git a/config_help.txt b/config_help.txt index 5725e9213f..f711a01cb8 100644 --- a/config_help.txt +++ b/config_help.txt @@ -85,7 +85,6 @@ Build options: -framework ........... Build Qt framework bundles [yes] (Apple only) -platform ... Select host mkspec [detected] - -host-option ..... Add option for the host mkspec -xplatform .. Select target mkspec when cross-compiling [PLATFORM] -device ....... Cross-compile for device -device-option ... Add option for the device mkspec diff --git a/configure b/configure index 9f1a3a0412..09966e8e1b 100755 --- a/configure +++ b/configure @@ -123,10 +123,7 @@ IFS=$SAVED_IFS # initialize global variables DEVICE_VARS_FILE=.device.vars -HOST_VARS_FILE=.host.vars - :> "$DEVICE_VARS_FILE" -:> "$HOST_VARS_FILE" #------------------------------------------------------------------------------- # utility functions @@ -169,6 +166,9 @@ expandQMakeConf() ;; *load\(device_config\)*) conf_file="$2" + if [ -z "$conf_file" ]; then + continue + fi if [ ! -f "$conf_file" ]; then echo "WARNING: Unable to find file $conf_file" >&2 continue @@ -312,7 +312,7 @@ macSDKify() getQMakeConf() { if [ -z "$specvals" ]; then - specvals=`expandQMakeConf "$QMAKESPEC/qmake.conf" "$HOST_VARS_FILE" | extractQMakeVariables` + specvals=`expandQMakeConf "$QMAKESPEC/qmake.conf" | extractQMakeVariables` if [ "$BUILD_ON_MAC" = "yes" ]; then specvals=$(macSDKify "$specvals"); fi fi getSingleQMakeVariable "$1" "$specvals" @@ -361,23 +361,6 @@ resolveDeviceMkspec() fi } -#------------------------------------------------------------------------------- -# Host options -#------------------------------------------------------------------------------- -HostVar() -{ - case "$1" in - set) - eq="=" - ;; - *) - echo >&2 "BUG: wrong command to HostVar: $1" - ;; - esac - - echo "$2" "$eq" "$3" >> "$HOST_VARS_FILE" -} - #------------------------------------------------------------------------------- # operating system detection #------------------------------------------------------------------------------- @@ -559,7 +542,6 @@ while [ "$#" -gt 0 ]; do -xplatform| \ -device| \ -device-option| \ - -host-option| \ -sdk| \ -android-sdk| \ -android-ndk| \ @@ -697,11 +679,6 @@ while [ "$#" -gt 0 ]; do DEV_VAL=`echo $VAL | cut -d '=' -f 2-` DeviceVar set $DEV_VAR "$DEV_VAL" ;; - host-option) - HOST_VAR=`echo $VAL | cut -d '=' -f 1` - HOST_VAL=`echo $VAL | cut -d '=' -f 2-` - HostVar set $HOST_VAR "$HOST_VAL" - ;; optimized-qmake|optimized-tools) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then CFG_RELEASE_TOOLS="$VAL" @@ -1580,17 +1557,6 @@ else DEVICE_VARS_FILE="$DEVICE_VARS_OUTFILE" fi -#------------------------------------------------------------------------------- -# write out host config. -#------------------------------------------------------------------------------- -HOST_VARS_OUTFILE="$outpath/mkspecs/qhost.pri" -if cmp -s "$HOST_VARS_FILE" "$HOST_VARS_OUTFILE"; then - rm -f "$HOST_VARS_FILE" -else - mv -f $HOST_VARS_FILE "$HOST_VARS_OUTFILE" - HOST_VARS_FILE="$HOST_VARS_OUTFILE" -fi - #------------------------------------------------------------------------------- # run configure tests #------------------------------------------------------------------------------- diff --git a/configure.json b/configure.json index 92b6f659ad..9c6248549e 100644 --- a/configure.json +++ b/configure.json @@ -81,7 +81,6 @@ "gnumake": { "type": "boolean", "name": "GNUmake" }, "gui": "boolean", "headersclean": "boolean", - "host-option": "string", "incredibuild-xge": { "type": "boolean", "name": "incredibuild_xge" }, "libudev": "boolean", "ltcg": "boolean", diff --git a/mkspecs/features/device_config.prf b/mkspecs/features/device_config.prf index 5c5b094a9c..c15559e174 100644 --- a/mkspecs/features/device_config.prf +++ b/mkspecs/features/device_config.prf @@ -1,12 +1,12 @@ # This file is loaded by some qmakespecs to get early configuration data. -host_build: \ - PRI_FILE_NAME = qhost.pri -else: \ - PRI_FILE_NAME = qdevice.pri -DEVICE_PRI = $$[QT_HOST_DATA/get]/mkspecs/$$PRI_FILE_NAME +# Some of these qmakespecs can be used also in host mode, but they are not +# supposed to be influenced by -device-option then. +host_build: return() + +DEVICE_PRI = $$[QT_HOST_DATA/get]/mkspecs/qdevice.pri exists($$DEVICE_PRI):include($$DEVICE_PRI) unset(DEVICE_PRI) # this variable can be persisted via qmake -set CROSS_COMPILE /foo -!host_build:isEmpty(CROSS_COMPILE): CROSS_COMPILE = $$[CROSS_COMPILE] +isEmpty(CROSS_COMPILE): CROSS_COMPILE = $$[CROSS_COMPILE] diff --git a/qtbase.pro b/qtbase.pro index 4aa4d6f600..c0ce0972ef 100644 --- a/qtbase.pro +++ b/qtbase.pro @@ -28,7 +28,6 @@ QMAKE_DISTCLEAN += \ config.tests/.qmake.cache \ mkspecs/qconfig.pri \ mkspecs/qdevice.pri \ - mkspecs/qhost.pri \ mkspecs/qmodule.pri \ src/corelib/global/qconfig.h \ src/corelib/global/qconfig_p.h \ @@ -79,7 +78,7 @@ prefix_build|!equals(PWD, $$OUT_PWD) { mkspecs.path = $$[QT_HOST_DATA]/mkspecs mkspecs.files = \ $$OUT_PWD/mkspecs/qconfig.pri $$OUT_PWD/mkspecs/qmodule.pri \ - $$OUT_PWD/mkspecs/qdevice.pri $$OUT_PWD/mkspecs/qhost.pri \ + $$OUT_PWD/mkspecs/qdevice.pri \ $$files($$PWD/mkspecs/*) mkspecs.files -= $$PWD/mkspecs/modules $$PWD/mkspecs/modules-inst INSTALLS += mkspecs From 169a40d511165f6c3c9a71cd5c079786c22d2aca Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 24 Nov 2016 18:41:48 +0100 Subject: [PATCH 48/74] move generation of qconfig.cpp (and qt.conf) to qmake-based configure this moves us another step towards the "outer" configure doing just minimal bootstrapping of qmake. a challenge here was that so far, qmake itself needed qconfig.cpp. this was replaced by usage of a qt.conf file instead of compiled-in values. however, to make the executable still self-contained, that qt.conf is embedded into it (by simple appending of a fixed signature and the text file). the qmake with the embedded qt.conf is not used for the qt build itself, which instead relies on the qt.conf in bin/ as before. however, due to the missing built-in values, this file now needs to contain more information than before. but except for a minimal version that is needed to start up qmake/configure at all, that file is now also generated with qmake. as some of the newly set up properties are subsequently used by configure itself, qmake gains a (deliberately undocumented) function to reload the qt.conf after it's fully populated. unlike the old implementations, this one doesn't emit redundant qt.conf entries which match the hard-coded fallbacks. omitting them leads to leaner files which are more comprehensible. Started-by: Paolo Angelelli Change-Id: I4526ef64b3c89d9851e10f83965fe479ed7f39f6 Reviewed-by: Jake Petroules --- configure | 420 +--------------------------- configure.json | 11 +- configure.pri | 231 +++++++++++++++ mkspecs/features/qt_configure.prf | 2 +- qmake/Makefile.unix | 3 +- qmake/Makefile.win32 | 2 - qmake/library/qmakebuiltins.cpp | 8 +- qmake/library/qmakeglobals.h | 1 + qmake/option.cpp | 5 + qmake/property.cpp | 6 + qmake/property.h | 2 + qmake/qmake-aux.pro | 20 +- src/corelib/global/qlibraryinfo.cpp | 116 +++++++- src/corelib/global/qlibraryinfo.h | 2 + tools/configure/configureapp.cpp | 405 +-------------------------- tools/configure/configureapp.h | 8 - tools/configure/main.cpp | 3 - 17 files changed, 397 insertions(+), 848 deletions(-) diff --git a/configure b/configure index 09966e8e1b..78ff04a474 100755 --- a/configure +++ b/configure @@ -129,26 +129,6 @@ DEVICE_VARS_FILE=.device.vars # utility functions #------------------------------------------------------------------------------- -makeabs() -{ - local FILE="$1" - local RES="$FILE" - if [ -z "${FILE##/*}" ]; then - true - elif [ "$OSTYPE" = "msys" -a -z "${FILE##[a-zA-Z]:[/\\]*}" ]; then - true - else - RES=$PWD/$FILE - fi - RES=$RES/ - while true; do - nres=`echo "$RES" | sed 's,/[^/][^/]*/\.\./,/,g; s,/\./,/,g'` - test x"$nres" = x"$RES" && break - RES=$nres - done - echo "$RES" | sed 's,//,/,g; s,/$,,' -} - # Helper function for getQMakeConf. It parses include statements in # qmake.conf and prints out the expanded file expandQMakeConf() @@ -443,29 +423,6 @@ CFG_SILENT=no OPT_MAC_SDK= CFG_DEV=no -# initalize variables used for installation -QT_INSTALL_PREFIX= -QT_INSTALL_DOCS= -QT_INSTALL_HEADERS= -QT_INSTALL_LIBS= -QT_INSTALL_BINS= -QT_INSTALL_LIBEXECS= -QT_INSTALL_PLUGINS= -QT_INSTALL_IMPORTS= -QT_INSTALL_QML= -QT_INSTALL_ARCHDATA= -QT_INSTALL_DATA= -QT_INSTALL_TRANSLATIONS= -QT_INSTALL_SETTINGS= -QT_INSTALL_EXAMPLES= -QT_INSTALL_TESTS= -CFG_SYSROOT= -QT_HOST_PREFIX= -QT_HOST_BINS= -QT_HOST_LIBS= -QT_HOST_DATA= -QT_EXT_PREFIX= - # Android vars CFG_DEFAULT_ANDROID_NDK_ROOT=$ANDROID_NDK_ROOT CFG_DEFAULT_ANDROID_SDK_ROOT=$ANDROID_SDK_ROOT @@ -590,72 +547,9 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=no case "$VAR" in - prefix) - QT_INSTALL_PREFIX="$VAL" - ;; - hostprefix) - QT_HOST_PREFIX="$VAL" - ;; - hostdatadir) - QT_HOST_DATA="$VAL" - ;; - hostbindir) - QT_HOST_BINS="$VAL" - ;; - hostlibdir) - QT_HOST_LIBS="$VAL" - ;; - extprefix) - QT_EXT_PREFIX="$VAL" - ;; - docdir) - QT_INSTALL_DOCS="$VAL" - ;; - headerdir) - QT_INSTALL_HEADERS="$VAL" - ;; - plugindir) - QT_INSTALL_PLUGINS="$VAL" - ;; - importdir) - QT_INSTALL_IMPORTS="$VAL" - ;; - qmldir) - QT_INSTALL_QML="$VAL" - ;; - archdatadir) - QT_INSTALL_ARCHDATA="$VAL" - ;; - datadir) - QT_INSTALL_DATA="$VAL" - ;; - libdir) - QT_INSTALL_LIBS="$VAL" - ;; - translationdir) - QT_INSTALL_TRANSLATIONS="$VAL" - ;; - sysconfdir|settingsdir) - QT_INSTALL_SETTINGS="$VAL" - ;; - examplesdir) - QT_INSTALL_EXAMPLES="$VAL" - ;; - testsdir) - QT_INSTALL_TESTS="$VAL" - ;; - sysroot) - CFG_SYSROOT="$VAL" - ;; external-hostbindir) CFG_HOST_QT_TOOLS_PATH="$VAL" ;; - bindir) - QT_INSTALL_BINS="$VAL" - ;; - libexecdir) - QT_INSTALL_LIBEXECS="$VAL" - ;; sdk) if [ "$BUILD_ON_MAC" = "yes" ]; then DeviceVar set QMAKE_MAC_SDK "$VAL" @@ -1090,274 +984,6 @@ if [ "$XPLATFORM_ANDROID" = "no" ]; then fi fi -#------------------------------------------------------------------------------- -# postprocess installation and deployment paths -#------------------------------------------------------------------------------- - -if [ -z "$QT_INSTALL_PREFIX" ]; then - if [ "$CFG_DEV" = "yes" ]; then - QT_INSTALL_PREFIX="$outpath" # In Development, we use sandboxed builds by default - else - QT_INSTALL_PREFIX="/usr/local/Qt-${QT_VERSION}" # the default install prefix is /usr/local/Qt-$QT_VERSION - fi -fi -QT_INSTALL_PREFIX=`makeabs "$QT_INSTALL_PREFIX"` - -if [ -z "$QT_EXT_PREFIX" ]; then - QT_EXT_PREFIX=$QT_INSTALL_PREFIX - if [ -n "$CFG_SYSROOT" ]; then - QMAKE_SYSROOTIFY=true - else - QMAKE_SYSROOTIFY=false - fi -else - QT_EXT_PREFIX=`makeabs "$QT_EXT_PREFIX"` - QMAKE_SYSROOTIFY=false -fi - -if [ -z "$QT_HOST_PREFIX" ]; then - if $QMAKE_SYSROOTIFY; then - QT_HOST_PREFIX=$CFG_SYSROOT$QT_EXT_PREFIX - else - QT_HOST_PREFIX=$QT_EXT_PREFIX - fi - HAVE_HOST_PATH=false -else - QT_HOST_PREFIX=`makeabs "$QT_HOST_PREFIX"` - HAVE_HOST_PATH=true -fi - -#------- make the paths relative to the prefixes -------- - -PREFIX_COMPLAINTS= -PREFIX_REMINDER=false -while read basevar baseoption var option; do - eval path=\$QT_${basevar}_$var - [ -z "$path" ] && continue - path=`makeabs "$path"` - eval base=\$QT_${basevar}_PREFIX - rel=${path##$base} - if [ x"$rel" = x"$path" ]; then - if [ x"$option" != x"sysconf" ]; then - PREFIX_COMPLAINTS="$PREFIX_COMPLAINTS - NOTICE: -${option}dir is not a subdirectory of ${baseoption}prefix." - eval \$HAVE_${basevar}_PATH || PREFIX_REMINDER=true - fi - eval QT_REL_${basevar}_$var=\$rel - elif [ -z "$rel" ]; then - eval QT_REL_${basevar}_$var=. - else - eval QT_REL_${basevar}_$var=\${rel#/} - fi -done < "$outpath/src/corelib/global/qconfig.cpp.new" < "$QTCONFFILE" <> "$QTCONFFILE" <> "$QTCONFFILE" <> "$QTCONFFILE" <reloadProperties(); +#endif + return ReturnTrue; default: evalError(fL1S("Function '%1' is not implemented.").arg(function.toQString(m_tmp1))); return ReturnFalse; diff --git a/qmake/library/qmakeglobals.h b/qmake/library/qmakeglobals.h index 96c39fa168..1bb8632883 100644 --- a/qmake/library/qmakeglobals.h +++ b/qmake/library/qmakeglobals.h @@ -125,6 +125,7 @@ public: void setDirectories(const QString &input_dir, const QString &output_dir); #ifdef QT_BUILD_QMAKE void setQMakeProperty(QMakeProperty *prop) { property = prop; } + void reloadProperties() { property->reload(); } ProString propertyValue(const ProKey &name) const { return property->value(name); } #else # ifdef PROEVALUATOR_INIT_PROPS diff --git a/qmake/option.cpp b/qmake/option.cpp index fb49f5a100..b8102ecf06 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -638,6 +638,11 @@ qmakeAddCacheClear(qmakeCacheClearFunc func, void **data) cache_items.append(new QMakeCacheClearItem(func, data)); } +QString qmake_absoluteLocation() +{ + return Option::globals->qmake_abslocation; +} + QString qmake_libraryInfoFile() { if (!Option::globals->qtconf.isEmpty()) diff --git a/qmake/property.cpp b/qmake/property.cpp index d17d62481a..9a8db8904d 100644 --- a/qmake/property.cpp +++ b/qmake/property.cpp @@ -70,6 +70,12 @@ static const struct { QMakeProperty::QMakeProperty() : settings(0) { + reload(); +} + +void QMakeProperty::reload() +{ + QLibraryInfo::reload(); for (unsigned i = 0; i < sizeof(propList)/sizeof(propList[0]); i++) { QString name = QString::fromLatin1(propList[i].name); if (!propList[i].singular) { diff --git a/qmake/property.h b/qmake/property.h index cd04e4bc03..b0129196eb 100644 --- a/qmake/property.h +++ b/qmake/property.h @@ -50,6 +50,8 @@ public: QMakeProperty(); ~QMakeProperty(); + void reload(); + bool hasValue(const ProKey &); ProString value(const ProKey &); diff --git a/qmake/qmake-aux.pro b/qmake/qmake-aux.pro index 33a7fbfd2d..357ebc7367 100644 --- a/qmake/qmake-aux.pro +++ b/qmake/qmake-aux.pro @@ -6,6 +6,24 @@ QMAKE_DOCS = $$PWD/doc/qmake.qdocconf # qmake binary win32: EXTENSION = .exe + +!build_pass { + qmake_exe.target = $$OUT_PWD/qmake$$EXTENSION + qmake_exe.depends = ../bin/qmake$$EXTENSION builtin-qt.conf + equals(QMAKE_DIR_SEP, /): \ + qmake_exe.commands = cat ../bin/qmake$$EXTENSION builtin-qt.conf > qmake$$EXTENSION && chmod +x qmake$$EXTENSION + else: \ + qmake_exe.commands = copy /B ..\bin\qmake$$EXTENSION + builtin-qt.conf qmake$$EXTENSION + QMAKE_EXTRA_TARGETS += qmake_exe + + QMAKE_CLEAN += builtin-qt.conf + QMAKE_DISTCLEAN += qmake$$EXTENSION + + first.depends += qmake_exe + QMAKE_EXTRA_TARGETS += first +} + qmake.path = $$[QT_HOST_BINS] -qmake.files = $$OUT_PWD/../bin/qmake$$EXTENSION +qmake.files = $$OUT_PWD/qmake$$EXTENSION +qmake.CONFIG = no_check_exist executable INSTALLS += qmake diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 27fe10a79e..87ee75fa45 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -41,15 +41,18 @@ #include "qdir.h" #include "qstringlist.h" #include "qfile.h" +#include "qtemporaryfile.h" #include "qsettings.h" #include "qlibraryinfo.h" #include "qscopedpointer.h" #ifdef QT_BUILD_QMAKE QT_BEGIN_NAMESPACE +extern QString qmake_absoluteLocation(); extern QString qmake_libraryInfoFile(); QT_END_NAMESPACE #else +# include "qconfig.cpp" # include "qcoreapplication.h" #endif @@ -57,7 +60,6 @@ QT_END_NAMESPACE # include "private/qcore_mac_p.h" #endif -#include "qconfig.cpp" #include "archdetect.cpp" QT_BEGIN_NAMESPACE @@ -70,9 +72,16 @@ struct QLibrarySettings { QLibrarySettings(); void load(); +#ifdef QT_BUILD_QMAKE + void loadBuiltinValues(QSettings *config); +#endif QScopedPointer settings; #ifdef QT_BUILD_QMAKE + QString builtinValues[QLibraryInfo::LastHostPath + 1]; +# ifndef Q_OS_WIN + QString builtinSettingsPath; +# endif bool haveDevicePaths; bool haveEffectiveSourcePaths; bool haveEffectivePaths; @@ -88,6 +97,11 @@ class QLibraryInfoPrivate public: static QSettings *findConfiguration(); #ifdef QT_BUILD_QMAKE + static void reload() + { + if (qt_library_settings.exists()) + qt_library_settings->load(); + } static bool haveGroup(QLibraryInfo::PathGroup group) { QLibrarySettings *ls = qt_library_settings(); @@ -99,6 +113,25 @@ public: ? ls->haveDevicePaths : ls->havePaths) : false; } + static bool sysrootify() + { + // This is actually bogus, as it does not consider post-configure settings. + QLibrarySettings *ls = qt_library_settings(); + return ls ? (!ls->builtinValues[QLibraryInfo::SysrootPath].isEmpty() + && ls->builtinValues[QLibraryInfo::ExtPrefixPath].isEmpty()) : false; + } + static QString builtinValue(int loc) + { + QLibrarySettings *ls = qt_library_settings(); + return ls ? ls->builtinValues[loc] : QString(); + } +# ifndef Q_OS_WIN + static QString builtinSettingsPath() + { + QLibrarySettings *ls = qt_library_settings(); + return ls ? ls->builtinSettingsPath : QString(); + } +# endif #endif static QSettings *configuration() { @@ -122,6 +155,20 @@ QLibrarySettings::QLibrarySettings() load(); } +#ifdef QT_BUILD_QMAKE +static QByteArray qtconfSeparator() +{ +# ifdef Q_OS_WIN + QByteArray header = QByteArrayLiteral("\r\n===========================================================\r\n"); +# else + QByteArray header = QByteArrayLiteral("\n===========================================================\n"); +# endif + QByteArray content = QByteArrayLiteral("==================== qt.conf beginning ===================="); + // Assemble from pieces to avoid that the string appears in a raw executable + return header + content + header; +} +#endif + void QLibrarySettings::load() { // If we get any settings here, those won't change when the application shows up. @@ -159,6 +206,27 @@ void QLibrarySettings::load() havePaths = false; #endif } + +#ifdef QT_BUILD_QMAKE + // Try to use an embedded qt.conf appended to the QMake executable. + QFile qmakeFile(qmake_absoluteLocation()); + if (!qmakeFile.open(QIODevice::ReadOnly)) + return; + qmakeFile.seek(qmakeFile.size() - 10000); + QByteArray tail = qmakeFile.read(10000); + QByteArray separator = qtconfSeparator(); + int qtconfOffset = tail.lastIndexOf(separator); + if (qtconfOffset < 0) + return; + tail.remove(0, qtconfOffset + separator.size()); + // If QSettings had a c'tor taking a QIODevice, we'd pass a QBuffer ... + QTemporaryFile tmpFile; + tmpFile.open(); + tmpFile.write(tail); + tmpFile.close(); + QSettings builtinSettings(tmpFile.fileName(), QSettings::IniFormat); + loadBuiltinValues(&builtinSettings); +#endif } QSettings *QLibraryInfoPrivate::findConfiguration() @@ -420,10 +488,30 @@ static const struct { { "HostData", "." }, { "TargetSpec", "" }, { "HostSpec", "" }, + { "ExtPrefix", "" }, { "HostPrefix", "" }, #endif }; +#ifdef QT_BUILD_QMAKE +void QLibrarySettings::loadBuiltinValues(QSettings *config) +{ + config->beginGroup(QLatin1String("Paths")); + for (int i = 0; i <= QLibraryInfo::LastHostPath; i++) + builtinValues[i] = config->value(QLatin1String(qtConfEntries[i].key), + QLatin1String(qtConfEntries[i].value)).toString(); +# ifndef Q_OS_WIN + builtinSettingsPath = config->value(QLatin1String("Settings")).toString(); +# endif + config->endGroup(); +} + +void QLibraryInfo::reload() +{ + QLibraryInfoPrivate::reload(); +} +#endif + /*! Returns the location specified by \a loc. */ @@ -434,7 +522,7 @@ QLibraryInfo::location(LibraryLocation loc) QString ret = rawLocation(loc, FinalPaths); // Automatically prepend the sysroot to target paths - if ((loc < SysrootPath || loc > LastHostPath) && QT_CONFIGURE_SYSROOTIFY_PREFIX) { + if ((loc < SysrootPath || loc > LastHostPath) && QLibraryInfoPrivate::sysrootify()) { QString sysroot = rawLocation(SysrootPath, FinalPaths); if (!sysroot.isEmpty() && ret.length() > 2 && ret.at(1) == QLatin1Char(':') && (ret.at(2) == QLatin1Char('/') || ret.at(2) == QLatin1Char('\\'))) @@ -528,28 +616,32 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) #endif // QT_NO_SETTINGS if (!fromConf) { +#ifdef QT_BUILD_QMAKE + if ((unsigned)loc <= (unsigned)LastHostPath) { + if (loc == PrefixPath && group != DevicePaths) + ret = QLibraryInfoPrivate::builtinValue(ExtPrefixPath); + else + ret = QLibraryInfoPrivate::builtinValue(loc); +# ifndef Q_OS_WIN // On Windows we use the registry + } else if (loc == SettingsPath) { + ret = QLibraryInfoPrivate::builtinSettingsPath(); +# endif + } +#else // QT_BUILD_QMAKE const char * volatile path = 0; if (loc == PrefixPath) { - path = -#ifdef QT_BUILD_QMAKE - (group != DevicePaths) ? - QT_CONFIGURE_EXT_PREFIX_PATH : -#endif - QT_CONFIGURE_PREFIX_PATH; + path = QT_CONFIGURE_PREFIX_PATH; } else if (unsigned(loc) <= sizeof(qt_configure_str_offsets)/sizeof(qt_configure_str_offsets[0])) { path = qt_configure_strs + qt_configure_str_offsets[loc - 1]; #ifndef Q_OS_WIN // On Windows we use the registry } else if (loc == SettingsPath) { path = QT_CONFIGURE_SETTINGS_PATH; -#endif -#ifdef QT_BUILD_QMAKE - } else if (loc == HostPrefixPath) { - path = QT_CONFIGURE_HOST_PREFIX_PATH; #endif } if (path) ret = QString::fromLocal8Bit(path); +#endif } #ifdef QT_BUILD_QMAKE diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h index 55be706382..9d794ce1da 100644 --- a/src/corelib/global/qlibraryinfo.h +++ b/src/corelib/global/qlibraryinfo.h @@ -96,6 +96,7 @@ public: HostDataPath, TargetSpecPath, HostSpecPath, + ExtPrefixPath, HostPrefixPath, LastHostPath = HostPrefixPath, #endif @@ -105,6 +106,7 @@ public: #ifdef QT_BUILD_QMAKE enum PathGroup { FinalPaths, EffectivePaths, EffectiveSourcePaths, DevicePaths }; static QString rawLocation(LibraryLocation, PathGroup); + static void reload(); #endif static QStringList platformPluginArguments(const QString &platformName); diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 49dab2fcd4..630e58d818 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -48,14 +48,6 @@ QT_BEGIN_NAMESPACE -enum Platforms { - WINDOWS, - WINDOWS_RT, - QNX, - ANDROID, - OTHER -}; - std::ostream &operator<<(std::ostream &s, const QString &val) { s << val.toLocal8Bit().data(); return s; @@ -84,19 +76,12 @@ Configure::Configure(int& argc, char** argv) sourceDir = sourcePathInfo.dir(); } buildPath = QDir::currentPath(); -#if 0 - const QString installPath = QString("C:\\Qt\\%1").arg(QT_VERSION_STR); -#else - const QString installPath = buildPath; -#endif if (sourceDir != buildDir) { //shadow builds! QDir(buildPath).mkpath("bin"); buildDir.mkpath("mkspecs"); } - dictionary[ "QT_INSTALL_PREFIX" ] = installPath; - if (dictionary[ "QMAKESPEC" ].size() == 0) { dictionary[ "QMAKESPEC" ] = Environment::detectQMakeSpec(); dictionary[ "QMAKESPEC_FROM" ] = "detected"; @@ -104,9 +89,6 @@ Configure::Configure(int& argc, char** argv) dictionary[ "SYNCQT" ] = "auto"; - //Only used when cross compiling. - dictionary[ "QT_INSTALL_SETTINGS" ] = "/etc/xdg"; - QString tmp = dictionary[ "QMAKESPEC" ]; if (tmp.contains("\\")) { tmp = tmp.mid(tmp.lastIndexOf("\\") + 1); @@ -197,148 +179,6 @@ void Configure::parseCmdLine() else if (configCmdLine.at(i) == "-no-syncqt") dictionary[ "SYNCQT" ] = "no"; - // Directories ---------------------------------------------- - else if (configCmdLine.at(i) == "-prefix") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_INSTALL_PREFIX" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-bindir") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_INSTALL_BINS" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-libexecdir") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_INSTALL_LIBEXECS" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-libdir") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_INSTALL_LIBS" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-docdir") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_INSTALL_DOCS" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-headerdir") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_INSTALL_HEADERS" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-plugindir") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_INSTALL_PLUGINS" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-importdir") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_INSTALL_IMPORTS" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-qmldir") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_INSTALL_QML" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-archdatadir") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_INSTALL_ARCHDATA" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-datadir") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_INSTALL_DATA" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-translationdir") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_INSTALL_TRANSLATIONS" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-examplesdir") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_INSTALL_EXAMPLES" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-testsdir") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_INSTALL_TESTS" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-sysroot") { - ++i; - if (i == argCount) - break; - dictionary[ "CFG_SYSROOT" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-hostprefix") { - ++i; - if (i == argCount || configCmdLine.at(i).startsWith('-')) - dictionary[ "QT_HOST_PREFIX" ] = buildPath; - else - dictionary[ "QT_HOST_PREFIX" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-hostbindir") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_HOST_BINS" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-hostlibdir") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_HOST_LIBS" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-hostdatadir") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_HOST_DATA" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-extprefix") { - ++i; - if (i == argCount) - break; - dictionary[ "QT_EXT_PREFIX" ] = configCmdLine.at(i); - } - else if (configCmdLine.at(i) == "-make-tool") { ++i; if (i == argCount) @@ -346,13 +186,6 @@ void Configure::parseCmdLine() dictionary[ "MAKE" ] = configCmdLine.at(i); } - else if (configCmdLine.at(i) == "-sysconfdir") { - ++i; - if (i == argCount) - break; - dictionary["QT_INSTALL_SETTINGS"] = configCmdLine.at(i); - } - else if (configCmdLine.at(i) == "-android-ndk") { ++i; if (i == argCount) @@ -531,219 +364,6 @@ void Configure::generateHeaders() } } -void Configure::addConfStr(int group, const QString &val) -{ - confStrOffsets[group] += ' ' + QString::number(confStringOff) + ','; - confStrings[group] += " \"" + val + "\\0\"\n"; - confStringOff += val.length() + 1; -} - -void Configure::generateQConfigCpp() -{ - QString hostSpec = dictionary["QMAKESPEC"]; - QString targSpec = dictionary.contains("XQMAKESPEC") ? dictionary["XQMAKESPEC"] : hostSpec; - - dictionary["CFG_SYSROOT"] = QDir::cleanPath(dictionary["CFG_SYSROOT"]); - - bool qipempty = false; - if (dictionary["QT_INSTALL_PREFIX"].isEmpty()) - qipempty = true; - else - dictionary["QT_INSTALL_PREFIX"] = QDir::cleanPath(dictionary["QT_INSTALL_PREFIX"]); - - bool sysrootifyPrefix; - if (dictionary["QT_EXT_PREFIX"].isEmpty()) { - dictionary["QT_EXT_PREFIX"] = dictionary["QT_INSTALL_PREFIX"]; - sysrootifyPrefix = !dictionary["CFG_SYSROOT"].isEmpty(); - } else { - dictionary["QT_EXT_PREFIX"] = QDir::cleanPath(dictionary["QT_EXT_PREFIX"]); - sysrootifyPrefix = false; - } - - bool haveHpx; - if (dictionary["QT_HOST_PREFIX"].isEmpty()) { - dictionary["QT_HOST_PREFIX"] = (sysrootifyPrefix ? dictionary["CFG_SYSROOT"] : QString()) - + dictionary["QT_INSTALL_PREFIX"]; - haveHpx = false; - } else { - dictionary["QT_HOST_PREFIX"] = QDir::cleanPath(dictionary["QT_HOST_PREFIX"]); - haveHpx = true; - } - - static const struct { - const char *basevar, *baseoption, *var, *option; - } varmod[] = { - { "INSTALL_", "-prefix", "DOCS", "-docdir" }, - { "INSTALL_", "-prefix", "HEADERS", "-headerdir" }, - { "INSTALL_", "-prefix", "LIBS", "-libdir" }, - { "INSTALL_", "-prefix", "LIBEXECS", "-libexecdir" }, - { "INSTALL_", "-prefix", "BINS", "-bindir" }, - { "INSTALL_", "-prefix", "PLUGINS", "-plugindir" }, - { "INSTALL_", "-prefix", "IMPORTS", "-importdir" }, - { "INSTALL_", "-prefix", "QML", "-qmldir" }, - { "INSTALL_", "-prefix", "ARCHDATA", "-archdatadir" }, - { "INSTALL_", "-prefix", "DATA", "-datadir" }, - { "INSTALL_", "-prefix", "TRANSLATIONS", "-translationdir" }, - { "INSTALL_", "-prefix", "EXAMPLES", "-examplesdir" }, - { "INSTALL_", "-prefix", "TESTS", "-testsdir" }, - { "INSTALL_", "-prefix", "SETTINGS", "-sysconfdir" }, - { "HOST_", "-hostprefix", "BINS", "-hostbindir" }, - { "HOST_", "-hostprefix", "LIBS", "-hostlibdir" }, - { "HOST_", "-hostprefix", "DATA", "-hostdatadir" }, - }; - - bool prefixReminder = false; - for (uint i = 0; i < sizeof(varmod) / sizeof(varmod[0]); i++) { - QString path = QDir::cleanPath( - dictionary[QLatin1String("QT_") + varmod[i].basevar + varmod[i].var]); - if (path.isEmpty()) - continue; - QString base = dictionary[QLatin1String("QT_") + varmod[i].basevar + "PREFIX"]; - if (!path.startsWith(base)) { - if (i != 13) { - dictionary["PREFIX_COMPLAINTS"] += QLatin1String("\n NOTICE: ") - + varmod[i].option + " is not a subdirectory of " + varmod[i].baseoption + "."; - if (i < 13 ? qipempty : !haveHpx) - prefixReminder = true; - } - } else { - path.remove(0, base.size()); - if (path.startsWith('/')) - path.remove(0, 1); - } - dictionary[QLatin1String("QT_REL_") + varmod[i].basevar + varmod[i].var] - = path.isEmpty() ? "." : path; - } - if (prefixReminder) { - dictionary["PREFIX_COMPLAINTS"] - += "\n Maybe you forgot to specify -prefix/-hostprefix?"; - } - - if (!qipempty) { - // If QT_INSTALL_* have not been specified on the command line, - // default them here, unless prefix is empty (WinCE). - - if (dictionary["QT_REL_INSTALL_HEADERS"].isEmpty()) - dictionary["QT_REL_INSTALL_HEADERS"] = "include"; - - if (dictionary["QT_REL_INSTALL_LIBS"].isEmpty()) - dictionary["QT_REL_INSTALL_LIBS"] = "lib"; - - if (dictionary["QT_REL_INSTALL_BINS"].isEmpty()) - dictionary["QT_REL_INSTALL_BINS"] = "bin"; - - if (dictionary["QT_REL_INSTALL_ARCHDATA"].isEmpty()) - dictionary["QT_REL_INSTALL_ARCHDATA"] = "."; - if (dictionary["QT_REL_INSTALL_ARCHDATA"] != ".") - dictionary["QT_REL_INSTALL_ARCHDATA_PREFIX"] = dictionary["QT_REL_INSTALL_ARCHDATA"] + '/'; - - if (dictionary["QT_REL_INSTALL_LIBEXECS"].isEmpty()) { - if (targSpec.startsWith("win")) - dictionary["QT_REL_INSTALL_LIBEXECS"] = dictionary["QT_REL_INSTALL_ARCHDATA_PREFIX"] + "bin"; - else - dictionary["QT_REL_INSTALL_LIBEXECS"] = dictionary["QT_REL_INSTALL_ARCHDATA_PREFIX"] + "libexec"; - } - - if (dictionary["QT_REL_INSTALL_PLUGINS"].isEmpty()) - dictionary["QT_REL_INSTALL_PLUGINS"] = dictionary["QT_REL_INSTALL_ARCHDATA_PREFIX"] + "plugins"; - - if (dictionary["QT_REL_INSTALL_IMPORTS"].isEmpty()) - dictionary["QT_REL_INSTALL_IMPORTS"] = dictionary["QT_REL_INSTALL_ARCHDATA_PREFIX"] + "imports"; - - if (dictionary["QT_REL_INSTALL_QML"].isEmpty()) - dictionary["QT_REL_INSTALL_QML"] = dictionary["QT_REL_INSTALL_ARCHDATA_PREFIX"] + "qml"; - - if (dictionary["QT_REL_INSTALL_DATA"].isEmpty()) - dictionary["QT_REL_INSTALL_DATA"] = "."; - if (dictionary["QT_REL_INSTALL_DATA"] != ".") - dictionary["QT_REL_INSTALL_DATA_PREFIX"] = dictionary["QT_REL_INSTALL_DATA"] + '/'; - - if (dictionary["QT_REL_INSTALL_DOCS"].isEmpty()) - dictionary["QT_REL_INSTALL_DOCS"] = dictionary["QT_REL_INSTALL_DATA_PREFIX"] + "doc"; - - if (dictionary["QT_REL_INSTALL_TRANSLATIONS"].isEmpty()) - dictionary["QT_REL_INSTALL_TRANSLATIONS"] = dictionary["QT_REL_INSTALL_DATA_PREFIX"] + "translations"; - - if (dictionary["QT_REL_INSTALL_EXAMPLES"].isEmpty()) - dictionary["QT_REL_INSTALL_EXAMPLES"] = "examples"; - - if (dictionary["QT_REL_INSTALL_TESTS"].isEmpty()) - dictionary["QT_REL_INSTALL_TESTS"] = "tests"; - } - - if (dictionary["QT_REL_HOST_BINS"].isEmpty()) - dictionary["QT_REL_HOST_BINS"] = haveHpx ? "bin" : dictionary["QT_REL_INSTALL_BINS"]; - - if (dictionary["QT_REL_HOST_LIBS"].isEmpty()) - dictionary["QT_REL_HOST_LIBS"] = haveHpx ? "lib" : dictionary["QT_REL_INSTALL_LIBS"]; - - if (dictionary["QT_REL_HOST_DATA"].isEmpty()) - dictionary["QT_REL_HOST_DATA"] = haveHpx ? "." : dictionary["QT_REL_INSTALL_ARCHDATA"]; - - confStringOff = 0; - addConfStr(0, dictionary["QT_REL_INSTALL_DOCS"]); - addConfStr(0, dictionary["QT_REL_INSTALL_HEADERS"]); - addConfStr(0, dictionary["QT_REL_INSTALL_LIBS"]); - addConfStr(0, dictionary["QT_REL_INSTALL_LIBEXECS"]); - addConfStr(0, dictionary["QT_REL_INSTALL_BINS"]); - addConfStr(0, dictionary["QT_REL_INSTALL_PLUGINS"]); - addConfStr(0, dictionary["QT_REL_INSTALL_IMPORTS"]); - addConfStr(0, dictionary["QT_REL_INSTALL_QML"]); - addConfStr(0, dictionary["QT_REL_INSTALL_ARCHDATA"]); - addConfStr(0, dictionary["QT_REL_INSTALL_DATA"]); - addConfStr(0, dictionary["QT_REL_INSTALL_TRANSLATIONS"]); - addConfStr(0, dictionary["QT_REL_INSTALL_EXAMPLES"]); - addConfStr(0, dictionary["QT_REL_INSTALL_TESTS"]); - addConfStr(1, dictionary["CFG_SYSROOT"]); - addConfStr(1, dictionary["QT_REL_HOST_BINS"]); - addConfStr(1, dictionary["QT_REL_HOST_LIBS"]); - addConfStr(1, dictionary["QT_REL_HOST_DATA"]); - addConfStr(1, targSpec); - addConfStr(1, hostSpec); - - // Generate the new qconfig.cpp file - { - FileWriter tmpStream(buildPath + "/src/corelib/global/qconfig.cpp"); - tmpStream << "/* Build date */" << endl - << "static const char qt_configure_installation [11 + 12] = \"qt_instdate=2012-12-20\";" << endl - << endl - << "/* Installation Info */" << endl - << "static const char qt_configure_prefix_path_str [512 + 12] = \"qt_prfxpath=" << dictionary["QT_INSTALL_PREFIX"] << "\";" << endl - << "#ifdef QT_BUILD_QMAKE" << endl - << "static const char qt_configure_ext_prefix_path_str [512 + 12] = \"qt_epfxpath=" << dictionary["QT_EXT_PREFIX"] << "\";" << endl - << "static const char qt_configure_host_prefix_path_str [512 + 12] = \"qt_hpfxpath=" << dictionary["QT_HOST_PREFIX"] << "\";" << endl - << "#endif" << endl - << endl - << "static const short qt_configure_str_offsets[] = {\n" - << " " << confStrOffsets[0] << endl - << "#ifdef QT_BUILD_QMAKE\n" - << " " << confStrOffsets[1] << endl - << "#endif\n" - << "};\n" - << "static const char qt_configure_strs[] =\n" - << confStrings[0] << "#ifdef QT_BUILD_QMAKE\n" - << confStrings[1] << "#endif\n" - << ";\n" - << endl; - if ((platform() != WINDOWS) && (platform() != WINDOWS_RT)) - tmpStream << "#define QT_CONFIGURE_SETTINGS_PATH \"" << dictionary["QT_REL_INSTALL_SETTINGS"] << "\"" << endl; - - tmpStream << endl - << "#ifdef QT_BUILD_QMAKE\n" - << "# define QT_CONFIGURE_SYSROOTIFY_PREFIX " << (sysrootifyPrefix ? "true" : "false") << endl - << "#endif\n\n" - << endl - << "#define QT_CONFIGURE_PREFIX_PATH qt_configure_prefix_path_str + 12\n" - << "#ifdef QT_BUILD_QMAKE\n" - << "# define QT_CONFIGURE_EXT_PREFIX_PATH qt_configure_ext_prefix_path_str + 12\n" - << "# define QT_CONFIGURE_HOST_PREFIX_PATH qt_configure_host_prefix_path_str + 12\n" - << "#endif\n"; - - if (!tmpStream.flush()) - dictionary[ "DONE" ] = "error"; - } -} - void Configure::buildQmake() { { @@ -841,7 +461,11 @@ void Configure::buildQmake() if (confFile.open(QFile::WriteOnly | QFile::Text)) { // Truncates any existing file. QTextStream confStream(&confFile); confStream << "[EffectivePaths]" << endl - << "Prefix=.." << endl; + << "Prefix=.." << endl + << "[Paths]" << endl + << "TargetSpec=" << (dictionary.contains("XQMAKESPEC") + ? dictionary["XQMAKESPEC"] : dictionary["QMAKESPEC"]) << endl + << "HostSpec=" << dictionary["QMAKESPEC"] << endl; if (sourcePath != buildPath) confStream << "[EffectiveSourcePaths]" << endl << "Prefix=" << sourcePath << endl; @@ -897,25 +521,6 @@ bool Configure::isOk() return (dictionary[ "DONE" ] != "error"); } -int Configure::platform() const -{ - const QString xQMakeSpec = dictionary.value("XQMAKESPEC"); - - if ((xQMakeSpec.startsWith("winphone") || xQMakeSpec.startsWith("winrt"))) - return WINDOWS_RT; - - if (xQMakeSpec.contains("qnx")) - return QNX; - - if (xQMakeSpec.contains("android")) - return ANDROID; - - if (!xQMakeSpec.isEmpty()) - return OTHER; - - return WINDOWS; -} - FileWriter::FileWriter(const QString &name) : QTextStream() , m_name(name) diff --git a/tools/configure/configureapp.h b/tools/configure/configureapp.h index 755a2e2696..32ba7d3444 100644 --- a/tools/configure/configureapp.h +++ b/tools/configure/configureapp.h @@ -44,7 +44,6 @@ public: void parseCmdLine(); - void generateQConfigCpp(); void buildQmake(); void prepareConfigureInput(); @@ -56,8 +55,6 @@ public: bool isDone(); bool isOk(); - int platform() const; - private: int verbose; @@ -72,11 +69,6 @@ private: QString sourcePathMangled, buildPathMangled; QDir sourceDir, buildDir; - QString confStrOffsets[2]; - QString confStrings[2]; - int confStringOff; - - void addConfStr(int group, const QString &val); QString formatPath(const QString &path); bool reloadCmdLine(int idx); diff --git a/tools/configure/main.cpp b/tools/configure/main.cpp index 3fce934da5..e4b9c12e3d 100644 --- a/tools/configure/main.cpp +++ b/tools/configure/main.cpp @@ -45,9 +45,6 @@ int runConfigure( int argc, char** argv ) if (!app.isOk()) return 3; - // Source file with path settings. Needed by qmake. - app.generateQConfigCpp(); - // Bootstrapped includes. Needed by qmake. app.generateHeaders(); if (!app.isOk()) From b6b44b368c6fc2df168195eaee57a2f925a29646 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 11 Nov 2016 11:40:24 +0100 Subject: [PATCH 49/74] qmake: introduce magic bypassNesting() scope will be needed by configure. Change-Id: If14e6944fe84767bd67604ecde98076f873749ef Reviewed-by: Lars Knoll --- qmake/library/proitems.h | 3 ++ qmake/library/qmakeevaluator.cpp | 18 +++++++ qmake/library/qmakeparser.cpp | 26 ++++++++- tests/auto/tools/qmakelib/evaltest.cpp | 25 +++++++++ tests/auto/tools/qmakelib/parsertest.cpp | 69 ++++++++++++++++++++++++ 5 files changed, 140 insertions(+), 1 deletion(-) diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h index 05d9e8da28..c81e205699 100644 --- a/qmake/library/proitems.h +++ b/qmake/library/proitems.h @@ -329,6 +329,9 @@ enum ProToken { // - function name: hash (2), length (1), chars (length) // - body length (2) // - body + TokTerminator (body length) + TokBypassNesting, // escape from function local variable scopes: + // - block length (2) + // - block + TokTerminator (block length) TokMask = 0xff, TokQuoted = 0x100, // The expression is quoted => join expanded stringlist TokNewStr = 0x200 // Next stringlist element diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index cc57aa7f2b..4ca87e8bc7 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -594,6 +594,24 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( tokPtr += blockLen; okey = true, or_op = false; // force next evaluation break; + case TokBypassNesting: + blockLen = getBlockLen(tokPtr); + if ((m_cumulative || okey != or_op) && blockLen) { + ProValueMapStack savedValuemapStack = m_valuemapStack; + m_valuemapStack.clear(); + m_valuemapStack.append(savedValuemapStack.takeFirst()); + traceMsg("visiting nesting-bypassing block"); + ret = visitProBlock(tokPtr); + traceMsg("visited nesting-bypassing block"); + savedValuemapStack.prepend(m_valuemapStack.first()); + m_valuemapStack = savedValuemapStack; + } else { + traceMsg("skipped nesting-bypassing block"); + ret = ReturnTrue; + } + tokPtr += blockLen; + okey = true, or_op = false; // force next evaluation + break; case TokTestDef: case TokReplaceDef: if (m_cumulative || okey != or_op) { diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp index 56b217dfbb..78350c76c4 100644 --- a/qmake/library/qmakeparser.cpp +++ b/qmake/library/qmakeparser.cpp @@ -118,6 +118,7 @@ static struct { QString strfor; QString strdefineTest; QString strdefineReplace; + QString strbypassNesting; QString stroption; QString strreturn; QString strnext; @@ -141,6 +142,7 @@ void QMakeParser::initialize() statics.strfor = QLatin1String("for"); statics.strdefineTest = QLatin1String("defineTest"); statics.strdefineReplace = QLatin1String("defineReplace"); + statics.strbypassNesting = QLatin1String("bypassNesting"); statics.stroption = QLatin1String("option"); statics.strreturn = QLatin1String("return"); statics.strnext = QLatin1String("next"); @@ -1157,6 +1159,25 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg } parseError(fL1S("%1(function) requires one literal argument.").arg(*defName)); return; + } else if (m_tmp == statics.strbypassNesting) { + if (*uce != TokFuncTerminator) { + bogusTest(tokPtr, fL1S("%1() requires zero arguments.").arg(m_tmp)); + return; + } + if (!(m_blockstack.top().nest & NestFunction)) { + bogusTest(tokPtr, fL1S("Unexpected %1().").arg(m_tmp)); + return; + } + if (m_invert) { + bogusTest(tokPtr, fL1S("Unexpected NOT operator in front of %1().").arg(m_tmp)); + return; + } + flushScopes(tokPtr); + putLineMarker(tokPtr); + putOperator(tokPtr); + putTok(tokPtr, TokBypassNesting); + enterScope(tokPtr, true, StCtrl); + return; } else if (m_tmp == statics.strreturn) { if (m_blockstack.top().nest & NestFunction) { if (argc > 1) { @@ -1425,7 +1446,7 @@ static bool getBlock(const ushort *tokens, int limit, int &offset, QString *outS "TokReturn", "TokBreak", "TokNext", "TokNot", "TokAnd", "TokOr", "TokBranch", "TokForLoop", - "TokTestDef", "TokReplaceDef" + "TokTestDef", "TokReplaceDef", "TokBypassNesting" }; while (offset != limit) { @@ -1509,6 +1530,9 @@ static bool getBlock(const ushort *tokens, int limit, int &offset, QString *outS if (ok) ok = getSubBlock(tokens, limit, offset, outStr, indent, "body"); break; + case TokBypassNesting: + ok = getSubBlock(tokens, limit, offset, outStr, indent, "block"); + break; default: Q_ASSERT(!"unhandled token"); } diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp index e3be294e5f..4e215b8570 100644 --- a/tests/auto/tools/qmakelib/evaltest.cpp +++ b/tests/auto/tools/qmakelib/evaltest.cpp @@ -633,6 +633,31 @@ void tst_qmakelib::addControlStructs() << "" << true; + QTest::newRow("bypassNesting()") + << "defineTest(func) {\n" + "LOCAL = 1\n" + "bypassNesting() {\n" + "OUT = 1\n" + "!isEmpty(GLOBAL): OUT1 = 1\n" + "!isEmpty(LOCAL): OUT2 = 1\n" + "}\n" + "}\n" + "GLOBAL = 1\n" + "func()" + << "GLOBAL = 1\nLOCAL = UNDEF\nOUT = 1\nOUT1 = 1\nOUT2 = UNDEF" + << "" + << true; + + QTest::newRow("error() from bypassNesting()") + << "defineTest(func) {\n" + "bypassNesting() { error(error) }\n" + "}\n" + "func()\n" + "OKE = 1" + << "OKE = UNDEF" + << "Project ERROR: error" + << false; + QTest::newRow("top-level return()") << "VAR = good\nreturn()\nVAR = bad" << "VAR = good" diff --git a/tests/auto/tools/qmakelib/parsertest.cpp b/tests/auto/tools/qmakelib/parsertest.cpp index dc92f98f45..70f1be5fc3 100644 --- a/tests/auto/tools/qmakelib/parsertest.cpp +++ b/tests/auto/tools/qmakelib/parsertest.cpp @@ -1684,6 +1684,57 @@ void tst_qmakelib::addParseCustomFunctions() /* 22 */ << H(TokTerminator)) << "" << true; + + QTest::newRow("bypassNesting()-{return}") + << "defineTest(test) { bypassNesting() { return(true) } }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokTestDef) << HS(L"test") + /* 10 */ /* body */ << I(16) + /* 12 */ << H(TokLine) << H(1) + /* 14 */ << H(TokBypassNesting) + /* 15 */ /* block */ << I(10) + /* 17 */ << H(TokLine) << H(1) + /* 19 */ << H(TokLiteral | TokNewStr) << S(L"true") + /* 25 */ << H(TokReturn) + /* 26 */ << H(TokTerminator) + /* 27 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("test-AND-bypassNesting()-{}") + << "defineTest(test) { test: bypassNesting() {} }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokTestDef) << HS(L"test") + /* 10 */ /* body */ << I(17) + /* 12 */ << H(TokLine) << H(1) + /* 14 */ << H(TokHashLiteral) << HS(L"test") + /* 22 */ << H(TokCondition) + /* 23 */ << H(TokAnd) + /* 24 */ << H(TokBypassNesting) + /* 25 */ /* block */ << I(1) + /* 27 */ << H(TokTerminator) + /* 28 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("test-OR-bypassNesting()-{}") + << "defineTest(test) { test| bypassNesting() {} }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokTestDef) << HS(L"test") + /* 10 */ /* body */ << I(17) + /* 12 */ << H(TokLine) << H(1) + /* 14 */ << H(TokHashLiteral) << HS(L"test") + /* 22 */ << H(TokCondition) + /* 23 */ << H(TokOr) + /* 24 */ << H(TokBypassNesting) + /* 25 */ /* block */ << I(1) + /* 27 */ << H(TokTerminator) + /* 28 */ << H(TokTerminator)) + << "" + << true; } void tst_qmakelib::addParseAbuse() @@ -1736,6 +1787,24 @@ void tst_qmakelib::addParseAbuse() << "in:1: Unexpected NOT operator in front of function definition." << false; + QTest::newRow("outer-bypassNesting()-{}") + << "bypassNesting() {}" + << TS() + << "in:1: Unexpected bypassNesting()." + << false; + + QTest::newRow("bypassNesting(arg)-{}") + << "defineTest(test) { bypassNesting(arg) {} }" + << TS() + << "in:1: bypassNesting() requires zero arguments." + << false; + + QTest::newRow("NOT-bypassNesting()-{}") + << "defineTest(test) { !bypassNesting() {} }" + << TS() + << "in:1: Unexpected NOT operator in front of bypassNesting()." + << false; + QTest::newRow("AND-test") << ":test" << TS( From 8861b82f9ef59fa871adc86552012cd90eee6e09 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 24 Nov 2016 18:41:57 +0100 Subject: [PATCH 50/74] move qdevice.pri creation to qmake-based configure system Change-Id: I06540c3b6d98303bd9a218feedfb529993477ed6 Reviewed-by: Lars Knoll Reviewed-by: BogDan Vatra Reviewed-by: Jake Petroules --- configure | 157 +------------------------- configure.json | 19 +++- configure.pri | 154 ++++++++++++++++++++++++- mkspecs/common/android-base-head.conf | 3 + mkspecs/common/android-base-tail.conf | 3 + mkspecs/features/qt_configure.prf | 3 +- mkspecs/features/toolchain.prf | 3 + tools/configure/configureapp.cpp | 145 ------------------------ tools/configure/configureapp.h | 13 --- tools/configure/main.cpp | 5 - 10 files changed, 176 insertions(+), 329 deletions(-) diff --git a/configure b/configure index 78ff04a474..100c3db0d2 100755 --- a/configure +++ b/configure @@ -121,10 +121,6 @@ done set +f IFS=$SAVED_IFS -# initialize global variables -DEVICE_VARS_FILE=.device.vars -:> "$DEVICE_VARS_FILE" - #------------------------------------------------------------------------------- # utility functions #------------------------------------------------------------------------------- @@ -142,18 +138,7 @@ expandQMakeConf() echo "WARNING: Unable to find file $conf_file" >&2 continue fi - expandQMakeConf "$conf_file" "$2" - ;; - *load\(device_config\)*) - conf_file="$2" - if [ -z "$conf_file" ]; then - continue - fi - if [ ! -f "$conf_file" ]; then - echo "WARNING: Unable to find file $conf_file" >&2 - continue - fi - expandQMakeConf "$conf_file" "$2" + expandQMakeConf "$conf_file" ;; *) echo "$line" @@ -298,32 +283,6 @@ getQMakeConf() getSingleQMakeVariable "$1" "$specvals" } -getXQMakeConf() -{ - if [ -z "$xspecvals" ]; then - xspecvals=`expandQMakeConf "$XQMAKESPEC/qmake.conf" "$DEVICE_VARS_FILE" | extractQMakeVariables` - if [ "$XPLATFORM_MAC" = "yes" ]; then xspecvals=$(macSDKify "$xspecvals"); fi - fi - getSingleQMakeVariable "$1" "$xspecvals" -} - -#------------------------------------------------------------------------------- -# device options -#------------------------------------------------------------------------------- -DeviceVar() -{ - case "$1" in - set) - eq="=" - ;; - *) - echo >&2 "BUG: wrong command to DeviceVar: $1" - ;; - esac - - echo "$2" "$eq" "$3" >> "$DEVICE_VARS_FILE" -} - resolveDeviceMkspec() { result=$(find "$relpath/mkspecs/devices/" -type d -name "*$1*" | sed "s,^$relpath/mkspecs/,,") @@ -420,17 +379,8 @@ OPT_SHADOW=maybe OPT_VERBOSE=no OPT_HELP= CFG_SILENT=no -OPT_MAC_SDK= CFG_DEV=no -# Android vars -CFG_DEFAULT_ANDROID_NDK_ROOT=$ANDROID_NDK_ROOT -CFG_DEFAULT_ANDROID_SDK_ROOT=$ANDROID_SDK_ROOT -CFG_DEFAULT_ANDROID_PLATFORM=android-16 -CFG_DEFAULT_ANDROID_TARGET_ARCH=armeabi-v7a -CFG_DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION=4.9 -CFG_DEFAULT_ANDROID_NDK_HOST=$ANDROID_NDK_HOST - #------------------------------------------------------------------------------- # parse command line arguments #------------------------------------------------------------------------------- @@ -550,14 +500,6 @@ while [ "$#" -gt 0 ]; do external-hostbindir) CFG_HOST_QT_TOOLS_PATH="$VAL" ;; - sdk) - if [ "$BUILD_ON_MAC" = "yes" ]; then - DeviceVar set QMAKE_MAC_SDK "$VAL" - OPT_MAC_SDK="$VAL" - else - UNKNOWN_OPT=yes - fi - ;; platform) PLATFORM="$VAL" ;; @@ -568,11 +510,6 @@ while [ "$#" -gt 0 ]; do XPLATFORM=`resolveDeviceMkspec $VAL` [ "$XPLATFORM" = "undefined" ] && exit 101 ;; - device-option) - DEV_VAR=`echo $VAL | cut -d '=' -f 1` - DEV_VAL=`echo $VAL | cut -d '=' -f 2-` - DeviceVar set $DEV_VAR "$DEV_VAL" - ;; optimized-qmake|optimized-tools) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then CFG_RELEASE_TOOLS="$VAL" @@ -601,24 +538,6 @@ while [ "$#" -gt 0 ]; do # need to keep this here, to ensure qmake is built silently CFG_SILENT="$VAL" ;; - android-sdk) - CFG_DEFAULT_ANDROID_SDK_ROOT="$VAL" - ;; - android-ndk) - CFG_DEFAULT_ANDROID_NDK_ROOT="$VAL" - ;; - android-ndk-platform) - CFG_DEFAULT_ANDROID_PLATFORM="$VAL" - ;; - android-ndk-host) - CFG_DEFAULT_ANDROID_NDK_HOST="$VAL" - ;; - android-arch) - CFG_DEFAULT_ANDROID_TARGET_ARCH="$VAL" - ;; - android-toolchain-version) - CFG_DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION="$VAL" - ;; *) ;; esac @@ -834,60 +753,6 @@ esac # command line and environment validation #------------------------------------------------------------------------------- -if [ "$XPLATFORM_ANDROID" != "no" ]; then - if [ -z "$CFG_DEFAULT_ANDROID_NDK_HOST" ]; then - case $PLATFORM in - linux-*) - if [ -d "$CFG_DEFAULT_ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-$CFG_DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION/prebuilt/linux-x86" ]; then - CFG_DEFAULT_ANDROID_NDK_HOST=linux-x86 - elif [ -d "$CFG_DEFAULT_ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-$CFG_DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION/prebuilt/linux-x86_64" ]; then - CFG_DEFAULT_ANDROID_NDK_HOST=linux-x86_64 - fi - ;; - macx-*) - CFG_DEFAULT_ANDROID_NDK_HOST=darwin-x86 - if [ -d "$CFG_DEFAULT_ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-$CFG_DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION/prebuilt/darwin-x86_64" ]; then - CFG_DEFAULT_ANDROID_NDK_HOST=darwin-x86_64 - fi - ;; - win32-*) - CFG_DEFAULT_ANDROID_NDK_HOST=windows - if [ -d "$CFG_DEFAULT_ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-$CFG_DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION/prebuilt/windows-x86_64" ]; then - CFG_DEFAULT_ANDROID_NDK_HOST=windows-x86_64 - fi - ;; - esac - fi - - if [ -z "$CFG_DEFAULT_ANDROID_NDK_ROOT" ]; then - echo - echo "Can not find Android NDK. Please use -android-ndk option to specify one" - exit 1 - fi - if [ -z "$CFG_DEFAULT_ANDROID_SDK_ROOT" ]; then - echo - echo "Can not find Android SDK. Please use -android-sdk option to specify one" - exit 1 - fi - if [ -z "CFG_DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION" ] || [ ! -d "$CFG_DEFAULT_ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-$CFG_DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION/prebuilt" ]; then - echo - echo "Can not detect Android NDK toolchain. Please use -android-toolchain-version to specify" - exit 1 - fi - if [ -z "$CFG_DEFAULT_ANDROID_NDK_HOST" ] || [ ! -d "$CFG_DEFAULT_ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-$CFG_DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION/prebuilt/$CFG_DEFAULT_ANDROID_NDK_HOST" ]; then - echo - echo "Can not detect the android host. Please use -android-ndk-host option to specify one" - exit 1 - fi - - DeviceVar set DEFAULT_ANDROID_SDK_ROOT "$CFG_DEFAULT_ANDROID_SDK_ROOT" - DeviceVar set DEFAULT_ANDROID_NDK_ROOT "$CFG_DEFAULT_ANDROID_NDK_ROOT" - DeviceVar set DEFAULT_ANDROID_PLATFORM "$CFG_DEFAULT_ANDROID_PLATFORM" - DeviceVar set DEFAULT_ANDROID_NDK_HOST "$CFG_DEFAULT_ANDROID_NDK_HOST" - DeviceVar set DEFAULT_ANDROID_TARGET_ARCH "$CFG_DEFAULT_ANDROID_TARGET_ARCH" - DeviceVar set DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION "$CFG_DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION" -fi - if [ -d "$PLATFORM" ]; then QMAKESPEC="$PLATFORM" else @@ -975,15 +840,6 @@ if [ "$OPT_SHADOW" = "yes" ]; then mkdir -p "$outpath/mkspecs" fi -if [ "$XPLATFORM_ANDROID" = "no" ]; then - TEST_COMPILER=`getXQMakeConf QMAKE_CXX` - GCC_MACHINE_DUMP= - case "$TEST_COMPILER" in *g++) GCC_MACHINE_DUMP=$($TEST_COMPILER -dumpmachine);; esac - if [ -n "$GCC_MACHINE_DUMP" ]; then - DeviceVar set GCC_MACHINE_DUMP $($TEST_COMPILER -dumpmachine) - fi -fi - # ----------------------------------------------------------------------------- # build qmake # ----------------------------------------------------------------------------- @@ -1137,17 +993,6 @@ fi [ -z "$CFG_HOST_QT_TOOLS_PATH" ] && CFG_HOST_QT_TOOLS_PATH="$outpath/bin" CFG_QMAKE_PATH="$CFG_HOST_QT_TOOLS_PATH/qmake" -#------------------------------------------------------------------------------- -# write out device config before we run the test. -#------------------------------------------------------------------------------- -DEVICE_VARS_OUTFILE="$outpath/mkspecs/qdevice.pri" -if cmp -s "$DEVICE_VARS_FILE" "$DEVICE_VARS_OUTFILE"; then - rm -f "$DEVICE_VARS_FILE" -else - mv -f $DEVICE_VARS_FILE "$DEVICE_VARS_OUTFILE" - DEVICE_VARS_FILE="$DEVICE_VARS_OUTFILE" -fi - #------------------------------------------------------------------------------- # run configure tests #------------------------------------------------------------------------------- diff --git a/configure.json b/configure.json index 537a6ff526..59358180d0 100644 --- a/configure.json +++ b/configure.json @@ -73,7 +73,7 @@ "debug-and-release": { "type": "boolean", "name": "debug_and_release" }, "developer-build": "void", "device": "string", - "device-option": "string", + "device-option": "addString", "force-asserts": { "type": "boolean", "name": "force_asserts" }, "force-debug-info": { "type": "boolean", "name": "force_debug_info" }, "force-pkg-config": { "type": "void", "name": "pkg-config" }, @@ -189,9 +189,9 @@ "testTypeDependencies": { "linkerSupportsFlag": [ "use_gold_linker" ], - "verifySpec": [ "shared", "use_gold_linker", "compiler-flags", "gcc-sysroot", "qmakeargs" ], + "verifySpec": [ "shared", "use_gold_linker", "compiler-flags", "gcc-sysroot", "qmakeargs", "commit" ], "compile": [ "verifyspec" ], - "detectPkgConfig": [ "cross_compile" ], + "detectPkgConfig": [ "cross_compile", "machineTuple" ], "library": [ "pkg-config" ], "getPkgConfigVariable": [ "pkg-config" ], "neon": [ "architecture" ] @@ -202,6 +202,10 @@ }, "tests": { + "machineTuple": { + "label": "machine tuple", + "type": "machineTuple" + }, "verifyspec": { "label": "valid makespec", "type": "verifySpec", @@ -419,7 +423,14 @@ "features": { "prepare": { - "output": [ "preparePaths" ] + "output": [ "prepareOptions", "preparePaths" ] + }, + "machineTuple": { + "condition": "!config.linux || config.android || tests.machineTuple", + "output": [ "machineTuple" ] + }, + "commit": { + "output": [ "commitOptions" ] }, "android-style-assets": { "label": "Android Style Assets", diff --git a/configure.pri b/configure.pri index 2c70f271b0..b8e338bb54 100644 --- a/configure.pri +++ b/configure.pri @@ -233,6 +233,14 @@ defineReplace(qtConfFunc_licenseCheck) { # custom tests +# this is meant for linux device specs only +defineTest(qtConfTest_machineTuple) { + qtRunLoggedCommand("$$QMAKE_CXX -dumpmachine", $${1}.tuple)|return(false) + $${1}.cache += tuple + export($${1}.cache) + return(true) +} + defineTest(qtConfTest_architecture) { !qtConfTest_compile($${1}): \ error("Could not determine $$eval($${1}.label). See config.log for details.") @@ -328,11 +336,9 @@ defineTest(qtConfTest_detectPkgConfig) { } pkgConfigLibdir = $$sysroot/usr/lib/pkgconfig:$$sysroot/usr/share/pkgconfig - gcc { - qtRunLoggedCommand("$$QMAKE_CXX -dumpmachine", gccMachineDump): \ - !isEmpty(gccMachineDump): \ - pkgConfigLibdir = "$$pkgConfigLibdir:$$sysroot/usr/lib/$$gccMachineDump/pkgconfig" - } + machineTuple = $$eval($${currentConfig}.tests.machineTuple.tuple) + !isEmpty(machineTuple): \ + pkgConfigLibdir = "$$pkgConfigLibdir:$$sysroot/usr/lib/$$machineTuple/pkgconfig" qtConfAddNote("PKG_CONFIG_LIBDIR automatically set to $$pkgConfigLibdir") } @@ -437,6 +443,144 @@ defineTest(qtConfTest_checkCompiler) { # custom outputs +# this reloads the qmakespec as completely as reasonably possible. +defineTest(reloadSpec) { + bypassNesting() { + for (f, QMAKE_INTERNAL_INCLUDED_FILES) { + contains(f, .*/mkspecs/.*):\ + !contains(f, .*/(qt_build_config|qt_parts|qt_configure|configure_base)\\.prf): \ + discard_from($$f) + } + # nobody's going to try to re-load the features above, + # so don't bother with being selective. + QMAKE_INTERNAL_INCLUDED_FEATURES = + + _SAVED_CONFIG = $$CONFIG + load(spec_pre) + load(device_config) # avoid that the spec loads it later. + # discard possible settings from an earlier configure run. + discard_from($$[QT_HOST_DATA/get]/mkspecs/qdevice.pri) + # qdevice.pri gets written too late (and we can't write it early + # enough, as it's populated in stages, with later ones depending + # on earlier ones). so inject its variables manually. + for (l, $${currentConfig}.output.devicePro): \ + eval($$l) + include($$QMAKESPEC/qmake.conf) + load(spec_post) + load(default_pre) + CONFIG += $$_SAVED_CONFIG + + # ensure pristine environment for configuration. again. + discard_from($$[QT_HOST_DATA/get]/mkspecs/qconfig.pri) + discard_from($$[QT_HOST_DATA/get]/mkspecs/qmodule.pri) + } +} + +defineTest(qtConfOutput_prepareOptions) { + $${currentConfig}.output.devicePro += \ + $$replace(config.input.device-option, "^([^=]+) *= *(.*)$", "\\1 = \\2") + darwin:!isEmpty(config.input.sdk) { + $${currentConfig}.output.devicePro += \ + "QMAKE_MAC_SDK = $$val_escape(config.input.sdk)" + } + android { + ndk_root = $$eval(config.input.android-ndk) + isEmpty(ndk_root): \ + ndk_root = $$getenv(ANDROID_NDK_ROOT) + isEmpty(ndk_root): \ + qtConfFatalError("Cannot find Android NDK." \ + "Please use -android-ndk option to specify one.") + + ndk_tc_ver = $$eval(config.input.android-toolchain-version) + isEmpty(ndk_tc_ver): \ + ndk_tc_ver = 4.9 + !exists($$ndk_root/toolchains/arm-linux-androideabi-$$ndk_tc_ver/prebuilt/*): \ + qtConfFatalError("Cannot detect Android NDK toolchain." \ + "Please use -android-toolchain-version to specify it.") + + ndk_tc_pfx = $$ndk_root/toolchains/arm-linux-androideabi-$$ndk_tc_ver/prebuilt + ndk_host = $$eval(config.input.android-ndk-host) + isEmpty(ndk_host): \ + ndk_host = $$getenv(ANDROID_NDK_HOST) + isEmpty(ndk_host) { + equals(QMAKE_HOST.os, Linux) { + ndk_host_64 = linux-x86_64 + ndk_host_32 = linux-x86 + } else: equals(QMAKE_HOST.os, Darwin) { + ndk_host_64 = darwin-x86_64 + ndk_host_32 = darwin-x86 + } else: equals(QMAKE_HOST.os, Windows) { + ndk_host_64 = windows-x86_64 + ndk_host_32 = windows + } else { + qtConfFatalError("Host operating system not supported by Android.") + } + !exists($$ndk_tc_pfx/$$ndk_host_64/*): ndk_host_64 = + !exists($$ndk_tc_pfx/$$ndk_host_32/*): ndk_host_32 = + equals(QMAKE_HOST.arch, x86_64):!isEmpty(ndk_host_64) { + ndk_host = $$ndk_host_64 + } else: equals(QMAKE_HOST.arch, x86):!isEmpty(ndk_host_32) { + ndk_host = $$ndk_host_32 + } else { + !isEmpty(ndk_host_64): \ + ndk_host = $$ndk_host_64 + else: !isEmpty(ndk_host_32): \ + ndk_host = $$ndk_host_32 + else: \ + qtConfFatalError("Cannot detect the Android host." \ + "Please use -android-ndk-host option to specify one.") + qtConfAddNotice("Available Android host does not match host architecture.") + } + } else { + !exists($$ndk_tc_pfx/$$ndk_host/*): \ + qtConfFatalError("Specified Android NDK host is invalid.") + } + + sdk_root = $$eval(config.input.android-sdk) + isEmpty(sdk_root): \ + sdk_root = $$getenv(ANDROID_SDK_ROOT) + isEmpty(sdk_root): \ + qtConfFatalError("Cannot find Android SDK." \ + "Please use -android-sdk option to specify one.") + + target_arch = $$eval(config.input.android-arch) + isEmpty(target_arch): \ + target_arch = armeabi-v7a + + platform = $$eval(config.input.android-ndk-platform) + isEmpty(platform): \ + platform = android-16 ### the windows configure disagrees ... + + $${currentConfig}.output.devicePro += \ + "DEFAULT_ANDROID_SDK_ROOT = $$val_escape(sdk_root)" \ + "DEFAULT_ANDROID_NDK_ROOT = $$val_escape(ndk_root)" \ + "DEFAULT_ANDROID_PLATFORM = $$platform" \ + "DEFAULT_ANDROID_NDK_HOST = $$ndk_host" \ + "DEFAULT_ANDROID_TARGET_ARCH = $$target_arch" \ + "DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION = $$ndk_tc_ver" + } + + export($${currentConfig}.output.devicePro) + + # reload the spec to make the settings actually take effect. + !isEmpty($${currentConfig}.output.devicePro): \ + reloadSpec() +} + +defineTest(qtConfOutput_machineTuple) { + $${currentConfig}.output.devicePro += \ + "GCC_MACHINE_DUMP = $$eval($${currentConfig}.tests.machineTuple.tuple)" + export($${currentConfig}.output.devicePro) + + # for completeness, one could reload the spec here, + # but no downstream users actually need that. +} + +defineTest(qtConfOutput_commitOptions) { + # qdevice.pri needs to be written early, because the compile tests require it. + write_file($$QT_BUILD_TREE/mkspecs/qdevice.pri, $${currentConfig}.output.devicePro)|error() +} + # type (empty or 'host'), option name, default value defineTest(processQtPath) { out_var = config.rel_input.$${2} diff --git a/mkspecs/common/android-base-head.conf b/mkspecs/common/android-base-head.conf index b75bcfaacb..ae4933c453 100644 --- a/mkspecs/common/android-base-head.conf +++ b/mkspecs/common/android-base-head.conf @@ -1,5 +1,8 @@ load(device_config) +# In early configure setup; nothing useful to be done here. +isEmpty(DEFAULT_ANDROID_NDK_ROOT): return() + NDK_ROOT = $$(ANDROID_NDK_ROOT) !exists($$NDK_ROOT) { NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT diff --git a/mkspecs/common/android-base-tail.conf b/mkspecs/common/android-base-tail.conf index 47eaa83e42..23bd6696de 100644 --- a/mkspecs/common/android-base-tail.conf +++ b/mkspecs/common/android-base-tail.conf @@ -1,3 +1,6 @@ +# In early configure setup; nothing useful to be done here. +isEmpty(DEFAULT_ANDROID_NDK_ROOT): return() + # -fstack-protector-strong offers good protection against stack smashing attacks. # It is (currently) enabled only on Android because we know for sure that Andoroid compilers supports it QMAKE_CFLAGS += -fstack-protector-strong -DANDROID diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index cd4d36251e..b7b4e1f994 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -162,7 +162,8 @@ defineTest(qtConfCommandline_addString) { val = $${2} isEmpty(val): val = $$qtConfGetNextCommandlineArg() - contains(val, "^-.*|[A-Z_]+=.*")|isEmpty(val) { + # Note: Arguments which are variable assignments are legit here. + contains(val, "^-.*")|isEmpty(val) { qtConfAddError("No value supplied to command line option '$$opt'.") return() } diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index 3f266dd2a4..0ef0fa8fc7 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -1,4 +1,7 @@ +# In early configure setup; nothing useful to be done here. +isEmpty(QMAKE_CXX): return() + defineReplace(qtMakeExpand) { out = "$$1" for(ever) { diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 630e58d818..373fc89090 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -102,17 +102,6 @@ Configure::~Configure() { } -QString Configure::formatPath(const QString &path) -{ - QString ret = QDir::cleanPath(path); - // This amount of quoting is deemed sufficient. - if (ret.contains(QLatin1Char(' '))) { - ret.prepend(QLatin1Char('"')); - ret.append(QLatin1Char('"')); - } - return ret; -} - void Configure::parseCmdLine() { sourcePathMangled = sourcePath; @@ -166,14 +155,6 @@ void Configure::parseCmdLine() || configCmdLine.at(i) == "-device") { ++i; // do nothing - } else if (configCmdLine.at(i) == "-device-option") { - ++i; - const QString option = configCmdLine.at(i); - QString &devOpt = dictionary["DEVICE_OPTION"]; - if (!devOpt.isEmpty()) - devOpt.append("\n").append(option); - else - devOpt = option; } else if (configCmdLine.at(i) == "-no-syncqt") @@ -186,47 +167,6 @@ void Configure::parseCmdLine() dictionary[ "MAKE" ] = configCmdLine.at(i); } - else if (configCmdLine.at(i) == "-android-ndk") { - ++i; - if (i == argCount) - break; - dictionary[ "ANDROID_NDK_ROOT" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-android-sdk") { - ++i; - if (i == argCount) - break; - dictionary[ "ANDROID_SDK_ROOT" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-android-ndk-platform") { - ++i; - if (i == argCount) - break; - dictionary[ "ANDROID_PLATFORM" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-android-ndk-host") { - ++i; - if (i == argCount) - break; - dictionary[ "ANDROID_HOST" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-android-arch") { - ++i; - if (i == argCount) - break; - dictionary[ "ANDROID_TARGET_ARCH" ] = configCmdLine.at(i); - } - - else if (configCmdLine.at(i) == "-android-toolchain-version") { - ++i; - if (i == argCount) - break; - dictionary[ "ANDROID_NDK_TOOLCHAIN_VERSION" ] = configCmdLine.at(i); - } } // Ensure that QMAKESPEC exists in the mkspecs folder @@ -297,48 +237,6 @@ void Configure::parseCmdLine() } } -void Configure::generateQDevicePri() -{ - FileWriter deviceStream(buildPath + "/mkspecs/qdevice.pri"); - if (dictionary.contains("DEVICE_OPTION")) { - const QString devoptionlist = dictionary["DEVICE_OPTION"]; - const QStringList optionlist = devoptionlist.split(QStringLiteral("\n")); - foreach (const QString &entry, optionlist) - deviceStream << entry << "\n"; - } - if (dictionary.contains("ANDROID_SDK_ROOT") && dictionary.contains("ANDROID_NDK_ROOT")) { - deviceStream << "android_install {" << endl; - deviceStream << " DEFAULT_ANDROID_SDK_ROOT = " << formatPath(dictionary["ANDROID_SDK_ROOT"]) << endl; - deviceStream << " DEFAULT_ANDROID_NDK_ROOT = " << formatPath(dictionary["ANDROID_NDK_ROOT"]) << endl; - if (dictionary.contains("ANDROID_HOST")) - deviceStream << " DEFAULT_ANDROID_NDK_HOST = " << dictionary["ANDROID_HOST"] << endl; - else if (QSysInfo::WordSize == 64) - deviceStream << " DEFAULT_ANDROID_NDK_HOST = windows-x86_64" << endl; - else - deviceStream << " DEFAULT_ANDROID_NDK_HOST = windows" << endl; - QString android_arch(dictionary.contains("ANDROID_TARGET_ARCH") - ? dictionary["ANDROID_TARGET_ARCH"] - : QString("armeabi-v7a")); - QString android_tc_vers(dictionary.contains("ANDROID_NDK_TOOLCHAIN_VERSION") - ? dictionary["ANDROID_NDK_TOOLCHAIN_VERSION"] - : QString("4.9")); - - bool targetIs64Bit = android_arch == QString("arm64-v8a") - || android_arch == QString("x86_64") - || android_arch == QString("mips64"); - QString android_platform(dictionary.contains("ANDROID_PLATFORM") - ? dictionary["ANDROID_PLATFORM"] - : (targetIs64Bit ? QString("android-21") : QString("android-9"))); - - deviceStream << " DEFAULT_ANDROID_PLATFORM = " << android_platform << endl; - deviceStream << " DEFAULT_ANDROID_TARGET_ARCH = " << android_arch << endl; - deviceStream << " DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION = " << android_tc_vers << endl; - deviceStream << "}" << endl; - } - if (!deviceStream.flush()) - dictionary[ "DONE" ] = "error"; -} - void Configure::generateHeaders() { if (dictionary["SYNCQT"] == "auto") @@ -521,47 +419,4 @@ bool Configure::isOk() return (dictionary[ "DONE" ] != "error"); } -FileWriter::FileWriter(const QString &name) - : QTextStream() - , m_name(name) -{ - m_buffer.open(QIODevice::WriteOnly); - setDevice(&m_buffer); -} - -bool FileWriter::flush() -{ - QTextStream::flush(); - QFile oldFile(m_name); - if (oldFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - if (oldFile.readAll() == m_buffer.data()) - return true; - oldFile.close(); - } - QString dir = QFileInfo(m_name).absolutePath(); - if (!QDir().mkpath(dir)) { - cout << "Cannot create directory " << qPrintable(QDir::toNativeSeparators(dir)) << ".\n"; - return false; - } - QFile file(m_name + ".new"); - if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { - if (file.write(m_buffer.data()) == m_buffer.data().size()) { - file.close(); - if (file.error() == QFile::NoError) { - ::SetFileAttributes((wchar_t*)m_name.utf16(), FILE_ATTRIBUTE_NORMAL); - QFile::remove(m_name); - if (!file.rename(m_name)) { - cout << "Cannot replace file " << qPrintable(QDir::toNativeSeparators(m_name)) << ".\n"; - return false; - } - return true; - } - } - } - cout << "Cannot create file " << qPrintable(QDir::toNativeSeparators(file.fileName())) - << ": " << qPrintable(file.errorString()) << ".\n"; - file.remove(); - return false; -} - QT_END_NAMESPACE diff --git a/tools/configure/configureapp.h b/tools/configure/configureapp.h index 32ba7d3444..596196c2a9 100644 --- a/tools/configure/configureapp.h +++ b/tools/configure/configureapp.h @@ -50,7 +50,6 @@ public: void configure(); void generateHeaders(); - void generateQDevicePri(); bool isDone(); bool isOk(); @@ -69,19 +68,7 @@ private: QString sourcePathMangled, buildPathMangled; QDir sourceDir, buildDir; - QString formatPath(const QString &path); - bool reloadCmdLine(int idx); }; -class FileWriter : public QTextStream -{ -public: - FileWriter(const QString &name); - bool flush(); -private: - QString m_name; - QBuffer m_buffer; -}; - QT_END_NAMESPACE diff --git a/tools/configure/main.cpp b/tools/configure/main.cpp index e4b9c12e3d..c6b555d14d 100644 --- a/tools/configure/main.cpp +++ b/tools/configure/main.cpp @@ -55,11 +55,6 @@ int runConfigure( int argc, char** argv ) if (!app.isOk()) return 3; - // Generate qdevice.pri - app.generateQDevicePri(); - if (!app.isOk()) - return 3; - // run qmake based configure app.configure(); if (!app.isOk()) From ab0cc3055d3d1f0faa98f96a7e8ae58b6ef6461a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 16 Nov 2016 15:13:52 +0100 Subject: [PATCH 51/74] move all target spec handling to qmake-based configure system we pull this feat off by booting configure with a dummy spec. the proper spec gets loaded subsequently. note that it was necessary to move the cache loading after processing the early checks (from which the spec handling is triggered). this is just fine, as the cache is needed only by tests, which are forbidden at this stage by definition. Change-Id: I5120e25a8bf05fb8cc5485fd93cf6387301089aa Reviewed-by: Jake Petroules --- configure | 99 +------------------------------ configure.json | 7 ++- configure.pri | 33 ++++++++++- mkspecs/dummy/qmake.conf | 8 +++ mkspecs/features/qt_configure.prf | 16 ++--- tools/configure/configureapp.cpp | 49 +-------------- 6 files changed, 57 insertions(+), 155 deletions(-) create mode 100644 mkspecs/dummy/qmake.conf diff --git a/configure b/configure index 100c3db0d2..82df73fb1b 100755 --- a/configure +++ b/configure @@ -283,23 +283,6 @@ getQMakeConf() getSingleQMakeVariable "$1" "$specvals" } -resolveDeviceMkspec() -{ - result=$(find "$relpath/mkspecs/devices/" -type d -name "*$1*" | sed "s,^$relpath/mkspecs/,,") - match_count=$(echo "$result" | wc -w) - if [ "$match_count" -gt 1 ]; then - echo >&2 "Error: Multiple matches for device '$1'. Candidates are:" - tabbed_result=$(echo "$result" | sed 's,^, ,') - echo >&2 "$tabbed_result" - echo "undefined" - elif [ "$match_count" -eq 0 ]; then - echo >&2 "Error: No device matching '$1'" - echo "undefined" - else - echo "$result" - fi -} - #------------------------------------------------------------------------------- # operating system detection #------------------------------------------------------------------------------- @@ -366,14 +349,6 @@ unset QTDIR # initalize internal variables CFG_RELEASE_TOOLS=no - -XPLATFORM= # This seems to be the QMAKESPEC, like "linux-g++" -XPLATFORM_MAC=no # Whether target platform is macOS, iOS, tvOS, or watchOS -XPLATFORM_IOS=no # Whether target platform is iOS -XPLATFORM_TVOS=no # Whether target platform is tvOS -XPLATFORM_WATCHOS=no # Whether target platform is watchOS -XPLATFORM_ANDROID=no -XPLATFORM_MINGW=no # Whether target platform is MinGW (win32-g++*) PLATFORM= OPT_SHADOW=maybe OPT_VERBOSE=no @@ -503,13 +478,6 @@ while [ "$#" -gt 0 ]; do platform) PLATFORM="$VAL" ;; - xplatform) - XPLATFORM="$VAL" - ;; - device) - XPLATFORM=`resolveDeviceMkspec $VAL` - [ "$XPLATFORM" = "undefined" ] && exit 101 - ;; optimized-qmake|optimized-tools) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then CFG_RELEASE_TOOLS="$VAL" @@ -711,44 +679,6 @@ if [ -z "$PLATFORM" ]; then esac fi -[ -z "$XPLATFORM" ] && XPLATFORM="$PLATFORM" - -case "$XPLATFORM" in - *win32-g++*) - XPLATFORM_MINGW=yes - ;; - *qnx-*) - ;; - *haiku-*) - ;; - *ios*) - XPLATFORM_MAC=yes - XPLATFORM_IOS=yes - ;; - *tvos*) - XPLATFORM_MAC=yes - XPLATFORM_TVOS=yes - ;; - *watchos*) - XPLATFORM_MAC=yes - XPLATFORM_WATCHOS=yes - ;; - *macx*) - XPLATFORM_MAC=yes - ;; - *integrity*) - ;; - # XPLATFORM_ANDROID should not be set for unsupported/android-g++ - *unsupported*) - ;; - *android-g++*) - XPLATFORM_ANDROID=g++ - ;; - *android-clang*) - XPLATFORM_ANDROID=clang - ;; -esac - #------------------------------------------------------------------------------- # command line and environment validation #------------------------------------------------------------------------------- @@ -758,14 +688,9 @@ if [ -d "$PLATFORM" ]; then else QMAKESPEC="$relpath/mkspecs/${PLATFORM}" fi -if [ -d "$XPLATFORM" ]; then - XQMAKESPEC="$XPLATFORM" -else - XQMAKESPEC="$relpath/mkspecs/${XPLATFORM}" -fi if [ "$BUILD_ON_MAC" = "yes" ]; then - if [ `basename $QMAKESPEC` = "macx-xcode" ] || [ `basename $XQMAKESPEC` = "macx-xcode" ]; then + if [ `basename $QMAKESPEC` = "macx-xcode" ]; then echo >&2 echo " Platform 'macx-xcode' should not be used when building Qt/Mac." >&2 echo " Please build Qt/Mac with 'macx-clang' or 'macx-g++', then use" >&2 @@ -787,26 +712,6 @@ if [ '!' -d "$QMAKESPEC" ]; then echo exit 2 fi -if [ '!' -d "$XQMAKESPEC" ]; then - echo - echo " The specified system/compiler is not supported:" - echo - echo " $XQMAKESPEC" - echo - echo " Please see the README file for a complete list." - echo - exit 2 -fi -if [ '!' -f "${XQMAKESPEC}/qplatformdefs.h" ]; then - echo - echo " The specified system/compiler port is not complete:" - echo - echo " $XQMAKESPEC/qplatformdefs.h" - echo - echo " Please information use the contact form at http://www.qt.io/contact-us" - echo - exit 2 -fi #------------------------------------------------------------------------------- # build tree initialization @@ -980,7 +885,7 @@ cat > "$QTCONFFILE" < 1) { - dictionary[ "DONE" ] = "error"; - - cout << "Error: Multiple matches for device '" << dictionary["XQMAKESPEC"] << "'. Candidates are:" << endl; - - foreach (const QString &device, family) - cout << "\t* " << device << endl; - } else { - Q_ASSERT(family.size() == 1); - dictionary["XQMAKESPEC"] = family.at(0); - } - - } else { - // Ensure that -spec (XQMAKESPEC) exists in the mkspecs folder as well - if (dictionary.contains("XQMAKESPEC") && - !mkspecs.contains(dictionary["XQMAKESPEC"], Qt::CaseInsensitive)) { - dictionary[ "DONE" ] = "error"; - cout << "Invalid option \"" << dictionary["XQMAKESPEC"] << "\" for -xplatform." << endl; - } - } } void Configure::generateHeaders() @@ -361,8 +315,7 @@ void Configure::buildQmake() confStream << "[EffectivePaths]" << endl << "Prefix=.." << endl << "[Paths]" << endl - << "TargetSpec=" << (dictionary.contains("XQMAKESPEC") - ? dictionary["XQMAKESPEC"] : dictionary["QMAKESPEC"]) << endl + << "TargetSpec=dummy" << endl << "HostSpec=" << dictionary["QMAKESPEC"] << endl; if (sourcePath != buildPath) confStream << "[EffectiveSourcePaths]" << endl From f92cfab225757084bd89638cd83dc7734f84b5e2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 13 Dec 2016 13:08:40 -0800 Subject: [PATCH 52/74] Silence warning about non-void function without return value Q_UNREACHABLE() isn't enough for some compilers, especially if it expands to nothing. warning #1011: missing return statement at end of non-void function "fetchPixel(const uchar={unsigned char} *, int) [with bpp=QPixelLayout::BPPNone]" Change-Id: I3e3f0326f7234a26acf5fffd148fecf0b72ea7e0 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index ff7c8dfc28..af32811d34 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -843,6 +843,7 @@ template static uint QT_FASTCALL fetchPixel(const uchar *, int) { Q_UNREACHABLE(); + return 0; } template <> From 9cc3c8983e7f35dc52869cf44d566c752540f1fd Mon Sep 17 00:00:00 2001 From: Venugopal Shivashankar Date: Thu, 8 Dec 2016 17:43:02 +0100 Subject: [PATCH 53/74] Doc: Update the highlighted examples list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed a few from the list after testing them on a Linux desktop and an Android device. Change-Id: If1b9e7739d8c374acc8cbd2c72d7176fdff2e9f3 Reviewed-by: Topi Reiniö Reviewed-by: Leena Miettinen --- doc/global/manifest-meta.qdocconf | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/doc/global/manifest-meta.qdocconf b/doc/global/manifest-meta.qdocconf index 7ebe86a431..865a457581 100644 --- a/doc/global/manifest-meta.qdocconf +++ b/doc/global/manifest-meta.qdocconf @@ -33,7 +33,6 @@ manifestmeta.filters = highlighted android thumbnail ios manifestmeta.highlighted.names = "QtQuick/Qt Quick Demo - Same Game" \ "QtQuick/Qt Quick Demo - Photo Surface" \ "QtQuick/Qt Quick Demo - Tweet Search" \ - "QtQuick/Qt Quick Demo - Maroon*" \ "QtQuick/Qt Quick Demo - Calqlatr" \ "QtQuick/Qt Quick Demo - StocQt" \ "QtQuick/Qt Quick Demo - Clocks" \ @@ -45,14 +44,12 @@ manifestmeta.highlighted.names = "QtQuick/Qt Quick Demo - Same Game" \ "QtQuickDialogs/Qt Quick System Dialog Examples" \ "QtWinExtras/Quick Player" \ "QtMultimedia/QML Video Shader Effects Example" \ - "QtCanvas3D/Planets Example" \ "QtCanvas3D/Interactive Mobile Phone Example" \ "QtLocation/Map Viewer (QML)" manifestmeta.highlighted.attributes = isHighlighted:true -manifestmeta.android.names = "QtQuick/Qt Quick Demo - Maroon*" \ - "QtQuick/Qt Quick Demo - Calqlatr" \ +manifestmeta.android.names = "QtQuick/Qt Quick Demo - Calqlatr" \ "QtWidgets/Application Chooser Example" \ "QtWidgets/Stickman Example" \ "QtWidgets/Move Blocks Example" \ From 1d68e3386d7013152417b599be7798ff19331ce4 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 14 Dec 2016 08:36:03 +0100 Subject: [PATCH 54/74] eglfs/deviceintegration: Ensure eglfs_kms_support is added only once Use qmake operator *= to prevent adding it multiple times resulting in warnings on Linux/Desktop: Makefile:114: warning: overriding recipe for target 'sub-eglfs_kms_support-qmake_all' Makefile:64: warning: ignoring old recipe for target 'sub-eglfs_kms_support-qmake_all' Makefile:118: warning: overriding recipe for target 'sub-eglfs_kms_support' ... Change-Id: I18a926c9faeb8f9eafea5223d32c526c06c43724 Reviewed-by: Laszlo Agocs --- .../platforms/eglfs/deviceintegration/deviceintegration.pro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro index d86a67b4f4..f936d05927 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro @@ -2,8 +2,8 @@ TEMPLATE = subdirs QT_FOR_CONFIG += gui-private qtConfig(egl_x11): SUBDIRS += eglfs_x11 -qtConfig(eglfs_gbm): SUBDIRS += eglfs_kms_support eglfs_kms -qtConfig(eglfs_egldevice): SUBDIRS += eglfs_kms_support eglfs_kms_egldevice +qtConfig(eglfs_gbm): SUBDIRS *= eglfs_kms_support eglfs_kms +qtConfig(eglfs_egldevice): SUBDIRS *= eglfs_kms_support eglfs_kms_egldevice qtConfig(eglfs_brcm): SUBDIRS += eglfs_brcm qtConfig(eglfs_mali): SUBDIRS += eglfs_mali qtConfig(eglfs_viv): SUBDIRS += eglfs_viv From 5556308cbfabb1eef63359dfec24b8bcff44cb94 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 12 Dec 2016 16:33:14 -0800 Subject: [PATCH 55/74] MySQL: Make sure we clean the libraries from mysql_config It prints libraries necessary for linking against the MySQL static library. When linking against dynamic libraries, we end up with too many parameters. We don't want to explicitly link our plugin to OpenSSL and this is especially important on macOS since Sierra no longer comes with OpenSSL development files. On my Linux: -L/usr/lib64 -lmysqlclient -lpthread -lz -lm -lssl -lcrypto -ldl On my macOS: -L/usr/local/Cellar/mysql/5.7.16/lib -lmysqlclient -lssl -lcrypto Instead, keep only -L options (that haven't been removed by the function $$filterLibraryPath above) and the actual client library. Change-Id: I3e3f0326f7234a26acf5fffd148fa985d0fd9c93 Reviewed-by: Oswald Buddenhagen --- src/sql/configure.json | 6 ++++-- src/sql/configure.pri | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/sql/configure.json b/src/sql/configure.json index 96c82e84f9..72671b6df9 100644 --- a/src/sql/configure.json +++ b/src/sql/configure.json @@ -58,8 +58,10 @@ "label": "MySQL", "test": "unix/mysql", "sources": [ - { "type": "mysqlConfig", "query": "--libs_r" }, - { "type": "mysqlConfig", "query": "--libs" }, + { "type": "mysqlConfig", "query": "--libs_r", "cleanlibs": true }, + { "type": "mysqlConfig", "query": "--libs", "cleanlibs": true }, + { "type": "mysqlConfig", "query": "--libs_r", "cleanlibs": false }, + { "type": "mysqlConfig", "query": "--libs", "cleanlibs": false }, { "libs": "-lmysqlclient_r", "condition": "!config.win32" }, { "libs": "-llibmysql", "condition": "config.win32" }, { "libs": "-lmysqlclient", "condition": "!config.win32" } diff --git a/src/sql/configure.pri b/src/sql/configure.pri index 1d8847b4bc..62d56e2186 100644 --- a/src/sql/configure.pri +++ b/src/sql/configure.pri @@ -57,6 +57,14 @@ defineTest(qtConfLibrary_mysqlConfig) { libs = $$filterLibraryPath($$libs) # -rdynamic should not be returned by mysql_config, but is on RHEL 6.6 libs -= -rdynamic + equals($${1}.cleanlibs, true) { + for(l, libs) { + # Drop all options besides the -L one and the -lmysqlclient one + # so we don't unnecessarily link to libs like OpenSSL + contains(l, "^(-L|-lmysqlclient).*"): cleanlibs += $$l + } + libs = $$cleanlibs + } $${1}.libs = "$$val_escape(libs)" eval(includedir = $$includedir) includedir ~= s/^-I//g From b8fab7c9f5debec9e26816b6b9581de921f90ef6 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 14 Dec 2016 15:37:52 +0200 Subject: [PATCH 56/74] Add Q_[ENUM|FLAG]_NS to global qt-cpp-defines doc conf We need to add Q_[ENUM|FLAG]_NS to global qt-cpp-defines doc conf otherwise qdoc ignores them and it will not produce any documentation or links to these enums/flags Task-number: QTBUG-57616 Change-Id: I744317346feb41db02787677f8698c4de15db226 Reviewed-by: Martin Smith --- doc/global/qt-cpp-defines.qdocconf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/global/qt-cpp-defines.qdocconf b/doc/global/qt-cpp-defines.qdocconf index fe8b7fb87e..5ebb208bcc 100644 --- a/doc/global/qt-cpp-defines.qdocconf +++ b/doc/global/qt-cpp-defines.qdocconf @@ -148,8 +148,10 @@ Cpp.ignoredirectives += \ Q_DUMMY_COMPARISON_OPERATOR \ Q_ENUM \ Q_ENUMS \ + Q_ENUM_NS \ Q_FLAG \ Q_FLAGS \ + Q_FLAG_NS \ Q_INTERFACES \ Q_PRIVATE_PROPERTY \ QT_FORWARD_DECLARE_CLASS \ From 1f665efa913bf55f215ceff27ebfc9f0e0769aee Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 12 Dec 2016 11:39:38 +0100 Subject: [PATCH 57/74] Q_CHECK_PTR the result of QDataBuffer's allocations We might run out of memory or malloc() or realloc() might fail for any other reason. We want to crash cleanly with a clear message in that case, rather than returning a null pointer. Change-Id: If09c1b9e905fc60a5d9d45e598a418df433cf83b Reviewed-by: Thiago Macieira --- src/gui/painting/qdatabuffer_p.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/gui/painting/qdatabuffer_p.h b/src/gui/painting/qdatabuffer_p.h index 77b5be0c4c..7cac2ac358 100644 --- a/src/gui/painting/qdatabuffer_p.h +++ b/src/gui/painting/qdatabuffer_p.h @@ -65,10 +65,12 @@ public: QDataBuffer(int res) { capacity = res; - if (res) + if (res) { buffer = (Type*) malloc(capacity * sizeof(Type)); - else + Q_CHECK_PTR(buffer); + } else { buffer = 0; + } siz = 0; } @@ -115,14 +117,16 @@ public: while (capacity < size) capacity *= 2; buffer = (Type*) realloc(buffer, capacity * sizeof(Type)); + Q_CHECK_PTR(buffer); } } inline void shrink(int size) { capacity = size; - if (size) + if (size) { buffer = (Type*) realloc(buffer, capacity * sizeof(Type)); - else { + Q_CHECK_PTR(buffer); + } else { free(buffer); buffer = 0; } From 87e553b58a8b59bfafb670272a33848bc415042d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Tue, 13 Dec 2016 15:28:55 +0100 Subject: [PATCH 58/74] Android: Fix the bearer management plugin when running as a service Since Qt for Android now supports running as a service, we shouldn't use the activity context unconditionally, but instead query the current context from QtAndroidPrivate::context(). Change-Id: Ib793ba890fdbfc0cfe7b20115e41ff64cc73477a Reviewed-by: Andy Shaw Reviewed-by: BogDan Vatra --- .../qt5/android/bearer/QtNetworkReceiver.java | 13 ++++++------- .../src/wrappers/androidconnectivitymanager.cpp | 12 ++++++------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/plugins/bearer/android/jar/src/org/qtproject/qt5/android/bearer/QtNetworkReceiver.java b/src/plugins/bearer/android/jar/src/org/qtproject/qt5/android/bearer/QtNetworkReceiver.java index 8170188ecb..805c90548b 100644 --- a/src/plugins/bearer/android/jar/src/org/qtproject/qt5/android/bearer/QtNetworkReceiver.java +++ b/src/plugins/bearer/android/jar/src/org/qtproject/qt5/android/bearer/QtNetworkReceiver.java @@ -44,7 +44,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.util.Log; -import android.app.Activity; import android.net.ConnectivityManager; public class QtNetworkReceiver @@ -65,29 +64,29 @@ public class QtNetworkReceiver private QtNetworkReceiver() {} - public static void registerReceiver(final Activity activity) + public static void registerReceiver(final Context context) { synchronized (m_lock) { if (m_broadcastReceiver == null) { m_broadcastReceiver = new BroadcastReceiverPrivate(); IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); - activity.registerReceiver(m_broadcastReceiver, intentFilter); + context.registerReceiver(m_broadcastReceiver, intentFilter); } } } - public static void unregisterReceiver(final Activity activity) + public static void unregisterReceiver(final Context context) { synchronized (m_lock) { if (m_broadcastReceiver == null) return; - activity.unregisterReceiver(m_broadcastReceiver); + context.unregisterReceiver(m_broadcastReceiver); } } - public static ConnectivityManager getConnectivityManager(final Activity activity) + public static ConnectivityManager getConnectivityManager(final Context context) { - return (ConnectivityManager)activity.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); + return (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); } } diff --git a/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp b/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp index 3a5030d1f3..6787690246 100644 --- a/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp +++ b/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp @@ -250,15 +250,15 @@ AndroidConnectivityManager::AndroidConnectivityManager() m_connectivityManager = QJNIObjectPrivate::callStaticObjectMethod(networkReceiverClass, "getConnectivityManager", - "(Landroid/app/Activity;)Landroid/net/ConnectivityManager;", - QtAndroidPrivate::activity()); + "(Landroid/content/Context;)Landroid/net/ConnectivityManager;", + QtAndroidPrivate::context()); if (!m_connectivityManager.isValid()) return; QJNIObjectPrivate::callStaticMethod(networkReceiverClass, "registerReceiver", - "(Landroid/app/Activity;)V", - QtAndroidPrivate::activity()); + "(Landroid/content/Context;)V", + QtAndroidPrivate::context()); } AndroidConnectivityManager *AndroidConnectivityManager::getInstance() @@ -272,8 +272,8 @@ AndroidConnectivityManager::~AndroidConnectivityManager() { QJNIObjectPrivate::callStaticMethod(networkReceiverClass, "unregisterReceiver", - "(Landroid/app/Activity;)V", - QtAndroidPrivate::activity()); + "(Landroid/content/Context;)V", + QtAndroidPrivate::context()); } AndroidNetworkInfo AndroidConnectivityManager::getActiveNetworkInfo() const From b57e7c0963dbe5d6d85f6596d8264246ab339a7c Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Wed, 7 Dec 2016 18:11:39 +0300 Subject: [PATCH 59/74] doc: Replace Q_DECL_OVERRIDE by override in snippets And remove redundant virtual. Change-Id: If0650409b88ad962f6713d082d9095675f4c68e8 Reviewed-by: Friedemann Kleint Reviewed-by: hjk --- .../code/src_corelib_kernel_qabstractnativeeventfilter.cpp | 2 +- .../code/src_corelib_kernel_qabstractnativeeventfilter.h | 2 +- src/corelib/doc/snippets/code/src_corelib_thread_qthread.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.cpp index d222ca32a7..b84cf0ae2d 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.cpp @@ -52,7 +52,7 @@ class MyXcbEventFilter : public QAbstractNativeEventFilter { public: - virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE + bool nativeEventFilter(const QByteArray &eventType, void *message, long *) override { if (eventType == "xcb_generic_event_t") { xcb_generic_event_t* ev = static_cast(message); diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h index 6666bc56c5..9734f99d50 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h @@ -44,6 +44,6 @@ class MyCocoaEventFilter : public QAbstractNativeEventFilter { public: - bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE; + bool nativeEventFilter(const QByteArray &eventType, void *message, long *) override; }; //! [0] diff --git a/src/corelib/doc/snippets/code/src_corelib_thread_qthread.cpp b/src/corelib/doc/snippets/code/src_corelib_thread_qthread.cpp index a621109c0d..7c687a0430 100644 --- a/src/corelib/doc/snippets/code/src_corelib_thread_qthread.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_thread_qthread.cpp @@ -55,7 +55,7 @@ class MyObject; class WorkerThread : public QThread { Q_OBJECT - void run() Q_DECL_OVERRIDE { + void run() override { QString result; /* ... here is the expensive or blocking operation ... */ emit resultReady(result); From 39642fcc9e58926ed6a52009a2180a2d3a566c8e Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Wed, 14 Dec 2016 00:57:54 +0300 Subject: [PATCH 60/74] manual tests: Fix build with modularized configure.json Change-Id: I7979b147cc53d9f5250ba983da1245152dcbb2ec Reviewed-by: Oswald Buddenhagen --- tests/manual/manual.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index 2fe96c2f93..8367994509 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -1,4 +1,5 @@ TEMPLATE=subdirs +QT_FOR_CONFIG += network-private gui-private SUBDIRS = bearerex \ filetest \ From b08bdfb2e4de1f0b01e771dcd6d65afea0cbdd24 Mon Sep 17 00:00:00 2001 From: James McDonnell Date: Tue, 13 Dec 2016 14:33:04 -0500 Subject: [PATCH 61/74] Fix qtlibpng being built despite system libpng being found 90eee08b made system-png a subset of png, which is strictly speaking a porting error. However, as this is a good idea as such, fix it by adding the missing !system-png check. Change-Id: I1557a2130a22ac668be315dc9aea67845928ff4c Reviewed-by: Oswald Buddenhagen Reviewed-by: Andrew Knight --- src/src.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src.pro b/src/src.pro index b13bc4fa43..90d7e2b76c 100644 --- a/src/src.pro +++ b/src/src.pro @@ -164,7 +164,7 @@ qtConfig(gui) { SUBDIRS += src_angle src_gui.depends += src_angle } - qtConfig(png) { + qtConfig(png):!qtConfig(system-png) { SUBDIRS += src_3rdparty_libpng src_3rdparty_freetype.depends += src_3rdparty_libpng src_gui.depends += src_3rdparty_libpng From 6b79e18f172c6ffc8811fc4b60ebe54fdfb999f1 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Wed, 14 Dec 2016 12:57:28 +0100 Subject: [PATCH 62/74] qdoc: Ignore macro QT_WARNING_DISABLE_DEPRECATED This macro, introduced in Qt 5.8, needs to be ignored by QDoc in order to generate documentation correctly for a number of deprecated functions. Change-Id: I50bcd42167e3fafb7dda88484fde86e1aebb5980 Reviewed-by: Martin Smith --- doc/global/qt-cpp-defines.qdocconf | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/global/qt-cpp-defines.qdocconf b/doc/global/qt-cpp-defines.qdocconf index 4aa9111853..73bd8559d0 100644 --- a/doc/global/qt-cpp-defines.qdocconf +++ b/doc/global/qt-cpp-defines.qdocconf @@ -122,6 +122,7 @@ Cpp.ignoretokens += \ QT_END_NAMESPACE \ QT_FASTCALL \ QT_MUTEX_LOCK_NOEXCEPT \ + QT_WARNING_DISABLE_DEPRECATED \ QT_WARNING_PUSH \ QT_WARNING_POP \ QT_WIDGET_PLUGIN_EXPORT \ From cfbe5df48cb782294ea47ecf6c598707df8e0b69 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Wed, 14 Dec 2016 14:24:08 +0100 Subject: [PATCH 63/74] qdoc: Define Q_COMPILER_UNICODE_STRINGS Some public functions in QString and QDebug are declared inside Q_COMPILER_UNICODE_STRINGS. This commit defines it for QDoc, and adds documentation for QDebug functions that are now visible to QDoc. Change-Id: Ia7f2501c1dc7b8244dcc3ce4adcd2019fdbffcb6 Reviewed-by: Martin Smith Reviewed-by: Thiago Macieira --- doc/global/qt-cpp-defines.qdocconf | 1 + src/corelib/io/qdebug.cpp | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/doc/global/qt-cpp-defines.qdocconf b/doc/global/qt-cpp-defines.qdocconf index 73bd8559d0..f807241584 100644 --- a/doc/global/qt-cpp-defines.qdocconf +++ b/doc/global/qt-cpp-defines.qdocconf @@ -14,6 +14,7 @@ defines += Q_QDOC \ Q_NO_USING_KEYWORD \ __cplusplus \ Q_COMPILER_INITIALIZER_LISTS \ + Q_COMPILER_UNICODE_STRINGS \ Q_COMPILER_UNIFORM_INIT \ Q_COMPILER_RVALUE_REFS diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp index fa919e9f10..be33ec2d23 100644 --- a/src/corelib/io/qdebug.cpp +++ b/src/corelib/io/qdebug.cpp @@ -578,6 +578,22 @@ QDebug &QDebug::resetFormat() output, but note that some QDebug backends might not be 8-bit clean. */ +/*! + \fn QDebug &QDebug::operator<<(char16_t t) + \since 5.5 + + Writes the UTF-16 character, \a t, to the stream and returns a reference + to the stream. +*/ + +/*! + \fn QDebug &QDebug::operator<<(char32_t t) + \since 5.5 + + Writes the UTF-32 character, \a t, to the stream and returns a reference + to the stream. +*/ + /*! \fn QDebug &QDebug::operator<<(const QString &s) From 56a167d30c48e163f6abd089b68edda3ed9d5be1 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Thu, 24 Nov 2016 15:44:57 +0100 Subject: [PATCH 64/74] winrt: Check for removed timers after sending events After all the check makes sense here. If a timer was removed as a result of sendEvent and it was not at the end of the list the list is not shrunk but the timer info's id is just set to INVALID_TIMER_ID. Additionally the timer's object should be fetched before we unlock the locker as timerIdToObject is changed in removeTimer and we might access a nullptr if the timer has been removed. Reverts c83ba01f7bc542368973f3f24dfb59c6052dd78a Task-number: QTBUG-56756 Change-Id: Ib1a04c02fbfcf4c939b4891d42f954dc9e87149e (cherry picked from commit 8f2088db171a6941feb1903a2912a8b7fdf3a9ec) Reviewed-by: Maurice Kalinowski --- src/corelib/kernel/qeventdispatcher_winrt.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp index ff397fc750..33753ed507 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt.cpp +++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp @@ -166,7 +166,7 @@ private: timerIdToHandle.insert(id, handle); timerIdToCancelHandle.insert(id, cancelHandle); } - timerIdToObject.insert(id, obj); + const quint64 targetTime = qt_msectime() + interval; const WinRTTimerInfo info(id, interval, type, obj, targetTime); QMutexLocker locker(&timerInfoLock); @@ -587,15 +587,18 @@ bool QEventDispatcherWinRT::event(QEvent *e) break; info.inEvent = true; + QObject *timerObj = d->timerIdToObject.value(id); locker.unlock(); QTimerEvent te(id); - QCoreApplication::sendEvent(d->timerIdToObject.value(id), &te); + QCoreApplication::sendEvent(timerObj, &te); locker.relock(); - // The timer might have been removed in the meanwhile - if (id >= d->timerInfos.size()) + // The timer might have been removed in the meanwhile. If the timer was + // the last one in the list, id is bigger than the list's size. + // Otherwise, the id will just be set to INVALID_TIMER_ID. + if (id >= d->timerInfos.size() || info.timerId == INVALID_TIMER_ID) break; if (info.interval == 0 && info.inEvent) { From 3a9801d568e2f7d5a95ed4f5886a7f5062869456 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 12 Dec 2016 13:35:30 +0100 Subject: [PATCH 65/74] doc: Specify which characters are replaced by toPlainText() Some formatting characters are replaced by ASCII in the output from toPlainText(). Since this is a bit inconsistent, we should document it. Task-number: QTBUG-57552 Change-Id: I46033588d37517056a8d4668d1d16d48c72ee1b5 Reviewed-by: Lars Knoll --- src/gui/text/qtextdocument.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 0d05fee6ef..c006e7f427 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -1148,6 +1148,11 @@ void QTextDocument::setMetaInformation(MetaInformation info, const QString &stri Returns the plain text contained in the document. If you want formatting information use a QTextCursor instead. + Some formatting characters are replaced by ASCII equivalents. + In particular, no-break space (U+00A0) is replaced by a regular + space (U+0020), and both paragraph (U+2029) and line (U+2028) + separators are replaced by line feed (U+000A). + \note Embedded objects, such as images, are represented by a Unicode value U+FFFC (OBJECT REPLACEMENT CHARACTER). From 104854708cf610a4999cb0a3bde3c900045d1db9 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 15 Dec 2016 11:13:47 +0200 Subject: [PATCH 66/74] Update Ministro's url Task-number: QTBUG-57645 Change-Id: I014b1926c9b91e085baa5df563dc4cc06fe0596c Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/android/templates/res/values/libs.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/android/templates/res/values/libs.xml b/src/android/templates/res/values/libs.xml index 43296f2e7a..77f422cfb2 100644 --- a/src/android/templates/res/values/libs.xml +++ b/src/android/templates/res/values/libs.xml @@ -1,7 +1,7 @@ - https://download.qt.io/ministro/android/qt5/qt-5.7 + https://download.qt.io/ministro/android/qt5/qt-5.8