diff options
66 files changed, 643 insertions, 318 deletions
@@ -4198,6 +4198,9 @@ if [ "$CFG_NEON" = "auto" ]; then *neon*) CFG_NEON=yes ;; + *) + CFG_NEON=no + ;; esac fi diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp index 73c53ea649..acbd7dda8f 100644 --- a/src/corelib/json/qjsonarray.cpp +++ b/src/corelib/json/qjsonarray.cpp @@ -709,6 +709,11 @@ bool QJsonArray::operator!=(const QJsonArray &other) const \internal */ +/*! \typedef QJsonArray::iterator::pointer + + \internal +*/ + /*! \fn QJsonArray::iterator::iterator() Constructs an uninitialized iterator. @@ -953,6 +958,11 @@ bool QJsonArray::operator!=(const QJsonArray &other) const \internal */ +/*! \typedef QJsonArray::const_iterator::pointer + + \internal +*/ + /*! \fn QJsonArray::const_iterator::const_iterator(const const_iterator &other) Constructs a copy of \a other. diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 77900ba906..ca3d92bad1 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -2580,6 +2580,7 @@ void QCoreApplication::removeNativeEventFilter(QAbstractNativeEventFilter *filte \sa QAbstractEventDispatcher::hasPendingEvents() */ +#if QT_DEPRECATED_SINCE(5, 3) bool QCoreApplication::hasPendingEvents() { QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(); @@ -2587,6 +2588,7 @@ bool QCoreApplication::hasPendingEvents() return eventDispatcher->hasPendingEvents(); return false; } +#endif /*! Returns a pointer to the event dispatcher object for the main thread. If no diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 36acfc4c09..26bf7d047d 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -3644,7 +3644,7 @@ QByteArray QByteArray::toBase64(Base64Options options) const const char padchar = '='; int padlen = 0; - QByteArray tmp((d->size * 4) / 3 + 3, Qt::Uninitialized); + QByteArray tmp((d->size + 2) / 3 * 4, Qt::Uninitialized); int i = 0; char *out = tmp.data(); @@ -3682,8 +3682,9 @@ QByteArray QByteArray::toBase64(Base64Options options) const *out++ = alphabet[m]; } } - - tmp.truncate(out - tmp.data()); + Q_ASSERT((options & OmitTrailingEquals) || (out == tmp.size() + tmp.data())); + if (options & OmitTrailingEquals) + tmp.truncate(out - tmp.data()); return tmp; } diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 76069225eb..e830ed36e5 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1723,9 +1723,9 @@ void QString::expand(int i) /*! \fn void QString::clear() - Clears the contents of the string and makes it empty. + Clears the contents of the string and makes it null. - \sa resize(), isEmpty() + \sa resize(), isNull() */ /*! \fn QString &QString::operator=(const QString &other) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index a0b6256e72..9eefa968ad 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -207,7 +207,9 @@ QMouseEvent::QMouseEvent(Type type, const QPointF &localPos, Qt::MouseButton but Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) : QInputEvent(type, modifiers), l(localPos), w(localPos), b(button), mouseState(buttons), caps(0) { +#ifndef QT_NO_CURSOR s = QCursor::pos(); +#endif } @@ -1594,7 +1596,9 @@ QContextMenuEvent::~QContextMenuEvent() QContextMenuEvent::QContextMenuEvent(Reason reason, const QPoint &pos) : QInputEvent(ContextMenu), p(pos), reas(reason) { +#ifndef QT_NO_CURSOR gp = QCursor::pos(); +#endif } /*! diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index e421f79e91..ded3788dbf 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -869,7 +869,7 @@ QWindowList QGuiApplication::topLevelWindows() /*! Returns the primary (or default) screen of the application. - This will be the screen where QWindows are shown, unless otherwise specified. + This will be the screen where QWindows are initially shown, unless otherwise specified. */ QScreen *QGuiApplication::primaryScreen() { @@ -3386,15 +3386,21 @@ void QGuiApplicationPrivate::_q_updateFocusObject(QObject *object) { Q_Q(QGuiApplication); + QPlatformInputContext *inputContext = platformIntegration()->inputContext(); bool enabled = false; - if (object) { - QInputMethodQueryEvent query(Qt::ImEnabled); + if (object && inputContext) { + QInputMethodQueryEvent query(Qt::ImEnabled | Qt::ImHints); QGuiApplication::sendEvent(object, &query); enabled = query.value(Qt::ImEnabled).toBool(); + if (enabled) { + static const bool supportsHiddenText = inputContext->hasCapability(QPlatformInputContext::HiddenTextCapability); + const Qt::InputMethodHints hints = static_cast<Qt::InputMethodHints>(query.value(Qt::ImHints).toInt()); + if ((hints & Qt::ImhHiddenText) && !supportsHiddenText) + enabled = false; + } } QPlatformInputContextPrivate::setInputMethodAccepted(enabled); - QPlatformInputContext *inputContext = platformIntegration()->inputContext(); if (inputContext) inputContext->setFocusObject(object); emit q->focusObjectChanged(object); diff --git a/src/gui/kernel/qplatforminputcontext.cpp b/src/gui/kernel/qplatforminputcontext.cpp index 71dd609868..5937c65cc7 100644 --- a/src/gui/kernel/qplatforminputcontext.cpp +++ b/src/gui/kernel/qplatforminputcontext.cpp @@ -92,6 +92,17 @@ bool QPlatformInputContext::isValid() const } /*! + Returns whether the implementation supports \a capability. + \internal + \since 5.4 + */ +bool QPlatformInputContext::hasCapability(Capability capability) const +{ + Q_UNUSED(capability) + return true; +} + +/*! Method to be called when input method needs to be reset. Called by QInputMethod::reset(). No further QInputMethodEvents should be sent as response. */ diff --git a/src/gui/kernel/qplatforminputcontext.h b/src/gui/kernel/qplatforminputcontext.h index 7dd89ecd00..0c8953f89c 100644 --- a/src/gui/kernel/qplatforminputcontext.h +++ b/src/gui/kernel/qplatforminputcontext.h @@ -55,10 +55,15 @@ class Q_GUI_EXPORT QPlatformInputContext : public QObject Q_DECLARE_PRIVATE(QPlatformInputContext) public: + enum Capability { + HiddenTextCapability = 0x1 + }; + QPlatformInputContext(); virtual ~QPlatformInputContext(); virtual bool isValid() const; + virtual bool hasCapability(Capability capability) const; virtual void reset(); virtual void commit(); diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index c6e5cfb9d6..167bd44f0e 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -526,12 +526,14 @@ static inline const QScreen *effectiveScreen(const QWindow *window) if (!screen) return QGuiApplication::primaryScreen(); const QList<QScreen *> siblings = screen->virtualSiblings(); +#ifndef QT_NO_CURSOR if (siblings.size() > 1) { const QPoint referencePoint = window->transientParent() ? window->transientParent()->geometry().center() : QCursor::pos(); foreach (const QScreen *sibling, siblings) if (sibling->geometry().contains(referencePoint)) return sibling; } +#endif return screen; } diff --git a/src/gui/kernel/qshapedpixmapdndwindow.cpp b/src/gui/kernel/qshapedpixmapdndwindow.cpp index af60b36647..c8e9c2544d 100644 --- a/src/gui/kernel/qshapedpixmapdndwindow.cpp +++ b/src/gui/kernel/qshapedpixmapdndwindow.cpp @@ -88,12 +88,14 @@ void QShapedPixmapWindow::setHotspot(const QPoint &hotspot) void QShapedPixmapWindow::updateGeometry() { +#ifndef QT_NO_CURSOR QRect rect(QCursor::pos() - m_hotSpot, m_pixmap.size()); if (m_pixmap.isNull()) m_backingStore->resize(QSize(1,1)); else if (m_backingStore->size() != m_pixmap.size()) m_backingStore->resize(m_pixmap.size()); setGeometry(rect); +#endif } void QShapedPixmapWindow::exposeEvent(QExposeEvent *) diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp index 8049e303a7..b7f8e375a4 100644 --- a/src/gui/kernel/qsurfaceformat.cpp +++ b/src/gui/kernel/qsurfaceformat.cpp @@ -308,6 +308,7 @@ void QSurfaceFormat::setSamples(int numSamples) } } +#if QT_DEPRECATED_SINCE(5, 2) /*! \obsolete \overload @@ -343,6 +344,7 @@ bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOptions opt) const { return d->opts & opt; } +#endif // QT_DEPRECATED_SINCE(5, 2) /*! \since 5.3 diff --git a/src/gui/kernel/qsurfaceformat.h b/src/gui/kernel/qsurfaceformat.h index 797331e5a7..b33f4d1f6b 100644 --- a/src/gui/kernel/qsurfaceformat.h +++ b/src/gui/kernel/qsurfaceformat.h @@ -119,8 +119,10 @@ public: bool stereo() const; void setStereo(bool enable); +#if QT_DEPRECATED_SINCE(5, 2) QT_DEPRECATED void setOption(QSurfaceFormat::FormatOptions opt); QT_DEPRECATED bool testOption(QSurfaceFormat::FormatOptions opt) const; +#endif void setOptions(QSurfaceFormat::FormatOptions options); void setOption(FormatOption option, bool on = true); diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index fa99390af0..b9dba10f22 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -416,6 +416,15 @@ void QWindowPrivate::clearFocusObject() { } +// Allows for manipulating the suggested geometry before a resize/move +// event in derived classes for platforms that support it, for example to +// implement heightForWidth(). +QRectF QWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const +{ + Q_UNUSED(rect) + return QRectF(); +} + /*! Sets the \a surfaceType of the window. diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index 40f23b1c36..c496d7716b 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -136,6 +136,7 @@ public: void emitScreenChangedRecursion(QScreen *newScreen); virtual void clearFocusObject(); + virtual QRectF closestAcceptableGeometry(const QRectF &rect) const; bool isPopup() const { return (windowFlags & Qt::WindowType_Mask) == Qt::Popup; } diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index 8ba139d003..30ca7fce66 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -2965,6 +2965,7 @@ void QOpenGLTexture::setData(PixelFormat sourceFormat, PixelType sourceType, d->setData(0, 0, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options); } +#if QT_DEPRECATED_SINCE(5, 3) /*! \obsolete \overload @@ -3022,6 +3023,7 @@ void QOpenGLTexture::setData(PixelFormat sourceFormat, PixelType sourceType, Q_ASSERT(d->textureId); d->setData(0, 0, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options); } +#endif /*! This overload of setData() will allocate storage for you. @@ -3110,6 +3112,7 @@ void QOpenGLTexture::setCompressedData(int dataSize, const void *data, d->setCompressedData(0, 0, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options); } +#if QT_DEPRECATED_SINCE(5, 3) /*! \obsolete \overload @@ -3163,6 +3166,7 @@ void QOpenGLTexture::setCompressedData(int dataSize, void *data, Q_ASSERT(d->textureId); d->setCompressedData(0, 0, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options); } +#endif /*! Returns \c true if your OpenGL implementation and version supports the texture diff --git a/src/gui/opengl/qopengltexture.h b/src/gui/opengl/qopengltexture.h index 0f999a8409..1cf5fdc12a 100644 --- a/src/gui/opengl/qopengltexture.h +++ b/src/gui/opengl/qopengltexture.h @@ -404,6 +404,7 @@ public: // Pixel transfer // ### Qt 6: remove the non-const void * overloads +#if QT_DEPRECATED_SINCE(5, 3) QT_DEPRECATED void setData(int mipLevel, int layer, CubeMapFace cubeFace, PixelFormat sourceFormat, PixelType sourceType, void *data, const QOpenGLPixelTransferOptions * const options = 0); @@ -415,6 +416,7 @@ public: void *data, const QOpenGLPixelTransferOptions * const options = 0); QT_DEPRECATED void setData(PixelFormat sourceFormat, PixelType sourceType, void *data, const QOpenGLPixelTransferOptions * const options = 0); +#endif // QT_DEPRECATED_SINCE(5, 3) void setData(int mipLevel, int layer, CubeMapFace cubeFace, PixelFormat sourceFormat, PixelType sourceType, @@ -430,6 +432,7 @@ public: // Compressed data upload // ### Qt 6: remove the non-const void * overloads +#if QT_DEPRECATED_SINCE(5, 3) QT_DEPRECATED void setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace, int dataSize, void *data, const QOpenGLPixelTransferOptions * const options = 0); @@ -440,6 +443,7 @@ public: const QOpenGLPixelTransferOptions * const options = 0); QT_DEPRECATED void setCompressedData(int dataSize, void *data, const QOpenGLPixelTransferOptions * const options = 0); +#endif // QT_DEPRECATED_SINCE(5, 3) void setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace, int dataSize, const void *data, diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp index a9a2c91fd6..be147ec842 100644 --- a/src/gui/painting/qpaintbuffer.cpp +++ b/src/gui/painting/qpaintbuffer.cpp @@ -39,7 +39,6 @@ #include <private/qimage_p.h> #include <qstatictext.h> #include <private/qstatictext_p.h> -#include <private/qrawfont_p.h> #include <QDebug> @@ -1744,14 +1743,8 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd) painter->setFont(font); - QRawFont rawFont; - QRawFontPrivate *rawFontD = QRawFontPrivate::get(rawFont); - QFontPrivate *fontD = QFontPrivate::get(font); - rawFontD->fontEngine = fontD->engineForScript(QChar::Script_Common); - rawFontD->fontEngine->ref.ref(); - QGlyphRun glyphs; - glyphs.setRawFont(rawFont); + glyphs.setRawFont(QRawFont::fromFont(font, QFontDatabase::Any)); glyphs.setGlyphIndexes(glyphIndexes); glyphs.setPositions(positions); diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index eeebfde98c..b99a32df27 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6358,7 +6358,7 @@ void QPainterPrivate::drawTextItem(const QPointF &p, const QTextItem &_ti, QText return; const QPainter::RenderHints oldRenderHints = state->renderHints; - if (!state->renderHints & QPainter::Antialiasing && state->matrix.type() >= QTransform::TxScale) { + if (!(state->renderHints & QPainter::Antialiasing) && state->matrix.type() >= QTransform::TxScale) { // draw antialias decoration (underline/overline/strikeout) with // transformed text @@ -6428,7 +6428,10 @@ void QPainterPrivate::drawTextItem(const QPointF &p, const QTextItem &_ti, QText if (rtl) x -= ti2.width.toReal(); - engine->drawTextItem(QPointF(x, y), ti2); + if (extended) + extended->drawTextItem(QPointF(x, y), ti2); + else + engine->drawTextItem(QPointF(x, y), ti2); if (!rtl) x += ti2.width.toReal(); diff --git a/src/gui/text/qdistancefield.cpp b/src/gui/text/qdistancefield.cpp index 38215cd418..10fe1a2c84 100644 --- a/src/gui/text/qdistancefield.cpp +++ b/src/gui/text/qdistancefield.cpp @@ -752,7 +752,7 @@ bool qt_fontHasNarrowOutlines(const QRawFont &f) return false; QVector<quint32> glyphIndices = font.glyphIndexesForString(QLatin1String("O")); - if (glyphIndices.size() < 1) + if (glyphIndices.isEmpty() || glyphIndices[0] == 0) return false; return imageHasNarrowOutlines(font.alphaMapForGlyph(glyphIndices.at(0), diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index a0cbd052e4..b867dc6ef2 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -1950,6 +1950,7 @@ static void set_extended_font_bits(quint8 bits, QFontPrivate *f) } #endif +#if QT_DEPRECATED_SINCE(5, 3) /*! \fn QString QFont::rawName() const \deprecated @@ -1986,6 +1987,7 @@ QString QFont::rawName() const void QFont::setRawName(const QString &) { } +#endif /*! Returns the font's key, a textual representation of a font. It is diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index c00d3d18a6..8134e3012b 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -2482,11 +2482,12 @@ bool QFontDatabase::removeAllApplicationFonts() \sa {Thread-Support in Qt Modules#Painting In Threads}{Painting In Threads} */ -// QT_DEPRECATED_SINCE(5, 2) +#if QT_DEPRECATED_SINCE(5, 2) bool QFontDatabase::supportsThreadedFontRendering() { return true; } +#endif /*! \internal diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 4c5bab77d6..ef397e532c 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1345,20 +1345,28 @@ void QFontEngineFT::doKerning(QGlyphLayout *g, QFontEngine::ShaperFlags flags) c QFontEngine::doKerning(g, flags); } +static inline FT_Matrix QTransformToFTMatrix(const QTransform &matrix) +{ + FT_Matrix m; + + m.xx = FT_Fixed(matrix.m11() * 65536); + m.xy = FT_Fixed(-matrix.m21() * 65536); + m.yx = FT_Fixed(-matrix.m12() * 65536); + m.yy = FT_Fixed(matrix.m22() * 65536); + + return m; +} + QFontEngineFT::QGlyphSet *QFontEngineFT::loadTransformedGlyphSet(const QTransform &matrix) { - if (matrix.type() > QTransform::TxShear) + if (matrix.type() > QTransform::TxShear || !cacheEnabled) return 0; // FT_Set_Transform only supports scalable fonts if (!FT_IS_SCALABLE(freetype->face)) return 0; - FT_Matrix m; - m.xx = FT_Fixed(matrix.m11() * 65536); - m.xy = FT_Fixed(-matrix.m21() * 65536); - m.yx = FT_Fixed(-matrix.m12() * 65536); - m.yy = FT_Fixed(matrix.m22() * 65536); + FT_Matrix m = QTransformToFTMatrix(matrix); QGlyphSet *gs = 0; @@ -1377,11 +1385,6 @@ QFontEngineFT::QGlyphSet *QFontEngineFT::loadTransformedGlyphSet(const QTransfor } if (!gs) { - // don't try to load huge fonts - bool draw_as_outline = fontDef.pixelSize * qSqrt(qAbs(matrix.det())) >= QT_MAX_CACHED_GLYPH_SIZE; - if (draw_as_outline) - return 0; - // don't cache more than 10 transformations if (transformedGlyphSets.count() >= 10) { transformedGlyphSets.move(transformedGlyphSets.size() - 1, 0); @@ -1391,8 +1394,9 @@ QFontEngineFT::QGlyphSet *QFontEngineFT::loadTransformedGlyphSet(const QTransfor gs = &transformedGlyphSets[0]; gs->clear(); gs->transformationMatrix = m; - gs->outline_drawing = draw_as_outline; + gs->outline_drawing = fontDef.pixelSize * fontDef.pixelSize * qAbs(matrix.det()) >= QT_MAX_CACHED_GLYPH_SIZE * QT_MAX_CACHED_GLYPH_SIZE; } + Q_ASSERT(gs != 0); return gs; } @@ -1742,76 +1746,21 @@ glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph, const QTransform &matr return alphaMapBoundingBox(glyph, 0, matrix, QFontEngine::Format_None); } -static FT_Matrix QTransformToFTMatrix(const QTransform &matrix) -{ - FT_Matrix m; - - m.xx = FT_Fixed(matrix.m11() * 65536); - m.xy = FT_Fixed(-matrix.m21() * 65536); - m.yx = FT_Fixed(-matrix.m12() * 65536); - m.yy = FT_Fixed(matrix.m22() * 65536); - - return m; -} - glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix, QFontEngine::GlyphFormat format) { - FT_Face face = 0; - glyph_metrics_t overall; - QGlyphSet *glyphSet = 0; - FT_Matrix ftMatrix = QTransformToFTMatrix(matrix); - if (cacheEnabled) { - if (matrix.type() > QTransform::TxTranslate && FT_IS_SCALABLE(freetype->face)) { - // TODO move everything here to a method of its own to access glyphSets - // to be shared with a new method that will replace loadTransformedGlyphSet() - for (int i = 0; i < transformedGlyphSets.count(); ++i) { - const QGlyphSet &g = transformedGlyphSets.at(i); - if (g.transformationMatrix.xx == ftMatrix.xx - && g.transformationMatrix.xy == ftMatrix.xy - && g.transformationMatrix.yx == ftMatrix.yx - && g.transformationMatrix.yy == ftMatrix.yy) { - - // found a match, move it to the front - transformedGlyphSets.move(i, 0); - glyphSet = &transformedGlyphSets[0]; - break; - } - } - - if (!glyphSet) { - // don't cache more than 10 transformations - if (transformedGlyphSets.count() >= 10) { - transformedGlyphSets.move(transformedGlyphSets.size() - 1, 0); - } else { - transformedGlyphSets.prepend(QGlyphSet()); - } - glyphSet = &transformedGlyphSets[0]; - glyphSet->clear(); - glyphSet->transformationMatrix = ftMatrix; - } - Q_ASSERT(glyphSet); - } else { - glyphSet = &defaultGlyphSet; - } - } - Glyph * g = glyphSet ? glyphSet->getGlyph(glyph, subPixelPosition) : 0; - if (!g || g->format != format) { - face = lockFace(); - FT_Matrix m = this->matrix; - FT_Matrix_Multiply(&ftMatrix, &m); - freetype->matrix = m; - g = loadGlyph(glyphSet, glyph, subPixelPosition, format, false); - } + Glyph *g = loadGlyphFor(glyph, subPixelPosition, format, matrix); + glyph_metrics_t overall; if (g) { overall.x = g->x; overall.y = -g->y; overall.width = g->width; overall.height = g->height; overall.xoff = g->advance; - if (!glyphSet && g != &emptyGlyph) + if (!cacheEnabled && g != &emptyGlyph) delete g; } else { + FT_Face face = lockFace(); int left = FLOOR(face->glyph->metrics.horiBearingX); int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width); int top = CEIL(face->glyph->metrics.horiBearingY); @@ -1822,9 +1771,9 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe overall.x = TRUNC(left); overall.y = -TRUNC(top); overall.xoff = TRUNC(ROUND(face->glyph->advance.x)); + if (face) + unlockFace(); } - if (face) - unlockFace(); return overall; } @@ -1949,35 +1898,10 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, QGlyphSet *glyphSet = 0; FT_Matrix ftMatrix = QTransformToFTMatrix(t); if (cacheEnabled) { - if (t.type() > QTransform::TxTranslate && FT_IS_SCALABLE(freetype->face)) { - for (int i = 0; i < transformedGlyphSets.count(); ++i) { - const QGlyphSet &g = transformedGlyphSets.at(i); - if (g.transformationMatrix.xx == ftMatrix.xx - && g.transformationMatrix.xy == ftMatrix.xy - && g.transformationMatrix.yx == ftMatrix.yx - && g.transformationMatrix.yy == ftMatrix.yy) { - - // found a match, move it to the front - transformedGlyphSets.move(i, 0); - glyphSet = &transformedGlyphSets[0]; - break; - } - } - - if (!glyphSet) { - // don't cache more than 10 transformations - if (transformedGlyphSets.count() >= 10) { - transformedGlyphSets.move(transformedGlyphSets.size() - 1, 0); - } else { - transformedGlyphSets.prepend(QGlyphSet()); - } - glyphSet = &transformedGlyphSets[0]; - glyphSet->clear(); - glyphSet->transformationMatrix = ftMatrix; - } - } else { + if (t.type() > QTransform::TxTranslate && FT_IS_SCALABLE(freetype->face)) + glyphSet = loadTransformedGlyphSet(t); + else glyphSet = &defaultGlyphSet; - } Q_ASSERT(glyphSet != 0); } diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index efced94397..a7868f36ab 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -722,14 +722,19 @@ QStaticTextItem::~QStaticTextItem() { if (m_userData != 0 && !m_userData->ref.deref()) delete m_userData; - m_fontEngine->ref.deref(); + setFontEngine(0); } void QStaticTextItem::setFontEngine(QFontEngine *fe) { - if (m_fontEngine != 0) - m_fontEngine->ref.deref(); + if (m_fontEngine == fe) + return; + + if (m_fontEngine != 0 && !m_fontEngine->ref.deref()) + delete m_fontEngine; + m_fontEngine = fe; + if (m_fontEngine != 0) m_fontEngine->ref.ref(); } diff --git a/src/platformsupport/devicediscovery/devicediscovery.pri b/src/platformsupport/devicediscovery/devicediscovery.pri index 9748129225..1ac25da901 100644 --- a/src/platformsupport/devicediscovery/devicediscovery.pri +++ b/src/platformsupport/devicediscovery/devicediscovery.pri @@ -3,14 +3,15 @@ HEADERS += $$PWD/qdevicediscovery_p.h linux { contains(QT_CONFIG, libudev) { SOURCES += $$PWD/qdevicediscovery_udev.cpp + HEADERS += $$PWD/qdevicediscovery_udev_p.h INCLUDEPATH += $$QMAKE_INCDIR_LIBUDEV LIBS_PRIVATE += $$QMAKE_LIBS_LIBUDEV - # Use our own define. QT_NO_LIBUDEV may not be set on non-Linux systems. - DEFINES += QDEVICEDISCOVERY_UDEV } else: contains(QT_CONFIG, evdev) { SOURCES += $$PWD/qdevicediscovery_static.cpp + HEADERS += $$PWD/qdevicediscovery_static_p.h } else { SOURCES += $$PWD/qdevicediscovery_dummy.cpp + HEADERS += $$PWD/qdevicediscovery_dummy_p.h } } else { SOURCES += $$PWD/qdevicediscovery_dummy.cpp diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_dummy.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_dummy.cpp index c6b8610bab..44c5f845dc 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_dummy.cpp +++ b/src/platformsupport/devicediscovery/qdevicediscovery_dummy.cpp @@ -31,34 +31,23 @@ ** ****************************************************************************/ -#include "qdevicediscovery_p.h" +#include "qdevicediscovery_dummy_p.h" QT_BEGIN_NAMESPACE QDeviceDiscovery *QDeviceDiscovery::create(QDeviceTypes types, QObject *parent) { - return new QDeviceDiscovery(types, parent); + return new QDeviceDiscoveryDummy(types, parent); } -QDeviceDiscovery::QDeviceDiscovery(QDeviceTypes types, QObject *parent) - : QObject(parent), - m_types(types) +QDeviceDiscoveryDummy::QDeviceDiscoveryDummy(QDeviceTypes types, QObject *parent) + : QDeviceDiscovery(types, parent) { } -QDeviceDiscovery::~QDeviceDiscovery() -{ -} - -QStringList QDeviceDiscovery::scanConnectedDevices() +QStringList QDeviceDiscoveryDummy::scanConnectedDevices() { return QStringList(); } -bool QDeviceDiscovery::checkDeviceType(const QString &device) -{ - Q_UNUSED(device); - return false; -} - QT_END_NAMESPACE diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_dummy_p.h b/src/platformsupport/devicediscovery/qdevicediscovery_dummy_p.h new file mode 100644 index 0000000000..93a676858d --- /dev/null +++ b/src/platformsupport/devicediscovery/qdevicediscovery_dummy_p.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDEVICEDISCOVERY_DUMMY_H +#define QDEVICEDISCOVERY_DUMMY_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qdevicediscovery_p.h" + +QT_BEGIN_NAMESPACE + +class QDeviceDiscoveryDummy : public QDeviceDiscovery +{ + Q_OBJECT + +public: + QDeviceDiscoveryDummy(QDeviceTypes types, QObject *parent = 0); + QStringList scanConnectedDevices() Q_DECL_OVERRIDE; +}; + +QT_END_NAMESPACE + +#endif // QDEVICEDISCOVERY_DUMMY_H diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_p.h b/src/platformsupport/devicediscovery/qdevicediscovery_p.h index 07e7996a60..f3b0d19a7c 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_p.h +++ b/src/platformsupport/devicediscovery/qdevicediscovery_p.h @@ -49,10 +49,6 @@ #include <QSocketNotifier> #include <QStringList> -#ifdef QDEVICEDISCOVERY_UDEV -#include <libudev.h> -#endif - #define QT_EVDEV_DEVICE_PATH "/dev/input/" #define QT_EVDEV_DEVICE_PREFIX "event" #define QT_EVDEV_DEVICE QT_EVDEV_DEVICE_PATH QT_EVDEV_DEVICE_PREFIX @@ -84,39 +80,18 @@ public: Q_DECLARE_FLAGS(QDeviceTypes, QDeviceType) static QDeviceDiscovery *create(QDeviceTypes type, QObject *parent = 0); - ~QDeviceDiscovery(); - QStringList scanConnectedDevices(); + virtual QStringList scanConnectedDevices() = 0; signals: void deviceDetected(const QString &deviceNode); void deviceRemoved(const QString &deviceNode); -#ifdef QDEVICEDISCOVERY_UDEV -private slots: - void handleUDevNotification(); -#endif - -private: -#ifdef QDEVICEDISCOVERY_UDEV - QDeviceDiscovery(QDeviceTypes types, struct udev *udev, QObject *parent = 0); - bool checkDeviceType(struct udev_device *dev); -#else - QDeviceDiscovery(QDeviceTypes types, QObject *parent = 0); - bool checkDeviceType(const QString &device); -#endif +protected: + QDeviceDiscovery(QDeviceTypes types, QObject *parent) : QObject(parent), m_types(types) { } + Q_DISABLE_COPY(QDeviceDiscovery) QDeviceTypes m_types; - -#ifdef QDEVICEDISCOVERY_UDEV - void startWatching(); - void stopWatching(); - - struct udev *m_udev; - struct udev_monitor *m_udevMonitor; - int m_udevMonitorFileDescriptor; - QSocketNotifier *m_udevSocketNotifier; -#endif }; Q_DECLARE_OPERATORS_FOR_FLAGS(QDeviceDiscovery::QDeviceTypes) diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp index eb7c17d59e..660d3760fb 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp +++ b/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp @@ -31,7 +31,7 @@ ** ****************************************************************************/ -#include "qdevicediscovery_p.h" +#include "qdevicediscovery_static_p.h" #include <QStringList> #include <QCoreApplication> @@ -75,23 +75,18 @@ QT_BEGIN_NAMESPACE QDeviceDiscovery *QDeviceDiscovery::create(QDeviceTypes types, QObject *parent) { - return new QDeviceDiscovery(types, parent); + return new QDeviceDiscoveryStatic(types, parent); } -QDeviceDiscovery::QDeviceDiscovery(QDeviceTypes types, QObject *parent) : - QObject(parent), - m_types(types) +QDeviceDiscoveryStatic::QDeviceDiscoveryStatic(QDeviceTypes types, QObject *parent) + : QDeviceDiscovery(types, parent) { #ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG qWarning() << "New DeviceDiscovery created for type" << types; #endif } -QDeviceDiscovery::~QDeviceDiscovery() -{ -} - -QStringList QDeviceDiscovery::scanConnectedDevices() +QStringList QDeviceDiscoveryStatic::scanConnectedDevices() { QStringList devices; QDir dir; @@ -124,7 +119,7 @@ QStringList QDeviceDiscovery::scanConnectedDevices() return devices; } -bool QDeviceDiscovery::checkDeviceType(const QString &device) +bool QDeviceDiscoveryStatic::checkDeviceType(const QString &device) { bool ret = false; int fd = QT_OPEN(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_static_p.h b/src/platformsupport/devicediscovery/qdevicediscovery_static_p.h new file mode 100644 index 0000000000..6629a9a26c --- /dev/null +++ b/src/platformsupport/devicediscovery/qdevicediscovery_static_p.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDEVICEDISCOVERY_STATIC_H +#define QDEVICEDISCOVERY_STATIC_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qdevicediscovery_p.h" + +QT_BEGIN_NAMESPACE + +class QDeviceDiscoveryStatic : public QDeviceDiscovery +{ + Q_OBJECT + +public: + QDeviceDiscoveryStatic(QDeviceTypes types, QObject *parent = 0); + QStringList scanConnectedDevices() Q_DECL_OVERRIDE; + +private: + bool checkDeviceType(const QString &device); +}; + +QT_END_NAMESPACE + +#endif // QDEVICEDISCOVERY_STATIC_H diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp index 006b18552e..7645dc4544 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp +++ b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp @@ -31,7 +31,7 @@ ** ****************************************************************************/ -#include "qdevicediscovery_p.h" +#include "qdevicediscovery_udev_p.h" #include <QStringList> #include <QCoreApplication> @@ -60,7 +60,7 @@ QDeviceDiscovery *QDeviceDiscovery::create(QDeviceTypes types, QObject *parent) udev = udev_new(); if (udev) { - helper = new QDeviceDiscovery(types, udev, parent); + helper = new QDeviceDiscoveryUDev(types, udev, parent); } else { qWarning("Failed to get udev library context."); } @@ -68,9 +68,9 @@ QDeviceDiscovery *QDeviceDiscovery::create(QDeviceTypes types, QObject *parent) return helper; } -QDeviceDiscovery::QDeviceDiscovery(QDeviceTypes types, struct udev *udev, QObject *parent) : - QObject(parent), - m_types(types), m_udev(udev), m_udevMonitor(0), m_udevMonitorFileDescriptor(-1), m_udevSocketNotifier(0) +QDeviceDiscoveryUDev::QDeviceDiscoveryUDev(QDeviceTypes types, struct udev *udev, QObject *parent) : + QDeviceDiscovery(types, parent), + m_udev(udev), m_udevMonitor(0), m_udevMonitorFileDescriptor(-1), m_udevSocketNotifier(0) { #ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG qWarning() << "New UDeviceHelper created for type" << types; @@ -96,7 +96,7 @@ QDeviceDiscovery::QDeviceDiscovery(QDeviceTypes types, struct udev *udev, QObjec connect(m_udevSocketNotifier, SIGNAL(activated(int)), this, SLOT(handleUDevNotification())); } -QDeviceDiscovery::~QDeviceDiscovery() +QDeviceDiscoveryUDev::~QDeviceDiscoveryUDev() { if (m_udevMonitor) udev_monitor_unref(m_udevMonitor); @@ -105,7 +105,7 @@ QDeviceDiscovery::~QDeviceDiscovery() udev_unref(m_udev); } -QStringList QDeviceDiscovery::scanConnectedDevices() +QStringList QDeviceDiscoveryUDev::scanConnectedDevices() { QStringList devices; @@ -165,7 +165,7 @@ QStringList QDeviceDiscovery::scanConnectedDevices() return devices; } -void QDeviceDiscovery::handleUDevNotification() +void QDeviceDiscoveryUDev::handleUDevNotification() { if (!m_udevMonitor) return; @@ -216,7 +216,7 @@ cleanup: udev_device_unref(dev); } -bool QDeviceDiscovery::checkDeviceType(udev_device *dev) +bool QDeviceDiscoveryUDev::checkDeviceType(udev_device *dev) { if (!dev) return false; diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_udev_p.h b/src/platformsupport/devicediscovery/qdevicediscovery_udev_p.h new file mode 100644 index 0000000000..d31ba72c96 --- /dev/null +++ b/src/platformsupport/devicediscovery/qdevicediscovery_udev_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDEVICEDISCOVERY_UDEV_H +#define QDEVICEDISCOVERY_UDEV_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qdevicediscovery_p.h" +#include <libudev.h> + +QT_BEGIN_NAMESPACE + +class QDeviceDiscoveryUDev : public QDeviceDiscovery +{ + Q_OBJECT + +public: + QDeviceDiscoveryUDev(QDeviceTypes types, struct udev *udev, QObject *parent = 0); + ~QDeviceDiscoveryUDev(); + QStringList scanConnectedDevices() Q_DECL_OVERRIDE; + +private slots: + void handleUDevNotification(); + +private: + bool checkDeviceType(struct udev_device *dev); + + void startWatching(); + void stopWatching(); + + struct udev *m_udev; + struct udev_monitor *m_udevMonitor; + int m_udevMonitorFileDescriptor; + QSocketNotifier *m_udevSocketNotifier; +}; + +QT_END_NAMESPACE + +#endif // QDEVICEDISCOVERY_UDEV_H diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp index 43903acfe1..52505c570b 100644 --- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp @@ -106,6 +106,24 @@ void QBasicFontDatabase::populateFontDatabase() } } +inline static void setHintingPreference(QFontEngine *engine, QFont::HintingPreference hintingPreference) +{ + switch (hintingPreference) { + case QFont::PreferNoHinting: + engine->setDefaultHintStyle(QFontEngineFT::HintNone); + break; + case QFont::PreferFullHinting: + engine->setDefaultHintStyle(QFontEngineFT::HintFull); + break; + case QFont::PreferVerticalHinting: + engine->setDefaultHintStyle(QFontEngineFT::HintLight); + break; + case QFont::PreferDefaultHinting: + // Leave it as it is + break; + } +} + QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, void *usrPtr) { FontFile *fontfile = static_cast<FontFile *> (usrPtr); @@ -120,6 +138,8 @@ QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, void *usrPt if (!engine->init(fid, antialias, format) || engine->invalid()) { delete engine; engine = 0; + } else { + setHintingPreference(engine, static_cast<QFont::HintingPreference>(fontDef.hintingPreference)); } return engine; @@ -172,21 +192,7 @@ QFontEngine *QBasicFontDatabase::fontEngine(const QByteArray &fontData, qreal pi } fe->updateFamilyNameAndStyle(); - - switch (hintingPreference) { - case QFont::PreferNoHinting: - fe->setDefaultHintStyle(QFontEngineFT::HintNone); - break; - case QFont::PreferFullHinting: - fe->setDefaultHintStyle(QFontEngineFT::HintFull); - break; - case QFont::PreferVerticalHinting: - fe->setDefaultHintStyle(QFontEngineFT::HintLight); - break; - default: - // Leave it as it is - break; - } + setHintingPreference(fe, hintingPreference); return fe; } diff --git a/src/plugins/platforms/android/qandroidplatformmenu.cpp b/src/plugins/platforms/android/qandroidplatformmenu.cpp index 8f992f6bea..f8e7df8784 100644 --- a/src/plugins/platforms/android/qandroidplatformmenu.cpp +++ b/src/plugins/platforms/android/qandroidplatformmenu.cpp @@ -53,18 +53,18 @@ QAndroidPlatformMenu::~QAndroidPlatformMenu() void QAndroidPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) { QMutexLocker lock(&m_menuItemsMutex); - m_menuItems.insert(qFind(m_menuItems.begin(), - m_menuItems.end(), - static_cast<QAndroidPlatformMenuItem *>(before)), + m_menuItems.insert(std::find(m_menuItems.begin(), + m_menuItems.end(), + static_cast<QAndroidPlatformMenuItem *>(before)), static_cast<QAndroidPlatformMenuItem *>(menuItem)); } void QAndroidPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem) { QMutexLocker lock(&m_menuItemsMutex); - PlatformMenuItemsType::iterator it = qFind(m_menuItems.begin(), - m_menuItems.end(), - static_cast<QAndroidPlatformMenuItem *>(menuItem)); + PlatformMenuItemsType::iterator it = std::find(m_menuItems.begin(), + m_menuItems.end(), + static_cast<QAndroidPlatformMenuItem *>(menuItem)); if (it != m_menuItems.end()) m_menuItems.erase(it); } diff --git a/src/plugins/platforms/android/qandroidplatformmenubar.cpp b/src/plugins/platforms/android/qandroidplatformmenubar.cpp index 87ebaa8554..2892c3ef3b 100644 --- a/src/plugins/platforms/android/qandroidplatformmenubar.cpp +++ b/src/plugins/platforms/android/qandroidplatformmenubar.cpp @@ -51,18 +51,18 @@ QAndroidPlatformMenuBar::~QAndroidPlatformMenuBar() void QAndroidPlatformMenuBar::insertMenu(QPlatformMenu *menu, QPlatformMenu *before) { QMutexLocker lock(&m_menusListMutex); - m_menus.insert(qFind(m_menus.begin(), - m_menus.end(), - static_cast<QAndroidPlatformMenu *>(before)), - static_cast<QAndroidPlatformMenu *>(menu)); + m_menus.insert(std::find(m_menus.begin(), + m_menus.end(), + static_cast<QAndroidPlatformMenu *>(before)), + static_cast<QAndroidPlatformMenu *>(menu)); } void QAndroidPlatformMenuBar::removeMenu(QPlatformMenu *menu) { QMutexLocker lock(&m_menusListMutex); - m_menus.erase(qFind(m_menus.begin(), - m_menus.end(), - static_cast<QAndroidPlatformMenu *>(menu))); + m_menus.erase(std::find(m_menus.begin(), + m_menus.end(), + static_cast<QAndroidPlatformMenu *>(menu))); } void QAndroidPlatformMenuBar::syncMenu(QPlatformMenu *menu) diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp index b955cff44d..ef7093942c 100644 --- a/src/plugins/platforms/android/qandroidplatformtheme.cpp +++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp @@ -347,6 +347,9 @@ QAndroidPlatformTheme::QAndroidPlatformTheme(QAndroidPlatformNativeInterface *an m_androidStyleData = loadAndroidStyle(&m_defaultPalette); QGuiApplication::setPalette(m_defaultPalette); androidPlatformNativeInterface->m_androidStyle = m_androidStyleData; + + // default in case the style has not set a font + m_systemFont = QFont(QLatin1String("Roboto"), 14.0 * 100 / 72); // keep default size the same after changing from 100 dpi to 72 dpi } QPlatformMenuBar *QAndroidPlatformTheme::createPlatformMenuBar() const @@ -429,10 +432,8 @@ const QFont *QAndroidPlatformTheme::font(Font type) const return &(it.value()); } - // default in case the style has not set a font - static QFont systemFont("Roboto", 14.0 * 100 / 72); // keep default size the same after changing from 100 dpi to 72 dpi if (type == QPlatformTheme::SystemFont) - return &systemFont; + return &m_systemFont; return 0; } diff --git a/src/plugins/platforms/android/qandroidplatformtheme.h b/src/plugins/platforms/android/qandroidplatformtheme.h index 334e86ad7a..e842e672d6 100644 --- a/src/plugins/platforms/android/qandroidplatformtheme.h +++ b/src/plugins/platforms/android/qandroidplatformtheme.h @@ -35,6 +35,7 @@ #define QANDROIDPLATFORMTHEME_H #include <qpa/qplatformtheme.h> +#include <QtGui/qfont.h> #include <QtGui/qpalette.h> #include <QJsonObject> @@ -73,6 +74,7 @@ public: private: std::shared_ptr<AndroidStyle> m_androidStyleData; QPalette m_defaultPalette; + QFont m_systemFont; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/directfb/directfb.pro b/src/plugins/platforms/directfb/directfb.pro index 13481f6198..89d8d42cea 100644 --- a/src/plugins/platforms/directfb/directfb.pro +++ b/src/plugins/platforms/directfb/directfb.pro @@ -29,8 +29,6 @@ HEADERS = qdirectfbintegration.h \ qdirectfbscreen.h \ qdirectfbeglhooks.h -contains(QT_CONFIG, libudev): DEFINES += QDEVICEDISCOVERY_UDEV - # ### port the GL context contains(QT_CONFIG, directfb_egl) { HEADERS += qdirectfb_egl.h diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index d2a9c261ba..b4ff695f1a 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -63,25 +63,27 @@ public: QIOSInputContext(); ~QIOSInputContext(); - QRectF keyboardRect() const; + bool isValid() const Q_DECL_OVERRIDE { return true; } - void showInputPanel(); - void hideInputPanel(); + void showInputPanel() Q_DECL_OVERRIDE; + void hideInputPanel() Q_DECL_OVERRIDE; - void clearCurrentFocusObject(); + bool isInputPanelVisible() const Q_DECL_OVERRIDE; + QRectF keyboardRect() const Q_DECL_OVERRIDE; + + void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE; + void reset() Q_DECL_OVERRIDE; + void commit() Q_DECL_OVERRIDE; - bool isInputPanelVisible() const; - void setFocusObject(QObject *object); + void clearCurrentFocusObject(); + void setFocusObject(QObject *object) Q_DECL_OVERRIDE; void focusWindowChanged(QWindow *focusWindow); void cursorRectangleChanged(); + void scrollToCursor(); void scroll(int y); - void update(Qt::InputMethodQueries); - void reset(); - void commit(); - const ImeState &imeState() { return m_imeState; }; bool inputMethodAccepted() const; diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 65b4f6dd7d..21a05a302e 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -63,6 +63,7 @@ public: void setOpacity(qreal level) Q_DECL_OVERRIDE; bool isExposed() const Q_DECL_OVERRIDE; + void propagateSizeHints() Q_DECL_OVERRIDE {} void raise() { raiseOrLower(true); } void lower() { raiseOrLower(false); } diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index b0c5f15306..480062e4de 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -145,9 +145,10 @@ void QIOSWindow::setVisible(bool visible) bool QIOSWindow::shouldAutoActivateWindow() const { // We don't want to do automatic window activation for popup windows - // (including Tool, ToolTip and SplashScreen windows), unless they - // are standalone (no parent/transient parent), and hence not active. - return !(window()->type() & Qt::Popup) || !window()->isActive(); + // that are unlikely to contain editable controls (to avoid hiding + // the keyboard while the popup is showing) + const Qt::WindowType type = window()->type(); + return (type != Qt::Popup && type != Qt::ToolTip) || !window()->isActive(); } void QIOSWindow::setOpacity(qreal level) diff --git a/src/plugins/platforms/kms/kms.pro b/src/plugins/platforms/kms/kms.pro index 948d986fc5..baa8778153 100644 --- a/src/plugins/platforms/kms/kms.pro +++ b/src/plugins/platforms/kms/kms.pro @@ -9,7 +9,6 @@ QT += core-private gui-private platformsupport-private qtHaveModule(opengl):QT += opengl-private DEFINES += MESA_EGL_NO_X11_HEADERS __GBM__ -contains(QT_CONFIG, libudev): DEFINES += QDEVICEDISCOVERY_UDEV CONFIG += link_pkgconfig egl qpa/genericunixfontdatabase diff --git a/src/plugins/platforms/linuxfb/linuxfb.pro b/src/plugins/platforms/linuxfb/linuxfb.pro index 5e185e357f..389d45c29c 100644 --- a/src/plugins/platforms/linuxfb/linuxfb.pro +++ b/src/plugins/platforms/linuxfb/linuxfb.pro @@ -9,7 +9,6 @@ QT += core-private gui-private platformsupport-private SOURCES = main.cpp qlinuxfbintegration.cpp qlinuxfbscreen.cpp HEADERS = qlinuxfbintegration.h qlinuxfbscreen.h -contains(QT_CONFIG, libudev): DEFINES += QDEVICEDISCOVERY_UDEV CONFIG += qpa/genericunixfontdatabase diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h index 99c97d156f..90e6d6ab9d 100644 --- a/src/plugins/platforms/windows/qtwindowsglobal.h +++ b/src/plugins/platforms/windows/qtwindowsglobal.h @@ -72,7 +72,8 @@ enum WindowsEventType // Simplify event types ShowEventOnParentRestoring = WindowEventFlag + 20, HideEvent = WindowEventFlag + 8, DestroyEvent = WindowEventFlag + 9, - MoveEvent = WindowEventFlag + 10, + GeometryChangingEvent = WindowEventFlag + 10, + MoveEvent = WindowEventFlag + 11, ResizeEvent = WindowEventFlag + 12, QuerySizeHints = WindowEventFlag + 15, CalculateSize = WindowEventFlag + 16, @@ -146,6 +147,10 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI case WM_MOUSEWHEEL: case WM_MOUSEHWHEEL: return QtWindows::MouseWheelEvent; +#ifndef Q_OS_WINCE + case WM_WINDOWPOSCHANGING: + return QtWindows::GeometryChangingEvent; +#endif case WM_MOVE: return QtWindows::MoveEvent; case WM_SHOWWINDOW: diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 22a4dbb09f..4f1a1a375f 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -995,6 +995,8 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, return QWindowsGeometryHint::handleCalculateSize(platformWindow->customMargins(), msg, result); case QtWindows::NonClientHitTest: return platformWindow->handleNonClientHitTest(QPoint(msg.pt.x, msg.pt.y), result); + case QtWindows::GeometryChangingEvent: + return platformWindow->QWindowsWindow::handleGeometryChanging(&msg); #endif // !Q_OS_WINCE case QtWindows::ExposeEvent: return platformWindow->handleWmPaint(hwnd, message, wParam, lParam); diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index 376b1bdc37..6b13d93259 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -289,14 +289,15 @@ QWindowsFontEngine::QWindowsFontEngine(const QString &name, qCDebug(lcQpaFonts) << __FUNCTION__ << name << lf.lfHeight; HDC hdc = m_fontEngineData->hdc; SelectObject(hdc, hfont); - fontDef.pixelSize = -lf.lfHeight; const BOOL res = GetTextMetrics(hdc, &tm); - fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH); if (!res) { qErrnoWarning("%s: GetTextMetrics failed", __FUNCTION__); ZeroMemory(&tm, sizeof(TEXTMETRIC)); } + fontDef.pixelSize = -lf.lfHeight; + fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH); + cache_cost = tm.tmHeight * tm.tmAveCharWidth * 2000; getCMap(); diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index 929c6165d2..94a27d146f 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -145,6 +145,7 @@ static inline void imeNotifyCancelComposition(HWND hwnd) */ +HIMC QWindowsInputContext::m_defaultContext = 0; QWindowsInputContext::CompositionContext::CompositionContext() : hwnd(0), haveCaret(false), position(0), isComposing(false) @@ -163,6 +164,21 @@ QWindowsInputContext::~QWindowsInputContext() { } +bool QWindowsInputContext::hasCapability(Capability capability) const +{ + switch (capability) { + case QPlatformInputContext::HiddenTextCapability: +#ifndef Q_OS_WINCE + return false; // QTBUG-40691, do not show IME on desktop for password entry fields. +#else + break; // Windows CE: Show software keyboard. +#endif + default: + break; + } + return true; +} + /*! \brief Cancels a composition. */ @@ -184,13 +200,33 @@ void QWindowsInputContext::reset() doneContext(); } -void QWindowsInputContext::setFocusObject(QObject *) +void QWindowsInputContext::setFocusObject(QObject *object) { // ### fixme: On Windows 8.1, it has been observed that the Input context // remains active when this happens resulting in a lock-up. Consecutive // key events still have VK_PROCESSKEY set and are thus ignored. if (m_compositionContext.isComposing) imeNotifyCancelComposition(m_compositionContext.hwnd); + + const QWindow *window = QGuiApplication::focusWindow(); + if (object && window) { + QWindowsWindow *platformWindow = QWindowsWindow::baseWindowOf(window); + if (inputMethodAccepted()) { + // Re-enable IME by associating default context saved on first disabling. + if (platformWindow->testFlag(QWindowsWindow::InputMethodDisabled)) { + ImmAssociateContext(platformWindow->handle(), QWindowsInputContext::m_defaultContext); + platformWindow->clearFlag(QWindowsWindow::InputMethodDisabled); + } + } else { + // Disable IME by associating 0 context. Store context first time. + if (!platformWindow->testFlag(QWindowsWindow::InputMethodDisabled)) { + const HIMC oldImC = ImmAssociateContext(platformWindow->handle(), 0); + platformWindow->setFlag(QWindowsWindow::InputMethodDisabled); + if (!QWindowsInputContext::m_defaultContext && oldImC) + QWindowsInputContext::m_defaultContext = oldImC; + } + } + } } /*! diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.h b/src/plugins/platforms/windows/qwindowsinputcontext.h index db1c005207..86243952ec 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.h +++ b/src/plugins/platforms/windows/qwindowsinputcontext.h @@ -62,6 +62,7 @@ public: explicit QWindowsInputContext(); ~QWindowsInputContext(); + bool hasCapability(Capability capability) const Q_DECL_OVERRIDE; void reset() Q_DECL_OVERRIDE; void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE; void invokeAction(QInputMethod::Action, int cursorPosition) Q_DECL_OVERRIDE; @@ -87,6 +88,7 @@ private: void endContextComposition(); const DWORD m_WM_MSIME_MOUSE; + static HIMC m_defaultContext; CompositionContext m_compositionContext; bool m_endCompositionRecursionGuard; }; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 8a80729354..0b4bb9b09d 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1783,6 +1783,43 @@ void QWindowsWindow::propagateSizeHints() qCDebug(lcQpaWindows) << __FUNCTION__ << this << window(); } +bool QWindowsWindow::handleGeometryChanging(MSG *message) const +{ +#ifndef Q_OS_WINCE + QWindow *qWin = window(); + if (!qWin->isTopLevel()) + return false; + WINDOWPOS *windowPos = reinterpret_cast<WINDOWPOS *>(message->lParam); + if ((windowPos->flags & (SWP_NOCOPYBITS | SWP_NOSIZE))) + return false; + const QMargins marginsDp = frameMarginsDp(); + const QRect suggestedFrameGeometryDp(windowPos->x, windowPos->y, + windowPos->cx, windowPos->cy); + const qreal factor = QWindowsScaling::factor(); + const QRect suggestedGeometryDp = suggestedFrameGeometryDp - marginsDp; + const QRectF suggestedGeometry = QRectF(QPointF(suggestedGeometryDp.topLeft()) / factor, + QSizeF(suggestedGeometryDp.size()) / factor); + const QRectF correctedGeometryF = + qt_window_private(qWin)->closestAcceptableGeometry(suggestedGeometry); + if (!correctedGeometryF.isValid()) + return false; + const QRect correctedFrameGeometryDp + = QRectF(correctedGeometryF.topLeft() * factor, + correctedGeometryF.size() * factor).toRect() + + marginsDp; + if (correctedFrameGeometryDp == suggestedFrameGeometryDp) + return false; + windowPos->x = correctedFrameGeometryDp.left(); + windowPos->y = correctedFrameGeometryDp.top(); + windowPos->cx = correctedFrameGeometryDp.width(); + windowPos->cy = correctedFrameGeometryDp.height(); + return true; +#else // !Q_OS_WINCE + Q_UNUSED(message) + return false; +#endif +} + QMargins QWindowsWindow::frameMarginsDp() const { // Frames are invalidated by style changes (window state, flags). diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 71debf2476..a63a9f56e3 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -138,7 +138,8 @@ public: Exposed = 0x10000, WithinCreate = 0x20000, WithinMaximize = 0x40000, - MaximizeToFullScreen = 0x80000 + MaximizeToFullScreen = 0x80000, + InputMethodDisabled =0x100000 }; QWindowsWindow(QWindow *window, const QWindowsWindowData &data); @@ -182,6 +183,7 @@ public: void windowEvent(QEvent *event); void propagateSizeHints() Q_DECL_OVERRIDE; + bool handleGeometryChanging(MSG *message) const; QMargins frameMarginsDp() const; QMargins frameMargins() const Q_DECL_OVERRIDE { return frameMarginsDp() / QWindowsScaling::factor(); } diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 85af8ee1d2..e1ccc3f086 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2022,6 +2022,19 @@ void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, con QWindowSystemInterface::handleMouseEvent(window(), time, local, global, connection()->buttons(), modifiers); } +static bool ignoreLeaveEvent(const xcb_leave_notify_event_t *event) +{ + return event->detail == XCB_NOTIFY_DETAIL_VIRTUAL + || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL; +} + +static bool ignoreEnterEvent(const xcb_enter_notify_event_t *event) +{ + return ((event->mode != XCB_NOTIFY_MODE_NORMAL && event->mode != XCB_NOTIFY_MODE_UNGRAB) + || event->detail == XCB_NOTIFY_DETAIL_VIRTUAL + || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL); +} + class EnterEventChecker { public: @@ -2033,13 +2046,8 @@ public: return false; xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)event; - - if ((enter->mode != XCB_NOTIFY_MODE_NORMAL && enter->mode != XCB_NOTIFY_MODE_UNGRAB) - || enter->detail == XCB_NOTIFY_DETAIL_VIRTUAL - || enter->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL) - { + if (ignoreEnterEvent(enter)) return false; - } return true; } @@ -2052,12 +2060,9 @@ void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event) connection()->handleEnterEvent(event); #endif - if ((event->mode != XCB_NOTIFY_MODE_NORMAL && event->mode != XCB_NOTIFY_MODE_UNGRAB) - || event->detail == XCB_NOTIFY_DETAIL_VIRTUAL - || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL) - { + if (ignoreEnterEvent(event)) return; - } + const int dpr = int(devicePixelRatio()); const QPoint local(event->event_x/dpr, event->event_y/dpr); const QPoint global(event->root_x/dpr, event->root_y/dpr); @@ -2068,12 +2073,8 @@ void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event) { connection()->setTime(event->time); - if ((event->mode != XCB_NOTIFY_MODE_NORMAL && event->mode != XCB_NOTIFY_MODE_UNGRAB) - || event->detail == XCB_NOTIFY_DETAIL_VIRTUAL - || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL) - { + if (ignoreLeaveEvent(event)) return; - } EnterEventChecker checker; xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)connection()->checkEvent(checker); diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp index cbde2bfa9c..84b6bbe80e 100644 --- a/src/sql/drivers/sqlite/qsql_sqlite.cpp +++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp @@ -98,7 +98,7 @@ static QSqlError qMakeError(sqlite3 *access, const QString &descr, QSqlError::Er { return QSqlError(descr, QString(reinterpret_cast<const QChar *>(sqlite3_errmsg16(access))), - type, errorCode); + type, QString::number(errorCode)); } class QSQLiteResultPrivate; diff --git a/src/src.pro b/src/src.pro index ab93641131..81f4fa5256 100644 --- a/src/src.pro +++ b/src/src.pro @@ -16,6 +16,7 @@ src_tools_rcc.CONFIG = host_build src_tools_qlalr.subdir = tools/qlalr src_tools_qlalr.target = sub-qlalr +src_tools_qlalr.CONFIG = host_build force_bootstrap: src_tools_qlalr.depends = src_tools_bootstrap else: src_tools_qlalr.depends = src_corelib diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp index c9af3062d3..f0aceaacf7 100644 --- a/src/widgets/kernel/qgesturemanager.cpp +++ b/src/widgets/kernel/qgesturemanager.cpp @@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE +#if !defined(Q_OS_OSX) static inline int panTouchPoints() { // Override by environment variable for testing. @@ -80,6 +81,7 @@ static inline int panTouchPoints() // correctly. return 2; } +#endif QGestureManager::QGestureManager(QObject *parent) : QObject(parent), state(NotGesture), m_lastCustomGestureId(Qt::CustomGesture) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index ed59e40bb6..143293b589 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -9406,9 +9406,11 @@ void QWidget::focusOutEvent(QFocusEvent *) if (focusPolicy() != Qt::NoFocus || !isWindow()) update(); - // automatically hide the SIP +#ifndef Q_OS_IOS + // FIXME: revisit autoSIP logic, QTBUG-42906 if (qApp->autoSipEnabled() && testAttribute(Qt::WA_InputMethodEnabled)) qApp->inputMethod()->hide(); +#endif } /*! diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index de8f11e5ec..4bca0eab4a 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -33,6 +33,7 @@ #include "private/qwindow_p.h" #include "qwidgetwindow_p.h" +#include "qlayout.h" #include "private/qwidget_p.h" #include "private/qapplication_p.h" @@ -79,8 +80,38 @@ public: widget->focusWidget()->clearFocus(); } + QRectF closestAcceptableGeometry(const QRectF &rect) const Q_DECL_OVERRIDE; }; +QRectF QWidgetWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const +{ + Q_Q(const QWidgetWindow); + const QWidget *widget = q->widget(); + if (!widget->isWindow() || !widget->hasHeightForWidth()) + return QRect(); + const QSize oldSize = rect.size().toSize(); + const QSize newSize = QLayout::closestAcceptableSize(widget, oldSize); + if (newSize == oldSize) + return QRectF(); + const int dw = newSize.width() - oldSize.width(); + const int dh = newSize.height() - oldSize.height(); + QRectF result = rect; + const QRectF currentGeometry(widget->geometry()); + const qreal topOffset = result.top() - currentGeometry.top(); + const qreal bottomOffset = result.bottom() - currentGeometry.bottom(); + if (qAbs(topOffset) > qAbs(bottomOffset)) + result.setTop(result.top() - dh); // top edge drag + else + result.setBottom(result.bottom() + dh); // bottom edge drag + const qreal leftOffset = result.left() - currentGeometry.left(); + const qreal rightOffset = result.right() - currentGeometry.right(); + if (qAbs(leftOffset) > qAbs(rightOffset)) + result.setLeft(result.left() - dw); // left edge drag + else + result.setRight(result.right() + dw); // right edge drag + return result; +} + QWidgetWindow::QWidgetWindow(QWidget *widget) : QWindow(*new QWidgetWindowPrivate(), 0) , m_widget(widget) diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index 817f16b297..c4f78b9998 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -1403,7 +1403,9 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio painter->drawRoundedRect(progressBar.adjusted(1, 1, -1, -1), 1, 1); if (!indeterminate) { +#ifndef QT_NO_ANIMATION (const_cast<QFusionStylePrivate*>(d))->stopAnimation(option->styleObject); +#endif } else { highlightedGradientStartColor.setAlpha(120); painter->setPen(QPen(highlightedGradientStartColor, 9.0)); @@ -2431,6 +2433,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption styleObject->setProperty("_q_stylestate", static_cast<int>(scrollBar->state)); styleObject->setProperty("_q_stylecontrols", static_cast<uint>(scrollBar->activeSubControls)); +#ifndef QT_NO_ANIMATION QScrollbarStyleAnimation *anim = qobject_cast<QScrollbarStyleAnimation *>(d->animation(styleObject)); if (transient) { if (!anim) { @@ -2444,8 +2447,10 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption } else if (anim && anim->mode() == QScrollbarStyleAnimation::Deactivating) { d->stopAnimation(styleObject); } +#endif // !QT_NO_ANIMATION } +#ifndef QT_NO_ANIMATION QScrollbarStyleAnimation *anim = qobject_cast<QScrollbarStyleAnimation *>(d->animation(styleObject)); if (anim && anim->mode() == QScrollbarStyleAnimation::Deactivating) { // once a scrollbar was active (hovered/pressed), it retains @@ -2474,6 +2479,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption } } painter->setOpacity(opacity); +#endif // !QT_NO_ANIMATION } bool transient = proxy()->styleHint(SH_ScrollBar_Transient, option, widget); diff --git a/src/widgets/styles/qgtkstyle.cpp b/src/widgets/styles/qgtkstyle.cpp index 6f2a2046b7..f87af6cd93 100644 --- a/src/widgets/styles/qgtkstyle.cpp +++ b/src/widgets/styles/qgtkstyle.cpp @@ -1049,7 +1049,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, // The reason for this is that a lot of code that relies on custom item delegates will look odd having // a gradient on the branch but a flat shaded color on the item itself. QCommonStyle::drawPrimitive(element, option, painter, widget); - if (!option->state & State_Selected) { + if (!(option->state & State_Selected)) { break; } else { if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView*>(widget)) { @@ -3514,15 +3514,19 @@ void QGtkStyle::drawControl(ControlElement element, progressBar.setRect(rect.left(), rect.top(), width, rect.height()); else progressBar.setRect(rect.right() - width, rect.top(), width, rect.height()); +#ifndef QT_NO_ANIMATION d->stopAnimation(option->styleObject); +#endif } else { Q_D(const QGtkStyle); int slideWidth = ((rect.width() - 4) * 2) / 3; int step = 0; +#ifndef QT_NO_ANIMATION if (QProgressStyleAnimation *animation = qobject_cast<QProgressStyleAnimation*>(d->animation(option->styleObject))) step = animation->progressStep(slideWidth); else d->startAnimation(new QProgressStyleAnimation(d->animationFps, option->styleObject)); +#endif progressBar.setRect(rect.left() + step, rect.top(), slideWidth / 2, rect.height()); } diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 3db7781acc..5a504a880c 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -712,8 +712,11 @@ QSize QLineEdit::minimumSizeHint() const ensurePolished(); QFontMetrics fm = fontMetrics(); int h = fm.height() + qMax(2*d->verticalMargin, fm.leading()) + + d->topTextMargin + d->bottomTextMargin + d->topmargin + d->bottommargin; - int w = fm.maxWidth() + d->leftmargin + d->rightmargin; + int w = fm.maxWidth() + + d->effectiveLeftTextMargin() + d->effectiveRightTextMargin() + + d->leftmargin + d->rightmargin; QStyleOptionFrame opt; initStyleOption(&opt); return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w, h). diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index 982cc40b3d..871bf1eba1 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -2480,6 +2480,7 @@ void CloseButton::paintEvent(QPaintEvent *) style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &p, this); } +#ifndef QT_NO_ANIMATION void QTabBarPrivate::Tab::TabBarAnimation::updateCurrentValue(const QVariant ¤t) { priv->moveTab(priv->tabList.indexOf(*tab), current.toInt()); @@ -2489,6 +2490,7 @@ void QTabBarPrivate::Tab::TabBarAnimation::updateState(QAbstractAnimation::State { if (newState == Stopped) priv->moveTabFinished(priv->tabList.indexOf(*tab)); } +#endif QT_END_NAMESPACE diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 44d7671ca3..756b22073e 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -206,7 +206,6 @@ private slots: void enabledPropagation(); void ignoreKeyEventsWhenDisabled_QTBUG27417(); void properTabHandlingWhenDisabled_QTBUG27417(); - void popupEnterLeave(); #ifndef QT_NO_DRAGANDDROP void acceptDropsPropagation(); #endif @@ -5001,51 +5000,6 @@ bool verifyColor(QWidget &child, const QRegion ®ion, const QColor &color, uns return true; } -void tst_QWidget::popupEnterLeave() -{ - QWidget parent; - parent.setWindowFlags(Qt::FramelessWindowHint); - parent.setGeometry(10, 10, 200, 100); - - ColorWidget alien(&parent, Qt::Widget, Qt::black); - alien.setGeometry(0, 0, 10, 10); - alien.show(); - - parent.show(); - - QVERIFY(QTest::qWaitForWindowExposed(&parent)); - - QWindowSystemInterface::handleMouseEvent(parent.windowHandle(), QPointF(5, 5), QPointF(), Qt::LeftButton, Qt::NoModifier); - QTest::qWait(100); - QWindowSystemInterface::handleMouseEvent(parent.windowHandle(), QPointF(5, 5), QPointF(), Qt::NoButton, Qt::NoModifier); - QTest::qWait(100); - - QStringList wordList; - wordList << "alpha" << "omega" << "omicron" << "zeta"; - - QLineEdit popup(&parent); - - QCompleter completer(wordList); - completer.setCaseSensitivity(Qt::CaseInsensitive); - popup.setCompleter(&completer); - popup.setWindowFlags(Qt::Popup); - popup.setGeometry(20, 20, 80, 20); - - popup.show(); - - QVERIFY(QTest::qWaitForWindowExposed(&popup)); - - QTest::qWait(100); - - QWindowSystemInterface::handleMouseEvent(popup.windowHandle(), QPointF(-5, -5), QPointF(), Qt::LeftButton, Qt::NoModifier); - QTest::qWait(100); - QWindowSystemInterface::handleMouseEvent(popup.windowHandle(), QPointF(-5, -5), QPointF(), Qt::NoButton, Qt::NoModifier); - QTest::qWait(100); - - QTest::qWait(1000); - QVERIFY(!popup.underMouse()); -} - void tst_QWidget::moveChild_data() { QTest::addColumn<QPoint>("offset"); diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index 78fa0b4928..bf4d1f2ebd 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -3384,10 +3384,20 @@ void tst_QLineEdit::textMargin() testWidget.setCursorPosition(6); QSize sizeHint = testWidget.sizeHint(); + QSize minSizeHint = testWidget.minimumSizeHint(); testWidget.setTextMargins(left, top, right, bottom); + sizeHint.setWidth(sizeHint.width() + left + right); sizeHint.setHeight(sizeHint.height() + top +bottom); QCOMPARE(testWidget.sizeHint(), sizeHint); + + if (minSizeHint.width() > -1) { + minSizeHint.setWidth(minSizeHint.width() + left + right); + minSizeHint.setHeight(minSizeHint.height() + top + bottom); + QCOMPARE(testWidget.minimumSizeHint(), minSizeHint); + } + + testWidget.setFrame(false); centerOnScreen(&tlw); tlw.show(); diff --git a/tests/manual/diaglib/diaglib.pri b/tests/manual/diaglib/diaglib.pri index 138660f85e..05ecaf1444 100644 --- a/tests/manual/diaglib/diaglib.pri +++ b/tests/manual/diaglib/diaglib.pri @@ -26,7 +26,7 @@ greaterThan(QT_MAJOR_VERSION, 4) { } } else { HEADERS += \ - $$PWD/$$PWD/qwidgetdump.h + $$PWD/qwidgetdump.h SOURCES += \ $$PWD/qwidgetdump.cpp diff --git a/tests/manual/diaglib/eventfilter.cpp b/tests/manual/diaglib/eventfilter.cpp index f0573975f6..4968780e82 100644 --- a/tests/manual/diaglib/eventfilter.cpp +++ b/tests/manual/diaglib/eventfilter.cpp @@ -52,6 +52,8 @@ EventFilter::EventFilter(QObject *p) void EventFilter::init(EventCategories eventCategories) { + m_objectTypes = OtherType | QWidgetType | QWindowType; + if (eventCategories & MouseEvents) { m_eventTypes << QEvent::MouseButtonPress << QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick << QEvent::NonClientAreaMouseButtonPress @@ -79,6 +81,13 @@ void EventFilter::init(EventCategories eventCategories) m_eventTypes << QEvent::KeyPress << QEvent::KeyRelease << QEvent::ShortcutOverride << QEvent::Shortcut; } + if (eventCategories & FocusEvents) { + m_eventTypes +#if QT_VERSION >= 0x050000 + << QEvent::FocusAboutToChange +#endif + << QEvent::FocusIn << QEvent::FocusOut; + } if (eventCategories & GeometryEvents) m_eventTypes << QEvent::Move << QEvent::Resize; if (eventCategories & PaintEvents) { @@ -88,18 +97,44 @@ void EventFilter::init(EventCategories eventCategories) m_eventTypes << QEvent::Expose; #endif } + if (eventCategories & StateChangeEvents) { + m_eventTypes + << QEvent::WindowStateChange + << QEvent::WindowBlocked << QEvent::WindowUnblocked +#if QT_VERSION >= 0x050000 + << QEvent::ApplicationStateChange +#endif + << QEvent::ApplicationActivate << QEvent::ApplicationDeactivate; + } if (eventCategories & TimerEvents) m_eventTypes << QEvent::Timer << QEvent::ZeroTimerEvent; if (eventCategories & ObjectEvents) { m_eventTypes << QEvent::ChildAdded << QEvent::ChildPolished << QEvent::ChildRemoved << QEvent::Create << QEvent::Destroy; } + if (eventCategories & InputMethodEvents) { + m_eventTypes << QEvent::InputMethod; +#if QT_VERSION >= 0x050000 + m_eventTypes << QEvent::InputMethodQuery; +#endif + } +} + +static inline bool matchesType(const QObject *o, EventFilter::ObjectTypes types) +{ + if (o->isWidgetType()) + return types & EventFilter::QWidgetType; +#if QT_VERSION >= 0x050000 + if (o->isWindowType()) + return types & EventFilter::QWindowType; +#endif + return types & EventFilter::OtherType; } bool EventFilter::eventFilter(QObject *o, QEvent *e) { static int n = 0; - if (m_eventTypes.contains(e->type())) { + if (matchesType(o, m_objectTypes) && m_eventTypes.contains(e->type())) { QDebug debug = qDebug().nospace(); const QString on = o->objectName(); debug << '#' << n++ << ' ' << o->metaObject()->className(); diff --git a/tests/manual/diaglib/eventfilter.h b/tests/manual/diaglib/eventfilter.h index d87ac68b07..8d94c1308a 100644 --- a/tests/manual/diaglib/eventfilter.h +++ b/tests/manual/diaglib/eventfilter.h @@ -52,25 +52,41 @@ public: TabletEvents = 0x00008, DragAndDropEvents = 0x00010, KeyEvents = 0x00020, - GeometryEvents = 0x00040, - PaintEvents = 0x00080, - TimerEvents = 0x00100, - ObjectEvents = 0x00200 + FocusEvents = 0x00040, + GeometryEvents = 0x00080, + PaintEvents = 0x00100, + StateChangeEvents = 0x00200, + InputMethodEvents = 0x00400, + TimerEvents = 0x00800, + ObjectEvents = 0x01000, + AllEvents = 0xFFFFF }; Q_DECLARE_FLAGS(EventCategories, EventCategory) + enum ObjectType { + QWindowType = 0x1, + QWidgetType = 0x2, + OtherType = 0x4 + }; + Q_DECLARE_FLAGS(ObjectTypes, ObjectType) + explicit EventFilter(EventCategories eventCategories, QObject *p = 0); explicit EventFilter(QObject *p = 0); bool eventFilter(QObject *, QEvent *); + ObjectTypes objectTypes() const { return m_objectTypes; } + void setObjectTypes(ObjectTypes objectTypes) { m_objectTypes = objectTypes; } + private: void init(EventCategories eventCategories); QList<QEvent::Type> m_eventTypes; + ObjectTypes m_objectTypes; }; Q_DECLARE_OPERATORS_FOR_FLAGS(EventFilter::EventCategories) +Q_DECLARE_OPERATORS_FOR_FLAGS(EventFilter::ObjectTypes) } // namespace QtDiag diff --git a/tests/manual/diaglib/glinfo.cpp b/tests/manual/diaglib/glinfo.cpp index cd30e46b45..a7eff208de 100644 --- a/tests/manual/diaglib/glinfo.cpp +++ b/tests/manual/diaglib/glinfo.cpp @@ -102,7 +102,7 @@ static QString getGlString(GLenum name) return QString(); } -QString glInfo(const QWidget *) +QString glInfo(const QObject *) { return getGlString(GL_VENDOR) + QLatin1Char('\n') + getGlString(GL_RENDERER); } |