diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-10-20 01:02:53 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-10-20 01:02:53 +0200 |
commit | f06cbeb00b00e54826a67816663920cb468141a2 (patch) | |
tree | 9d073663750cfaf11ace6488f880be093b40b2bd /src | |
parent | eef179c9eb2c2d24e67c27742618555267e45e89 (diff) | |
parent | 6734ee9a6ddb6a3870556514a70d904836258559 (diff) |
Merge remote-tracking branch 'origin/5.12' into dev
Change-Id: I939b8ddc8b24e9c9853a72eb22da317023c7a2c4
Diffstat (limited to 'src')
-rw-r--r-- | src/imports/folderlistmodel/fileinfothread.cpp | 1 | ||||
-rw-r--r-- | src/imports/folderlistmodel/plugin.cpp | 3 | ||||
-rw-r--r-- | src/imports/folderlistmodel/qquickfolderlistmodel.cpp | 60 | ||||
-rw-r--r-- | src/imports/folderlistmodel/qquickfolderlistmodel.h | 5 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 2 | ||||
-rw-r--r-- | src/qml/configure.json | 1 | ||||
-rw-r--r-- | src/qml/parser/qqmljs.g | 25 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 97 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader_p.h | 1 | ||||
-rw-r--r-- | src/qml/types/qqmlinstantiator_p.h | 3 | ||||
-rw-r--r-- | src/qml/types/qqmlinstantiator_p_p.h | 5 | ||||
-rw-r--r-- | src/qml/util/qqmladaptormodel.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickborderimage.cpp | 26 | ||||
-rw-r--r-- | src/quick/items/qquickitemview.cpp | 1 | ||||
-rw-r--r-- | src/quick/items/qquicklistview.cpp | 38 | ||||
-rw-r--r-- | src/quick/items/qquicktableview.cpp | 10 | ||||
-rw-r--r-- | src/quick/items/qquicktableview_p_p.h | 1 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 26 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgbasicinternalimagenode.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp | 25 |
20 files changed, 222 insertions, 112 deletions
diff --git a/src/imports/folderlistmodel/fileinfothread.cpp b/src/imports/folderlistmodel/fileinfothread.cpp index 5b44ed012f..a006f659c9 100644 --- a/src/imports/folderlistmodel/fileinfothread.cpp +++ b/src/imports/folderlistmodel/fileinfothread.cpp @@ -135,6 +135,7 @@ void FileInfoThread::setSortFlags(QDir::SortFlags flags) QMutexLocker locker(&mutex); sortFlags = flags; sortUpdate = true; + needUpdate = true; condition.wakeAll(); } diff --git a/src/imports/folderlistmodel/plugin.cpp b/src/imports/folderlistmodel/plugin.cpp index 7089fed4ad..31cd793737 100644 --- a/src/imports/folderlistmodel/plugin.cpp +++ b/src/imports/folderlistmodel/plugin.cpp @@ -65,6 +65,9 @@ public: // revision in Qt 5.11: added status property qmlRegisterType<QQuickFolderListModel,11>(uri, 2, 11, "FolderListModel"); + + // revision in Qt 5.12: added sortCaseSensitive property + qmlRegisterType<QQuickFolderListModel,12>(uri, 2, 12, "FolderListModel"); } }; //![class decl] diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp index 66d9e7ae46..affb1e9fe2 100644 --- a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp +++ b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp @@ -51,15 +51,7 @@ class QQuickFolderListModelPrivate Q_DECLARE_PUBLIC(QQuickFolderListModel) public: - QQuickFolderListModelPrivate(QQuickFolderListModel *q) - : q_ptr(q), - sortField(QQuickFolderListModel::Name), sortReversed(false), showFiles(true), - showDirs(true), showDirsFirst(false), showDotAndDotDot(false), showOnlyReadable(false), - showHidden(false), caseSensitive(true), status(QQuickFolderListModel::Null) - { - nameFilters << QLatin1String("*"); - } - + QQuickFolderListModelPrivate(QQuickFolderListModel *q) : q_ptr(q) { } QQuickFolderListModel *q_ptr; QUrl currentDir; @@ -67,17 +59,18 @@ public: FileInfoThread fileInfoThread; QList<FileProperty> data; QHash<int, QByteArray> roleNames; - QQuickFolderListModel::SortField sortField; - QStringList nameFilters; - bool sortReversed; - bool showFiles; - bool showDirs; - bool showDirsFirst; - bool showDotAndDotDot; - bool showOnlyReadable; - bool showHidden; - bool caseSensitive; - QQuickFolderListModel::Status status; + QQuickFolderListModel::SortField sortField = QQuickFolderListModel::Name; + QStringList nameFilters = { QLatin1String("*") }; + QQuickFolderListModel::Status status = QQuickFolderListModel::Null; + bool sortReversed = false; + bool showFiles = true; + bool showDirs = true; + bool showDirsFirst = false; + bool showDotAndDotDot = false; + bool showOnlyReadable = false; + bool showHidden = false; + bool caseSensitive = true; + bool sortCaseSensitive = true; ~QQuickFolderListModelPrivate() {} void init(); @@ -132,14 +125,14 @@ void QQuickFolderListModelPrivate::updateSorting() case QQuickFolderListModel::Type: flags |= QDir::Type; break; - default: - break; } emit q->layoutAboutToBeChanged(); if (sortReversed) flags |= QDir::Reversed; + if (!sortCaseSensitive) + flags |= QDir::IgnoreCase; fileInfoThread.setSortFlags(flags); } @@ -856,6 +849,29 @@ QQuickFolderListModel::Status QQuickFolderListModel::status() const } /*! + \qmlproperty bool FolderListModel::sortCaseSensitive + \since 5.12 + + If set to true, the sort is case sensitive. This property is true by default. +*/ + +bool QQuickFolderListModel::sortCaseSensitive() const +{ + Q_D(const QQuickFolderListModel); + return d->sortCaseSensitive; +} + +void QQuickFolderListModel::setSortCaseSensitive(bool on) +{ + Q_D(QQuickFolderListModel); + + if (on != d->sortCaseSensitive) { + d->sortCaseSensitive = on; + d->updateSorting(); + } +} + +/*! \qmlmethod var FolderListModel::get(int index, string property) Get the folder property for the given index. The following properties diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.h b/src/imports/folderlistmodel/qquickfolderlistmodel.h index a449f0dd0f..d93e7daf3f 100644 --- a/src/imports/folderlistmodel/qquickfolderlistmodel.h +++ b/src/imports/folderlistmodel/qquickfolderlistmodel.h @@ -76,11 +76,12 @@ class QQuickFolderListModel : public QAbstractListModel, public QQmlParserStatus Q_PROPERTY(bool caseSensitive READ caseSensitive WRITE setCaseSensitive REVISION 2) Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(Status status READ status NOTIFY statusChanged REVISION 11) + Q_PROPERTY(bool sortCaseSensitive READ sortCaseSensitive WRITE setSortCaseSensitive REVISION 12) //![class props] //![abslistmodel] public: - QQuickFolderListModel(QObject *parent = 0); + QQuickFolderListModel(QObject *parent = nullptr); ~QQuickFolderListModel(); enum Roles { @@ -142,6 +143,8 @@ public: enum Status { Null, Ready, Loading }; Q_ENUM(Status) Status status() const; + bool sortCaseSensitive() const; + void setSortCaseSensitive(bool on); //![prop funcs] Q_INVOKABLE bool isFolder(int index) const; diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index c2ece459c8..b36b1a91ea 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -1176,6 +1176,8 @@ public: FunctionIterator objectFunctionsEnd(const Object *object) const { return FunctionIterator(data, object, object->nFunctions); } // --- + bool isESModule() const { return data->flags & Unit::IsESModule; } + bool isSharedLibrary() const { return data->flags & Unit::IsSharedLibrary; } QStringList moduleRequests() const; Heap::Module *instantiate(ExecutionEngine *engine); const Value *resolveExport(QV4::String *exportName); diff --git a/src/qml/configure.json b/src/qml/configure.json index 9e44a4987d..50fdf56048 100644 --- a/src/qml/configure.json +++ b/src/qml/configure.json @@ -52,6 +52,7 @@ "section": "QML", "condition": [ "features.commandlineparser", + "features.filesystemwatcher", "features.qml-network && features.localserver", "features.process", "features.qml-debug" diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g index a844e3cb3e..a7ae664d72 100644 --- a/src/qml/parser/qqmljs.g +++ b/src/qml/parser/qqmljs.g @@ -550,6 +550,8 @@ AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr) void Parser::pushToken(int token) { + Q_ASSERT(last_token); + Q_ASSERT(last_token < &token_buffer[TOKEN_BUFFER_SIZE]); last_token->token = yytoken; last_token->dval = yylval; last_token->spell = yytokenspell; @@ -4386,6 +4388,9 @@ ExportSpecifier: IdentifierName T_AS IdentifierName; token_buffer[1].loc = yylloc = location(lexer); if (t_action(errorState, yytoken)) { +#ifdef PARSER_DEBUG + qDebug() << "Parse error, trying to recover."; +#endif QString msg; int token = token_buffer[0].token; if (token < 0 || token >= TERMINAL_COUNT) @@ -4419,18 +4424,13 @@ ExportSpecifier: IdentifierName T_AS IdentifierName; for (int *tk = tokens; *tk != EOF_SYMBOL; ++tk) { int a = t_action(errorState, *tk); if (a > 0 && t_action(a, yytoken)) { +#ifdef PARSER_DEBUG + qDebug() << "Parse error, trying to recover (2)."; +#endif const QString msg = QCoreApplication::translate("QQmlParser", "Expected token `%1'").arg(QLatin1String(spell[*tk])); diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg)); - yytoken = *tk; - yylval = 0; - yylloc = token_buffer[0].loc; - yylloc.length = 0; - - first_token = &token_buffer[0]; - last_token = &token_buffer[2]; - - action = errorState; + pushToken(*tk); goto _Lcheck_token; } } @@ -4445,12 +4445,7 @@ ExportSpecifier: IdentifierName T_AS IdentifierName; const QString msg = QCoreApplication::translate("QQmlParser", "Expected token `%1'").arg(QLatin1String(spell[tk])); diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg)); - yytoken = tk; - yylval = 0; - yylloc = token_buffer[0].loc; - yylloc.length = 0; - - action = errorState; + pushToken(tk); goto _Lcheck_token; } } diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 0b0c6242ba..0047b20346 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2905,6 +2905,55 @@ void QQmlScriptData::initialize(QQmlEngine *engine) addref(); } +QQmlContextData *QQmlScriptData::qmlContextDataForContext(QQmlContextData *parentQmlContextData) +{ + Q_ASSERT(parentQmlContextData && parentQmlContextData->engine); + + if (m_precompiledScript->isESModule()) + return nullptr; + + auto qmlContextData = new QQmlContextData(); + + qmlContextData->isInternal = true; + qmlContextData->isJSContext = true; + if (m_precompiledScript->isSharedLibrary()) + qmlContextData->isPragmaLibraryContext = true; + else + qmlContextData->isPragmaLibraryContext = parentQmlContextData->isPragmaLibraryContext; + qmlContextData->baseUrl = url; + qmlContextData->baseUrlString = urlString; + + // For backward compatibility, if there are no imports, we need to use the + // imports from the parent context. See QTBUG-17518. + if (!typeNameCache->isEmpty()) { + qmlContextData->imports = typeNameCache; + } else if (!m_precompiledScript->isSharedLibrary()) { + qmlContextData->imports = parentQmlContextData->imports; + qmlContextData->importedScripts = parentQmlContextData->importedScripts; + } + + if (!m_precompiledScript->isSharedLibrary()) { + qmlContextData->setParent(parentQmlContextData); + } else { + qmlContextData->engine = parentQmlContextData->engine; // Fix for QTBUG-21620 + } + + QV4::ExecutionEngine *v4 = parentQmlContextData->engine->handle(); + QV4::Scope scope(v4); + QV4::ScopedObject scriptsArray(scope); + if (qmlContextData->importedScripts.isNullOrUndefined()) { + scriptsArray = v4->newArrayObject(scripts.count()); + qmlContextData->importedScripts.set(v4, scriptsArray); + } else { + scriptsArray = qmlContextData->importedScripts.valueRef(); + } + QV4::ScopedValue v(scope); + for (int ii = 0; ii < scripts.count(); ++ii) + scriptsArray->put(ii, (v = scripts.at(ii)->scriptData()->scriptValueForContext(qmlContextData))); + + return qmlContextData; +} + QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parentCtxt) { if (m_loaded) @@ -2913,7 +2962,7 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent Q_ASSERT(parentCtxt && parentCtxt->engine); QV4::ExecutionEngine *v4 = parentCtxt->engine->handle(); - if (m_precompiledScript->unitData()->flags & QV4::CompiledData::Unit::IsESModule) { + if (m_precompiledScript->isESModule()) { m_loaded = true; m_value.set(v4, m_precompiledScript->instantiate(v4)); @@ -2926,54 +2975,14 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent QQmlEnginePrivate *ep = QQmlEnginePrivate::get(parentCtxt->engine); QV4::Scope scope(v4); - bool shared = m_precompiledScript->unitData()->flags & QV4::CompiledData::Unit::IsSharedLibrary; - - QQmlContextData *effectiveCtxt = parentCtxt; - if (shared) - effectiveCtxt = nullptr; - // Create the script context if required - QQmlContextDataRef ctxt(new QQmlContextData); - ctxt->isInternal = true; - ctxt->isJSContext = true; - if (shared) - ctxt->isPragmaLibraryContext = true; - else - ctxt->isPragmaLibraryContext = parentCtxt->isPragmaLibraryContext; - ctxt->baseUrl = url; - ctxt->baseUrlString = urlString; - - // For backward compatibility, if there are no imports, we need to use the - // imports from the parent context. See QTBUG-17518. - if (!typeNameCache->isEmpty()) { - ctxt->imports = typeNameCache; - } else if (effectiveCtxt) { - ctxt->imports = effectiveCtxt->imports; - ctxt->importedScripts = effectiveCtxt->importedScripts; - } - - if (effectiveCtxt) { - ctxt->setParent(effectiveCtxt); - } else { - ctxt->engine = parentCtxt->engine; // Fix for QTBUG-21620 - } - - QV4::ScopedObject scriptsArray(scope); - if (ctxt->importedScripts.isNullOrUndefined()) { - scriptsArray = v4->newArrayObject(scripts.count()); - ctxt->importedScripts.set(v4, scriptsArray); - } else { - scriptsArray = ctxt->importedScripts.valueRef(); - } - QV4::ScopedValue v(scope); - for (int ii = 0; ii < scripts.count(); ++ii) - scriptsArray->put(ii, (v = scripts.at(ii)->scriptData()->scriptValueForContext(ctxt))); + QQmlContextDataRef ctxt(qmlContextDataForContext(parentCtxt)); if (!hasEngine()) initialize(parentCtxt->engine); if (!m_program) { - if (shared) + if (m_precompiledScript->isSharedLibrary()) m_loaded = true; return QV4::Encode::undefined(); } @@ -2990,7 +2999,7 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent } QV4::ScopedValue retval(scope, qmlContext->d()->qml()); - if (shared) { + if (m_precompiledScript->isSharedLibrary()) { m_value.set(scope.engine, retval); m_loaded = true; } diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index 031554b330..29c91346de 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -552,6 +552,7 @@ private: friend class QQmlScriptBlob; void initialize(QQmlEngine *); + QQmlContextData *qmlContextDataForContext(QQmlContextData *parentQmlContextData); bool m_loaded; QQmlRefPointer<QV4::CompiledData::CompilationUnit> m_precompiledScript; diff --git a/src/qml/types/qqmlinstantiator_p.h b/src/qml/types/qqmlinstantiator_p.h index 5727c4d1e1..ca371adc23 100644 --- a/src/qml/types/qqmlinstantiator_p.h +++ b/src/qml/types/qqmlinstantiator_p.h @@ -53,11 +53,12 @@ #include <QtQml/qqmlcomponent.h> #include <QtQml/qqmlparserstatus.h> +#include <QtQml/private/qtqmlglobal_p.h> QT_BEGIN_NAMESPACE class QQmlInstantiatorPrivate; -class Q_AUTOTEST_EXPORT QQmlInstantiator : public QObject, public QQmlParserStatus +class Q_QML_PRIVATE_EXPORT QQmlInstantiator : public QObject, public QQmlParserStatus { Q_OBJECT Q_INTERFACES(QQmlParserStatus) diff --git a/src/qml/types/qqmlinstantiator_p_p.h b/src/qml/types/qqmlinstantiator_p_p.h index a5a4d1a32d..4c76d5c689 100644 --- a/src/qml/types/qqmlinstantiator_p_p.h +++ b/src/qml/types/qqmlinstantiator_p_p.h @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE -class QQmlInstantiatorPrivate : public QObjectPrivate +class Q_QML_PRIVATE_EXPORT QQmlInstantiatorPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QQmlInstantiator) @@ -76,6 +76,9 @@ public: void _q_modelUpdated(const QQmlChangeSet &, bool); QObject *modelObject(int index, bool async); + static QQmlInstantiatorPrivate *get(QQmlInstantiator *instantiator) { return instantiator->d_func(); } + static const QQmlInstantiatorPrivate *get(const QQmlInstantiator *instantiator) { return instantiator->d_func(); } + bool componentComplete:1; bool effectiveReset:1; bool active:1; diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp index 2b50a0867c..831663fb7b 100644 --- a/src/qml/util/qqmladaptormodel.cpp +++ b/src/qml/util/qqmladaptormodel.cpp @@ -990,7 +990,7 @@ int QQmlAdaptorModel::rowCount() const int QQmlAdaptorModel::columnCount() const { - return qMax(isValid() ? 1 : 0, accessors->columnCount(*this)); + return qMax(0, accessors->columnCount(*this)); } int QQmlAdaptorModel::rowAt(int index) const diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp index d49829096f..e4e766a129 100644 --- a/src/quick/items/qquickborderimage.cpp +++ b/src/quick/items/qquickborderimage.cpp @@ -591,10 +591,18 @@ void QQuickBorderImagePrivate::calculateRects(const QQuickScaleGrid *border, *innerTargetRect = *targetRect; if (border) { - *innerSourceRect = QRectF(border->left() * devicePixelRatio / qreal(sourceSize.width()), - border->top() * devicePixelRatio / qreal(sourceSize.height()), - qMax<qreal>(0, sourceSize.width() - (border->right() + border->left()) * devicePixelRatio) / sourceSize.width(), - qMax<qreal>(0, sourceSize.height() - (border->bottom() + border->top()) * devicePixelRatio) / sourceSize.height()); + qreal borderLeft = border->left() * devicePixelRatio; + qreal borderRight = border->right() * devicePixelRatio; + qreal borderTop = border->top() * devicePixelRatio; + qreal borderBottom = border->bottom() * devicePixelRatio; + if (borderLeft + borderRight > sourceSize.width() && borderLeft < sourceSize.width()) + borderRight = sourceSize.width() - borderLeft; + if (borderTop + borderBottom > sourceSize.height() && borderTop < sourceSize.height()) + borderBottom = sourceSize.height() - borderTop; + *innerSourceRect = QRectF(QPointF(borderLeft / qreal(sourceSize.width()), + borderTop * devicePixelRatio / qreal(sourceSize.height())), + QPointF((sourceSize.width() - borderRight) / qreal(sourceSize.width()), + (sourceSize.height() - borderBottom) / qreal(sourceSize.height()))), *innerTargetRect = QRectF(border->left(), border->top(), qMax<qreal>(0, targetSize.width() - (border->right() + border->left())), @@ -604,14 +612,16 @@ void QQuickBorderImagePrivate::calculateRects(const QQuickScaleGrid *border, qreal hTiles = 1; qreal vTiles = 1; const QSizeF innerTargetSize = innerTargetRect->size() * devicePixelRatio; - if (innerSourceRect->width() != 0 - && horizontalTileMode != QQuickBorderImage::Stretch) { + if (innerSourceRect->width() <= 0) + hTiles = 0; + else if (horizontalTileMode != QQuickBorderImage::Stretch) { hTiles = innerTargetSize.width() / qreal(innerSourceRect->width() * sourceSize.width()); if (horizontalTileMode == QQuickBorderImage::Round) hTiles = qCeil(hTiles); } - if (innerSourceRect->height() != 0 - && verticalTileMode != QQuickBorderImage::Stretch) { + if (innerSourceRect->height() <= 0) + vTiles = 0; + else if (verticalTileMode != QQuickBorderImage::Stretch) { vTiles = innerTargetSize.height() / qreal(innerSourceRect->height() * sourceSize.height()); if (verticalTileMode == QQuickBorderImage::Round) vTiles = qCeil(vTiles); diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index a1a71bf3cd..8dafc16cf4 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -1185,6 +1185,7 @@ void QQuickItemView::modelUpdated(const QQmlChangeSet &changeSet, bool reset) { Q_D(QQuickItemView); if (reset) { + cancelFlick(); if (d->transitioner) d->transitioner->setPopulateTransitionEnabled(true); d->moveReason = QQuickItemViewPrivate::SetIndex; diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 540805ac28..908801ce1c 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -515,8 +515,8 @@ QString QQuickListViewPrivate::sectionAt(int modelIndex) qreal QQuickListViewPrivate::snapPosAt(qreal pos) { - if (FxViewItem *snapItem = snapItemAt(pos)) - return snapItem->position(); + if (FxListItemSG *snapItem = static_cast<FxListItemSG*>(snapItemAt(pos))) + return snapItem->itemPosition(); if (visibleItems.count()) { qreal firstPos = (*visibleItems.constBegin())->position(); qreal endPos = (*(--visibleItems.constEnd()))->position(); @@ -530,22 +530,35 @@ qreal QQuickListViewPrivate::snapPosAt(qreal pos) FxViewItem *QQuickListViewPrivate::snapItemAt(qreal pos) { + const qreal velocity = orient == QQuickListView::Vertical ? vData.velocity : hData.velocity; FxViewItem *snapItem = nullptr; + FxViewItem *prevItem = nullptr; qreal prevItemSize = 0; for (FxViewItem *item : qAsConst(visibleItems)) { if (item->index == -1) continue; - qreal itemTop = item->position(); - if (highlight && itemTop >= pos && item->endPosition() <= pos + highlight->size()) + + const FxListItemSG *listItem = static_cast<FxListItemSG *>(item); + qreal itemTop = listItem->position(); + qreal itemSize = listItem->size(); + if (highlight && itemTop >= pos && listItem->endPosition() <= pos + highlight->size()) return item; + if (listItem->section() && velocity > 0) { + if (itemTop + listItem->sectionSize() / 2 >= pos && itemTop - prevItemSize / 2 < pos) + snapItem = prevItem; + itemTop = listItem->itemPosition(); + itemSize = listItem->itemSize(); + } + // Middle of item and spacing (i.e. the middle of the distance between this item and the next - qreal halfwayToNextItem = itemTop + (item->size()+spacing) / 2; + qreal halfwayToNextItem = itemTop + (itemSize+spacing) / 2; qreal halfwayToPrevItem = itemTop - (prevItemSize+spacing) / 2; if (halfwayToNextItem >= pos && halfwayToPrevItem < pos) snapItem = item; - prevItemSize = item->size(); + prevItemSize = listItem->itemSize(); + prevItem = item; } return snapItem; } @@ -1530,15 +1543,15 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte pos = isContentFlowReversed() ? - header->position() + highlightRangeStart - size() : header->position() - highlightRangeStart; } else { if (isContentFlowReversed()) - pos = qMax(qMin(-topItem->position() + highlightRangeStart - size(), -maxExtent), -minExtent); + pos = qMax(qMin(-static_cast<FxListItemSG*>(topItem)->itemPosition() + highlightRangeStart - size(), -maxExtent), -minExtent); else - pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent); + pos = qMax(qMin(static_cast<FxListItemSG*>(topItem)->itemPosition() - highlightRangeStart, -maxExtent), -minExtent); } } else if (bottomItem && isInBounds) { if (isContentFlowReversed()) - pos = qMax(qMin(-bottomItem->position() + highlightRangeEnd - size(), -maxExtent), -minExtent); + pos = qMax(qMin(-static_cast<FxListItemSG*>(bottomItem)->itemPosition() + highlightRangeEnd - size(), -maxExtent), -minExtent); else - pos = qMax(qMin(bottomItem->position() - highlightRangeEnd, -maxExtent), -minExtent); + pos = qMax(qMin(static_cast<FxListItemSG*>(bottomItem)->itemPosition() - highlightRangeEnd, -maxExtent), -minExtent); } else { QQuickItemViewPrivate::fixup(data, minExtent, maxExtent); return; @@ -1568,7 +1581,10 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte timeline.reset(data.move); if (viewPos != position()) { if (fixupMode != Immediate) { - timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); + if (fixupMode == ExtentChanged && data.fixingUp) + timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::OutQuad), fixupDuration/2); + else + timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); data.fixingUp = true; } else { timeline.set(data.move, -viewPos); diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index d7060cbdea..4b13cde2d5 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -1664,6 +1664,7 @@ void QQuickTableViewPrivate::connectToModel() connect(aim, &QAbstractItemModel::columnsInserted, this, &QQuickTableViewPrivate::columnsInsertedCallback); connect(aim, &QAbstractItemModel::columnsRemoved, this, &QQuickTableViewPrivate::columnsRemovedCallback); connect(aim, &QAbstractItemModel::modelReset, this, &QQuickTableViewPrivate::modelResetCallback); + connect(aim, &QAbstractItemModel::layoutChanged, this, &QQuickTableViewPrivate::layoutChangedCallback); } else { QObjectPrivate::connect(model, &QQmlInstanceModel::modelUpdated, this, &QQuickTableViewPrivate::modelUpdated); } @@ -1689,6 +1690,7 @@ void QQuickTableViewPrivate::disconnectFromModel() disconnect(aim, &QAbstractItemModel::columnsInserted, this, &QQuickTableViewPrivate::columnsInsertedCallback); disconnect(aim, &QAbstractItemModel::columnsRemoved, this, &QQuickTableViewPrivate::columnsRemovedCallback); disconnect(aim, &QAbstractItemModel::modelReset, this, &QQuickTableViewPrivate::modelResetCallback); + disconnect(aim, &QAbstractItemModel::layoutChanged, this, &QQuickTableViewPrivate::layoutChangedCallback); } else { QObjectPrivate::disconnect(model, &QQmlInstanceModel::modelUpdated, this, &QQuickTableViewPrivate::modelUpdated); } @@ -1751,6 +1753,14 @@ void QQuickTableViewPrivate::columnsRemovedCallback(const QModelIndex &parent, i scheduleRebuildTable(RebuildOption::ViewportOnly); } +void QQuickTableViewPrivate::layoutChangedCallback(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint) +{ + Q_UNUSED(parents); + Q_UNUSED(hint); + + scheduleRebuildTable(RebuildOption::ViewportOnly); +} + void QQuickTableViewPrivate::modelResetCallback() { scheduleRebuildTable(RebuildOption::All); diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h index a4f829addd..2ed04f8d29 100644 --- a/src/quick/items/qquicktableview_p_p.h +++ b/src/quick/items/qquicktableview_p_p.h @@ -356,6 +356,7 @@ public: void rowsRemovedCallback(const QModelIndex &parent, int begin, int end); void columnsInsertedCallback(const QModelIndex &parent, int begin, int end); void columnsRemovedCallback(const QModelIndex &parent, int begin, int end); + void layoutChangedCallback(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint); void modelResetCallback(); void _q_componentFinalized(); diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 059886f41c..d27ee54c89 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -774,6 +774,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve void QQuickWindowPrivate::grabTouchPoints(QObject *grabber, const QVector<int> &ids) { + QQuickPointerEvent *ev = nullptr; for (int i = 0; i < ids.count(); ++i) { int id = ids.at(i); if (Q_UNLIKELY(id < 0)) { @@ -793,15 +794,26 @@ void QQuickWindowPrivate::grabTouchPoints(QObject *grabber, const QVector<int> & qCDebug(DBG_MOUSE_TARGET) << "grabTouchPoints: mouse grabber changed due to grabTouchPoints:" << touchMouseGrabber << "-> null"; } + // optimization to avoid the loop over devices below: + // all ids are probably from the same event, so we don't have to search + if (ev) { + auto point = ev->pointById(id); + if (point && point->exclusiveGrabber() != grabber) { + point->setExclusiveGrabber(grabber); + continue; // next id in the ids loop + } + } + // search all devices for a QQuickPointerEvent instance that is delivering the point with id const auto touchDevices = QQuickPointerDevice::touchDevices(); for (auto device : touchDevices) { - auto point = pointerEventInstance(device)->pointById(id); - if (!point) - continue; - QObject *oldGrabber = point->exclusiveGrabber(); - if (oldGrabber == grabber) - continue; - point->setExclusiveGrabber(grabber); + QQuickPointerEvent *pev = pointerEventInstance(device); + auto point = pev->pointById(id); + if (point) { + ev = pev; + if (point->exclusiveGrabber() != grabber) + point->setExclusiveGrabber(grabber); + break; // out of touchDevices loop + } } } } diff --git a/src/quick/scenegraph/qsgbasicinternalimagenode.cpp b/src/quick/scenegraph/qsgbasicinternalimagenode.cpp index c8699218ba..53271af9ab 100644 --- a/src/quick/scenegraph/qsgbasicinternalimagenode.cpp +++ b/src/quick/scenegraph/qsgbasicinternalimagenode.cpp @@ -484,7 +484,7 @@ void QSGBasicInternalImageNode::updateGeometry() int hTiles = ceilRight - floorLeft; int vTiles = ceilBottom - floorTop; - bool hasTiles = hTiles != 1 || vTiles != 1; + bool hasTiles = hTiles > 1 || vTiles > 1; bool fullTexture = innerSourceRect == QRectF(0, 0, 1, 1); // An image can be rendered as a single quad if: diff --git a/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp b/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp index 56508af152..94912778f8 100644 --- a/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp +++ b/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp @@ -57,20 +57,34 @@ QSGDepthStencilBuffer::~QSGDepthStencilBuffer() m_manager->m_buffers.remove(m_format); } +#ifndef GL_DEPTH_STENCIL_ATTACHMENT +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#endif + void QSGDepthStencilBuffer::attach() { +#ifndef Q_OS_WASM m_functions.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthBuffer); m_functions.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_stencilBuffer); +#else + m_functions.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, + GL_RENDERBUFFER, m_stencilBuffer); +#endif } void QSGDepthStencilBuffer::detach() { +#ifndef Q_OS_WASM m_functions.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); m_functions.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); +#else + m_functions.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, + GL_RENDERBUFFER, 0); +#endif } #ifndef GL_DEPTH24_STENCIL8_OES @@ -81,12 +95,17 @@ void QSGDepthStencilBuffer::detach() #define GL_DEPTH_COMPONENT24_OES 0x81A6 #endif +#ifndef GL_DEPTH_STENCIL +#define GL_DEPTH_STENCIL 0x84F9 +#endif + QSGDefaultDepthStencilBuffer::QSGDefaultDepthStencilBuffer(QOpenGLContext *context, const Format &format) : QSGDepthStencilBuffer(context, format) { const GLsizei width = format.size.width(); const GLsizei height = format.size.height(); +#ifndef Q_OS_WASM if (format.attachments == (DepthAttachment | StencilAttachment) && m_functions.hasOpenGLExtension(QOpenGLExtensions::PackedDepthStencil)) { @@ -138,6 +157,12 @@ QSGDefaultDepthStencilBuffer::QSGDefaultDepthStencilBuffer(QOpenGLContext *conte m_functions.glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, width, height); } } +#else + m_functions.glGenRenderbuffers(1, &m_depthBuffer); + m_functions.glBindRenderbuffer(GL_RENDERBUFFER, m_depthBuffer); + m_functions.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height); + m_stencilBuffer = m_depthBuffer; +#endif } QSGDefaultDepthStencilBuffer::~QSGDefaultDepthStencilBuffer() |