aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-02-24 10:14:57 +0100
committerLiang Qi <liang.qi@qt.io>2017-02-24 11:48:14 +0100
commitb1fa22c1683d9f6cedb001f5ef8a0dac71868935 (patch)
treec30a114c75be071310df974283b928329f9d5c12 /src
parentba68c325688acf3072715757480497524f61c425 (diff)
parentfe5d69669197a51662061b014810f0242eec5ca7 (diff)
Merge remote-tracking branch 'origin/5.8' into 5.9
Conflicts: src/qml/compiler/qv4ssa.cpp src/quick/accessible/qaccessiblequickview_p.h src/quick/items/qquickmousearea.cpp src/quick/util/qquickanimatorjob.cpp tools/qmlplugindump/main.cpp Change-Id: I84474cf39895b9b757403971d2e9196e8c9d1809
Diffstat (limited to 'src')
-rw-r--r--src/imports/imports.pro4
-rw-r--r--src/imports/localstorage/plugin.cpp2
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp3
-rw-r--r--src/qml/compiler/qv4compileddata.cpp5
-rw-r--r--src/qml/compiler/qv4jsir_p.h10
-rw-r--r--src/qml/compiler/qv4ssa.cpp195
-rw-r--r--src/qml/compiler/qv4ssa_p.h13
-rw-r--r--src/qml/debugger/qqmldebugserviceinterfaces_p.h18
-rw-r--r--src/qml/debugger/qqmlprofiler_p.h2
-rw-r--r--src/qml/doc/src/qmlfunctions.qdoc14
-rw-r--r--src/qml/jit/qv4regalloc.cpp8
-rw-r--r--src/qml/jsapi/qjsengine.cpp2
-rw-r--r--src/qml/jsruntime/qv4debugging_p.h3
-rw-r--r--src/qml/jsruntime/qv4profiling_p.h2
-rw-r--r--src/qml/qml/qqmlengine.cpp2
-rw-r--r--src/qml/qml/qqmlexpression.cpp1
-rw-r--r--src/qml/qml/qqmllist.cpp10
-rw-r--r--src/qml/qml/qqmlproperty.cpp16
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp15
-rw-r--r--src/quick/accessible/qaccessiblequickview.cpp8
-rw-r--r--src/quick/accessible/qaccessiblequickview_p.h1
-rw-r--r--src/quick/doc/snippets/qml/localstorage/hello.qml76
-rw-r--r--src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc2
-rw-r--r--src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc22
-rw-r--r--src/quick/doc/src/concepts/positioning/topic.qdoc2
-rw-r--r--src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc14
-rw-r--r--src/quick/doc/src/concepts/visualcanvas/visualparent.qdoc2
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture.cpp7
-rw-r--r--src/quick/items/qquickflickable.cpp5
-rw-r--r--src/quick/items/qquickitem.cpp10
-rw-r--r--src/quick/items/qquickmousearea.cpp28
-rw-r--r--src/quick/items/qquickopenglshadereffect.cpp10
-rw-r--r--src/quick/items/qquickshadereffect.cpp5
-rw-r--r--src/quick/items/qquickshadereffect_p.h2
-rw-r--r--src/quick/items/qquickwindow.cpp18
-rw-r--r--src/quick/scenegraph/qsgdefaultlayer.cpp7
-rw-r--r--src/quick/scenegraph/util/qsgdefaultpainternode.cpp6
-rw-r--r--src/quick/util/qquickanimatorjob.cpp4
-rw-r--r--src/quick/util/qquickimageprovider.cpp4
-rw-r--r--src/src.pro2
40 files changed, 391 insertions, 169 deletions
diff --git a/src/imports/imports.pro b/src/imports/imports.pro
index 20ade45fc8..45719df874 100644
--- a/src/imports/imports.pro
+++ b/src/imports/imports.pro
@@ -1,5 +1,7 @@
TEMPLATE = subdirs
+QT_FOR_CONFIG += quick-private
+
SUBDIRS += \
builtins \
qtqml \
@@ -18,7 +20,7 @@ qtHaveModule(quick) {
sharedimage \
testlib
- qtConfig(opengl(es1|es2)?): \
+ qtConfig(quick-sprite):qtConfig(opengl(es1|es2)?): \
SUBDIRS += particles
}
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
index 60b8dad5fb..8679750842 100644
--- a/src/imports/localstorage/plugin.cpp
+++ b/src/imports/localstorage/plugin.cpp
@@ -564,7 +564,7 @@ Database connections are automatically closed during Javascript garbage collecti
The API can be used from JavaScript functions in your QML:
-\snippet localstorage/localstorage/hello.qml 0
+\snippet qml/localstorage/hello.qml 0
The API conforms to the Synchronous API of the HTML5 Web Database API,
\link http://www.w3.org/TR/2009/WD-webdatabase-20091029/ W3C Working Draft 29 October 2009\endlink.
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 85267225be..109eb86c2e 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -1108,10 +1108,9 @@ QQmlComponentAndAliasResolver::AliasResolutionResult QQmlComponentAndAliasResolv
continue;
}
- // Try again later and resolve the target alias first.
- _objectsWithAliases.append(objectIndex);
// restore
alias->idIndex = idIndex;
+ // Try again later and resolve the target alias first.
break;
}
}
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 8f8d374e24..a8f065210b 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -427,6 +427,7 @@ bool CompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorString)
}
#endif
+#if QT_CONFIG(temporaryfile)
// Foo.qml -> Foo.qmlc
QSaveFile cacheFile(cacheFilePath(unitUrl));
if (!cacheFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
@@ -459,6 +460,10 @@ bool CompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorString)
}
return true;
+#else
+ *errorString = QStringLiteral("features.temporaryfile is disabled.");
+ return false;
+#endif // QT_CONFIG(temporaryfile)
}
void CompilationUnit::prepareCodeOffsetsForDiskStorage(Unit *unit)
diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h
index 04bc3d86e5..23ebe0c962 100644
--- a/src/qml/compiler/qv4jsir_p.h
+++ b/src/qml/compiler/qv4jsir_p.h
@@ -507,6 +507,16 @@ struct Q_AUTOTEST_EXPORT Temp: Expr {
, memberResolver(0)
{}
+ Temp(Type type, Kind kind, unsigned index)
+ : Expr(TempExpr)
+ , index(index)
+ , isReadOnly(0)
+ , kind(kind)
+ , memberResolver(0)
+ {
+ this->type = type;
+ }
+
void init(unsigned kind, unsigned index)
{
this->index = index;
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index 10f0bbcf8f..cc542e94e7 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -3581,16 +3581,43 @@ public:
, _replacement(0)
{}
- void operator()(Temp *toReplace, Expr *replacement, StatementWorklist &W, QVector<Stmt *> *newUses = 0)
+ bool operator()(Temp *toReplace, Expr *replacement, StatementWorklist &W, QVector<Stmt *> *newUses = 0)
{
Q_ASSERT(replacement->asTemp() || replacement->asConst() || replacement->asName());
-// qout << "Replacing ";toReplace->dump(qout);qout<<" by ";replacement->dump(qout);qout<<endl;
-
qSwap(_toReplace, toReplace);
qSwap(_replacement, replacement);
const QVector<Stmt *> &uses = _defUses.uses(*_toReplace);
+
+ // Prevent the following:
+ // L3:
+ // %1 = phi L1: %2, L2: %3
+ // %4 = phi L1: %5, L2: %6
+ // %6 = %1
+ // From turning into:
+ // L3:
+ // %1 = phi L1: %2, L2: %3
+ // %4 = phi L1: %5, L2: %1
+ //
+ // Because both phi nodes are "executed in parallel", we cannot replace %6 by %1 in the
+ // second phi node. So, if the defining statement for a temp is a phi node, and one of the
+ // uses of the to-be-replaced statement is a phi node in the same block as the defining
+ // statement, bail out.
+ if (Temp *r = _replacement->asTemp()) {
+ if (_defUses.defStmt(*r)->asPhi()) {
+ BasicBlock *replacementDefBlock = _defUses.defStmtBlock(*r);
+ for (Stmt *use : uses) {
+ if (Phi *usePhi = use->asPhi()) {
+ if (_defUses.defStmtBlock(*usePhi->targetTemp) == replacementDefBlock)
+ return false;
+ }
+ }
+ }
+ }
+
+// qout << "Replacing ";toReplace->dump(qout);qout<<" by ";replacement->dump(qout);qout<<endl;
+
if (newUses)
newUses->reserve(uses.size());
@@ -3606,6 +3633,7 @@ public:
qSwap(_replacement, replacement);
qSwap(_toReplace, toReplace);
+ return true;
}
private:
@@ -4082,11 +4110,12 @@ void optimizeSSA(StatementWorklist &W, DefUses &defUses, DominatorTree &df)
// copy propagation:
if (Temp *sourceTemp = m->source->asTemp()) {
QVector<Stmt *> newT2Uses;
- replaceUses(targetTemp, sourceTemp, W, &newT2Uses);
- defUses.removeUse(s, *sourceTemp);
- defUses.addUses(*sourceTemp, newT2Uses);
- defUses.removeDef(*targetTemp);
- W.remove(s);
+ if (replaceUses(targetTemp, sourceTemp, W, &newT2Uses)) {
+ defUses.removeUse(s, *sourceTemp);
+ defUses.addUses(*sourceTemp, newT2Uses);
+ defUses.removeDef(*targetTemp);
+ W.remove(s);
+ }
continue;
}
@@ -5635,25 +5664,97 @@ void MoveMapping::add(Expr *from, Temp *to) {
_moves.append(m);
}
+// Order the moves that are generated when resolving edges during register allocation (see [Wimmer1]
+// section 6 for details). Now these moves form one or more graphs, so we have to output them in
+// such an order that values don't get overwritten:
+// r1 <- r0
+// r2 <- r1
+// That input has to be ordered as follows in order to prevent the value in r1 from being lost:
+// r2 <- r1
+// r1 <- r0
+//
+// So, the algorithm is to output the leaves first, and take them out of the input. This will result
+// in some moves to become leaves (in the above example: when leaf r2 <- r1 is generated and taken
+// away, the r1 <- r0 is now a leaf), so we can output those and take those out, and repeat until
+// there are no more leafs.
+//
+// The tricky part is that there might be cycles:
+// r4 <- r5
+// r5 <- r4
+// These have to be turned into a "register swap":
+// r4 <=> r5
+//
+// So after running the above algorithm where we progressively remove the leaves, we are left with
+// zero or more cycles. To resolve those, we break one of the edges of the cycle, and for all other
+// edges we generate swaps. Note that the swaps will always occur as the last couple of moves,
+// because otherwise they might clobber sources for moves:
+// r4 <=> r5
+// r6 <- r5
+// Here, the value of r5 is already overwritten with the one in r4, so the correct order is:
+// r6 <- r5
+// r4 <=> r5
void MoveMapping::order()
{
- QList<Move> todo = _moves;
- QList<Move> output, swaps;
+ QList<Move> output;
output.reserve(_moves.size());
- QList<Move> delayed;
- delayed.reserve(_moves.size());
- while (!todo.isEmpty()) {
- const Move m = todo.first();
- todo.removeFirst();
- schedule(m, todo, delayed, output, swaps);
- }
+ while (!_moves.isEmpty()) {
+ // Take out all leaf edges, because we can output them without any problems.
+ int nextLeaf = findLeaf();
+ if (nextLeaf == -1)
+ break; // No more leafs left, we're done here.
+ output.append(_moves.takeAt(nextLeaf));
+ // Now there might be new leaf edges: any move that had the input of the previously found
+ // leaf as an output, so loop around.
+ }
+
+ while (!_moves.isEmpty()) {
+ // We're now left with one or more cycles.
+ // Step one: break the/a cycle.
+ _moves.removeFirst();
+ // Step two: find the other edges of the cycle, starting with the one of that is now a leaf.
+ while (!_moves.isEmpty()) {
+ int nextLeaf = findLeaf();
+ if (nextLeaf == -1)
+ break; // We're done with this cycle.
+ Move m = _moves.takeAt(nextLeaf);
+ // Step three: get the edges from the cycle and turn it into a swap
+ m.needsSwap = true;
+ output.append(m);
+ // Because we took out a leaf, find the next one.
+ }
+ // We're done with the cycle, let's see if there are more.
+ }
+
+ _moves = output;
+}
+
+int MoveMapping::findLeaf() const
+{
+ for (int i = 0, e = _moves.size(); i != e; ++i) {
+ // Take an edge from the list...
+ const Temp *target = _moves.at(i).to;
+ // ... and see if its target is used as a source...
+ bool targetUsedAsSource = false;
+ for (int j = 0; j != e; ++j) {
+ if (i == j)
+ continue;
- output += swaps;
+ Expr *source = _moves.at(j).from;
+ if (const Temp *sourceTemp = source->asTemp()) {
+ if (overlappingStorage(*target, *sourceTemp)) {
+ targetUsedAsSource = true;
+ break;
+ }
+ }
+ }
+ // ... if not, we have a leaf edge ...
+ if (!targetUsedAsSource)
+ return i;
+ // .. otherwise we try the next one.
+ }
- Q_ASSERT(todo.isEmpty());
- Q_ASSERT(delayed.isEmpty());
- qSwap(_moves, output);
+ return -1; // No leaf found
}
QList<IR::Move *> MoveMapping::insertMoves(BasicBlock *bb, IR::Function *function, bool atEnd) const
@@ -5695,60 +5796,12 @@ void MoveMapping::dump() const
}
}
-MoveMapping::Action MoveMapping::schedule(const Move &m, QList<Move> &todo, QList<Move> &delayed,
- QList<Move> &output, QList<Move> &swaps) const
-{
- const Moves usages = sourceUsages(m.to, todo) + sourceUsages(m.to, delayed);
- for (const Move &dependency : usages) {
- if (!output.contains(dependency)) {
- if (delayed.contains(dependency)) {
- // We have a cycle! Break it by swapping instead of assigning.
- if (DebugMoveMapping) {
- delayed += m;
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream out(&buf);
- IRPrinter printer(&out);
- out<<"we have a cycle! temps:" << endl;
- for (const Move &m : qAsConst(delayed)) {
- out<<"\t";
- printer.print(m.to);
- out<<" <- ";
- printer.print(m.from);
- out<<endl;
- }
- qDebug("%s", buf.data().constData());
- delayed.removeOne(m);
- }
-
- return NeedsSwap;
- } else {
- delayed.append(m);
- todo.removeOne(dependency);
- Action action = schedule(dependency, todo, delayed, output, swaps);
- delayed.removeOne(m);
- Move mm(m);
- if (action == NeedsSwap) {
- mm.needsSwap = true;
- swaps.append(mm);
- } else {
- output.append(mm);
- }
- return action;
- }
- }
- }
-
- output.append(m);
- return NormalMove;
-}
-
// References:
// [Wimmer1] C. Wimmer and M. Franz. Linear Scan Register Allocation on SSA Form. In Proceedings of
-// CGO’10, ACM Press, 2010
+// CGO'10, ACM Press, 2010
// [Wimmer2] C. Wimmer and H. Mossenbock. Optimized Interval Splitting in a Linear Scan Register
// Allocator. In Proceedings of the ACM/USENIX International Conference on Virtual
-// Execution Environments, pages 132–141. ACM Press, 2005.
+// Execution Environments, pages 132-141. ACM Press, 2005.
// [Briggs] P. Briggs, K.D. Cooper, T.J. Harvey, and L.T. Simpson. Practical Improvements to the
// Construction and Destruction of Static Single Assignment Form.
// [Appel] A.W. Appel. Modern Compiler Implementation in Java. Second edition, Cambridge
diff --git a/src/qml/compiler/qv4ssa_p.h b/src/qml/compiler/qv4ssa_p.h
index c07abd04c4..24257e99e9 100644
--- a/src/qml/compiler/qv4ssa_p.h
+++ b/src/qml/compiler/qv4ssa_p.h
@@ -265,15 +265,18 @@ private:
QHash<BasicBlock *, BasicBlock *> startEndLoops;
};
-class MoveMapping
+class Q_AUTOTEST_EXPORT MoveMapping
{
+#ifdef V4_AUTOTEST
+public:
+#endif
struct Move {
Expr *from;
Temp *to;
bool needsSwap;
- Move(Expr *from, Temp *to)
- : from(from), to(to), needsSwap(false)
+ Move(Expr *from, Temp *to, bool needsSwap = false)
+ : from(from), to(to), needsSwap(needsSwap)
{}
bool operator==(const Move &other) const
@@ -293,9 +296,7 @@ public:
void dump() const;
private:
- enum Action { NormalMove, NeedsSwap };
- Action schedule(const Move &m, QList<Move> &todo, QList<Move> &delayed, QList<Move> &output,
- QList<Move> &swaps) const;
+ int findLeaf() const;
};
/*
diff --git a/src/qml/debugger/qqmldebugserviceinterfaces_p.h b/src/qml/debugger/qqmldebugserviceinterfaces_p.h
index 2fe3a588c3..707ef1a937 100644
--- a/src/qml/debugger/qqmldebugserviceinterfaces_p.h
+++ b/src/qml/debugger/qqmldebugserviceinterfaces_p.h
@@ -67,13 +67,15 @@ class QQuickWindow;
#ifdef QT_NO_QML_DEBUGGER
-struct QV4DebugService
+class QV4DebugService
{
+public:
void signalEmitted(const QString &) {}
};
-struct QQmlProfilerService
+class QQmlProfilerService
{
+public:
void startProfiling(QJSEngine *engine, quint64 features = std::numeric_limits<quint64>::max())
{
Q_UNUSED(engine);
@@ -83,21 +85,23 @@ struct QQmlProfilerService
void stopProfiling(QJSEngine *) {}
};
-struct QQmlEngineDebugService
+class QQmlEngineDebugService
{
+public:
void objectCreated(QJSEngine *, QObject *) {}
virtual void setStatesDelegate(QQmlDebugStatesDelegate *) {}
};
-struct QQmlInspectorService {
+class QQmlInspectorService {
+public:
void addWindow(QQuickWindow *) {}
void setParentWindow(QQuickWindow *, QWindow *) {}
void removeWindow(QQuickWindow *) {}
};
-struct QDebugMessageService {};
-struct QQmlEngineControlService {};
-struct QQmlNativeDebugService {};
+class QDebugMessageService {};
+class QQmlEngineControlService {};
+class QQmlNativeDebugService {};
#else
diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h
index 41fb2c5b7b..88f8e94f25 100644
--- a/src/qml/debugger/qqmlprofiler_p.h
+++ b/src/qml/debugger/qqmlprofiler_p.h
@@ -69,7 +69,7 @@ QT_BEGIN_NAMESPACE
#define Q_QML_PROFILE(feature, profiler, Method)
#define Q_QML_OC_PROFILE(member, Code)
-struct QQmlProfiler {};
+class QQmlProfiler {};
struct QQmlBindingProfiler
{
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc
index a03c382ed5..834684fe6d 100644
--- a/src/qml/doc/src/qmlfunctions.qdoc
+++ b/src/qml/doc/src/qmlfunctions.qdoc
@@ -168,8 +168,9 @@
from \a uri having version number composed from \a versionMajor and
\a versionMinor.
- While the type has a name and a type, it cannot be created, and the
- given error \a reason will result if creation is attempted.
+ While the type has a name and a type, it cannot be created. An error
+ message with the given \a reason is printed if the user attempts to
+ create an instance of this type.
This is useful where the type is only intended for providing attached
properties, enum values or an abstract base class with its extension.
@@ -189,11 +190,14 @@
from \a uri having version number composed from \a versionMajor and
\a versionMinor.
- This function is useful to register Q_NAMESPACE namespaces.
+ An instance of the meta object cannot be created. An error message with
+ the given \a reason is printed if the user attempts to create it.
+
+ This function is useful for registering Q_NAMESPACE namespaces.
Returns the QML type id.
- Example:
+ For example:
\code
namespace MyNamespace {
@@ -209,7 +213,7 @@
qmlRegisterUncreatableMetaObject(MyNamespace::staticMetaObject, "io.qt", 1, 0, "MyNamespace", "Access to enums & flags only");
\endcode
- Now on QML side you can use the registered enums:
+ On the QML side, you can now use the registered enums:
\code
Component.onCompleted: console.log(MyNamespace.Key2)
\endcode
diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp
index e5abaa7458..8eafaaaa8a 100644
--- a/src/qml/jit/qv4regalloc.cpp
+++ b/src/qml/jit/qv4regalloc.cpp
@@ -1138,6 +1138,8 @@ private:
mapping.add(moveFrom, moveTo);
}
+ if (DebugRegAlloc)
+ mapping.dump();
mapping.order();
if (DebugRegAlloc)
mapping.dump();
@@ -1958,10 +1960,10 @@ void RegisterAllocator::dump(IR::Function *function) const
// References:
// [Wimmer1] C. Wimmer and M. Franz. Linear Scan Register Allocation on SSA Form. In Proceedings of
-// CGO’10, ACM Press, 2010
+// CGO'10, ACM Press, 2010
// [Wimmer2] C. Wimmer and H. Mossenbock. Optimized Interval Splitting in a Linear Scan Register
// Allocator. In Proceedings of the ACM/USENIX International Conference on Virtual
-// Execution Environments, pages 132–141. ACM Press, 2005.
+// Execution Environments, pages 132-141. ACM Press, 2005.
// [Traub] Omri Traub, Glenn Holloway, and Michael D. Smith. Quality and Speed in Linear-scan
// Register Allocation. In Proceedings of the ACM SIGPLAN 1998 Conference on Programming
-// Language Design and Implementation, pages 142–151, June 1998.
+// Language Design and Implementation, pages 142-151, June 1998.
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index 4404a5d79f..e4c150057a 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -525,7 +525,7 @@ QJSValue QJSEngine::newQObject(QObject *object)
\since 5.8
Creates a JavaScript object that wraps the given QMetaObject
- The metaObject must outlive the script engine. It is recommended to only
+ The \a metaObject must outlive the script engine. It is recommended to only
use this method with static metaobjects.
diff --git a/src/qml/jsruntime/qv4debugging_p.h b/src/qml/jsruntime/qv4debugging_p.h
index 3b589a41f1..8e2eec03d2 100644
--- a/src/qml/jsruntime/qv4debugging_p.h
+++ b/src/qml/jsruntime/qv4debugging_p.h
@@ -61,8 +61,9 @@ namespace Debugging {
#ifdef QT_NO_QML_DEBUGGER
-struct Debugger
+class Debugger
{
+public:
bool pauseAtNextOpportunity() const { return false; }
void maybeBreakAtInstruction() {}
void enteringFunction() {}
diff --git a/src/qml/jsruntime/qv4profiling_p.h b/src/qml/jsruntime/qv4profiling_p.h
index f75ac4d33a..9de597ad0e 100644
--- a/src/qml/jsruntime/qv4profiling_p.h
+++ b/src/qml/jsruntime/qv4profiling_p.h
@@ -67,7 +67,7 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
namespace Profiling {
-struct Profiler {};
+class Profiler {};
}
}
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 9e6d046485..86ad84b9c1 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -1039,7 +1039,7 @@ QQmlEngine::~QQmlEngine()
/*! \fn void QQmlEngine::exit(int retCode)
This signal is emitted when the QML loaded by the engine would like to exit
- from the event loop with the specified return code.
+ from the event loop with the specified return code \a retCode.
\since 5.8
\sa quit()
diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp
index 1e1fbcf448..b70db5ed86 100644
--- a/src/qml/qml/qqmlexpression.cpp
+++ b/src/qml/qml/qqmlexpression.cpp
@@ -202,6 +202,7 @@ QQmlExpression::QQmlExpression(QQmlContextData *ctxt, QObject *scope,
*/
QQmlExpression::~QQmlExpression()
{
+ clearError();
}
/*!
diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp
index edd93ef03d..2c71293363 100644
--- a/src/qml/qml/qqmllist.cpp
+++ b/src/qml/qml/qqmllist.cpp
@@ -394,8 +394,9 @@ can be very useful while prototyping.
\fn QQmlListProperty::QQmlListProperty(QObject *object, void *data,
CountFunction count, AtFunction at)
-Construct a readonly QQmlListProperty from a set of operation functions. An opaque \a data handle
-may be passed which can be accessed from within the operation functions. The list property
+Construct a readonly QQmlListProperty from a set of operation functions
+\a count and \a at. An opaque \a data handle may be passed which can be
+accessed from within the operation functions. The list property
remains valid while \a object exists.
*/
@@ -404,8 +405,9 @@ remains valid while \a object exists.
CountFunction count, AtFunction at,
ClearFunction clear)
-Construct a QQmlListProperty from a set of operation functions. An opaque \a data handle
-may be passed which can be accessed from within the operation functions. The list property
+Construct a QQmlListProperty from a set of operation functions \a append,
+\a count, \a at, and \a clear. An opaque \a data handle may be passed which
+can be accessed from within the operation functions. The list property
remains valid while \a object exists.
Null pointers can be passed for any function. If any null pointers are passed in, the list
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index df336f0803..ca522c29af 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -789,12 +789,12 @@ void QQmlPropertyPrivate::removeBinding(const QQmlProperty &that)
QQmlAbstractBinding *
QQmlPropertyPrivate::binding(QObject *object, QQmlPropertyIndex index)
{
+ findAliasTarget(object, index, &object, &index);
+
QQmlData *data = QQmlData::get(object);
if (!data)
return 0;
- findAliasTarget(object, index, &object, &index);
-
const int coreIndex = index.coreIndex();
const int valueTypeIndex = index.valueTypeIndex();
@@ -1399,9 +1399,9 @@ QQmlMetaObject QQmlPropertyPrivate::rawMetaObjectForType(QQmlEnginePrivate *engi
}
/*!
- Sets the property value to \a value and returns true.
- Returns false if the property can't be set because the
- \a value is the wrong type, for example.
+ Sets the property value to \a value. Returns \c true on success, or
+ \c false if the property can't be set because the \a value is the
+ wrong type, for example.
*/
bool QQmlProperty::write(const QVariant &value) const
{
@@ -1416,6 +1416,8 @@ bool QQmlProperty::write(const QVariant &value) const
QQmlProperty p(object, name);
p.write(value);
\endcode
+
+ Returns \c true on success, \c false otherwise.
*/
bool QQmlProperty::write(QObject *object, const QString &name, const QVariant &value)
{
@@ -1432,6 +1434,8 @@ bool QQmlProperty::write(QObject *object, const QString &name, const QVariant &v
QQmlProperty p(object, name, ctxt);
p.write(value);
\endcode
+
+ Returns \c true on success, \c false otherwise.
*/
bool QQmlProperty::write(QObject *object,
const QString &name,
@@ -1452,6 +1456,8 @@ bool QQmlProperty::write(QObject *object,
QQmlProperty p(object, name, engine);
p.write(value);
\endcode
+
+ Returns \c true on success, \c false otherwise.
*/
bool QQmlProperty::write(QObject *object, const QString &name, const QVariant &value,
QQmlEngine *engine)
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index fd1e9cc2be..be4ab68831 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -129,15 +129,20 @@ ReturnedValue QmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, Q
return w.asReturnedValue();
}
-static int enumForSingleton(String *name, QObject *qobjectSingleton)
+static int enumForSingleton(QV4::ExecutionEngine *v4, String *name, QObject *qobjectSingleton,
+ QQmlType *type)
{
+ bool ok;
+ int value = type->enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, &ok);
+ if (ok)
+ return value;
+
// ### Optimize
QByteArray enumName = name->toQString().toUtf8();
const QMetaObject *metaObject = qobjectSingleton->metaObject();
for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) {
QMetaEnum e = metaObject->enumerator(ii);
- bool ok;
- int value = e.keyToValue(enumName.constData(), &ok);
+ value = e.keyToValue(enumName.constData(), &ok);
if (ok)
return value;
}
@@ -183,7 +188,7 @@ ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasPrope
// check for enum value
const bool includeEnums = w->d()->mode == Heap::QmlTypeWrapper::IncludeEnums;
if (includeEnums && name->startsWithUpper()) {
- const int value = enumForSingleton(name, qobjectSingleton);
+ const int value = enumForSingleton(v4, name, qobjectSingleton, type);
if (value != -1)
return QV4::Primitive::fromInt32(value).asReturnedValue();
}
@@ -196,7 +201,7 @@ ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasPrope
// Warn when attempting to access a lowercased enum value, singleton case
if (!ok && includeEnums && !name->startsWithUpper()) {
- const int value = enumForSingleton(name, qobjectSingleton);
+ const int value = enumForSingleton(v4, name, qobjectSingleton, type);
if (value != -1)
return throwLowercaseEnumError(v4, name, type);
}
diff --git a/src/quick/accessible/qaccessiblequickview.cpp b/src/quick/accessible/qaccessiblequickview.cpp
index 222690e4f2..b3d1b6fc0f 100644
--- a/src/quick/accessible/qaccessiblequickview.cpp
+++ b/src/quick/accessible/qaccessiblequickview.cpp
@@ -81,6 +81,14 @@ QAccessibleInterface *QAccessibleQuickWindow::child(int index) const
return 0;
}
+QAccessibleInterface *QAccessibleQuickWindow::focusChild() const
+{
+ QObject *focusObject = window()->focusObject();
+ if (focusObject)
+ return QAccessible::queryAccessibleInterface(focusObject);
+ return nullptr;
+}
+
QAccessible::Role QAccessibleQuickWindow::role() const
{
return QAccessible::Window; // FIXME
diff --git a/src/quick/accessible/qaccessiblequickview_p.h b/src/quick/accessible/qaccessiblequickview_p.h
index 7c103380cb..39ffcaf39c 100644
--- a/src/quick/accessible/qaccessiblequickview_p.h
+++ b/src/quick/accessible/qaccessiblequickview_p.h
@@ -65,6 +65,7 @@ public:
QAccessibleInterface *parent() const override;
QAccessibleInterface *child(int index) const override;
+ QAccessibleInterface *focusChild() const override;
QAccessible::Role role() const override;
QAccessible::State state() const override;
diff --git a/src/quick/doc/snippets/qml/localstorage/hello.qml b/src/quick/doc/snippets/qml/localstorage/hello.qml
new file mode 100644
index 0000000000..959895c82a
--- /dev/null
+++ b/src/quick/doc/snippets/qml/localstorage/hello.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//![0]
+import QtQuick 2.0
+
+Rectangle {
+ color: "white"
+ width: 200
+ height: 100
+
+ Text {
+ text: "?"
+ anchors.horizontalCenter: parent.horizontalCenter
+ function findGreetings() {
+ var db = openDatabaseSync("QDeclarativeExampleDB", "1.0", "The Example QML SQL!", 1000000);
+
+ db.transaction(
+ function(tx) {
+ // Create the database if it doesn't already exist
+ tx.executeSql('CREATE TABLE IF NOT EXISTS Greeting(salutation TEXT, salutee TEXT)');
+
+ // Add (another) greeting row
+ tx.executeSql('INSERT INTO Greeting VALUES(?, ?)', [ 'hello', 'world' ]);
+
+ // Show all added greetings
+ var rs = tx.executeSql('SELECT * FROM Greeting');
+
+ var r = ""
+ for (var i = 0; i < rs.rows.length; i++) {
+ r += rs.rows.item(i).salutation + ", " + rs.rows.item(i).salutee + "\n"
+ }
+ text = r
+ }
+ )
+ }
+ Component.onCompleted: findGreetings()
+ }
+}
+//![0]
diff --git a/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc b/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc
index 20a6d131f5..e5834eb5c8 100644
--- a/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc
+++ b/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc
@@ -64,7 +64,7 @@
In addition to the above features, GridLayout adds these features:
\list
\li \l{Layout::row}{Grid coordinates} can be specified with the \l{Layout::row}{Layout.row} and
- \l{Layout::column}{Layout.column}.
+ \l{Layout::column}{Layout.column} properties.
\li \l{GridLayout::flow}{Automatic grid coordinates} used together with the
\l{GridLayout::flow}{flow}, \l{GridLayout::rows}{rows}, and
\l{GridLayout::columns}{columns} properties.
diff --git a/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc b/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc
index a764402c2f..12a107491a 100644
--- a/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc
+++ b/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc
@@ -36,10 +36,10 @@
Models can be defined in C++ and then made available to QML. This is useful
for exposing existing C++ data models or otherwise complex datasets to QML.
-A C++ model class can be defined as a \l QStringList, a QObjectList or a
-\l QAbstractItemModel. The first two are useful for exposing simpler datasets,
-while QAbstractItemModel provides a more flexible solution for more complex
-models.
+A C++ model class can be defined as a \l QStringList, a \l QVariantList, a
+QObjectList or a \l QAbstractItemModel. The first three are useful for exposing
+simpler datasets, while QAbstractItemModel provides a more flexible solution for
+more complex models.
\section2 QStringList-based Model
@@ -60,10 +60,20 @@ The complete source code for this example is available in
\l {models/stringlistmodel}{examples/quick/models/stringlistmodel}
within the Qt install directory.
-\b{Note:} There is no way for the view to know that the contents of a QStringList
-have changed. If the QStringList changes, it will be necessary to reset
+\note There is no way for the view to know that the contents of a QStringList
+have changed. If the QStringList changes, it will be necessary to reset
the model by calling QQmlContext::setContextProperty() again.
+\section2 QVariantList-based Model
+
+A model may be a single \l QVariantList, which provides the contents of the list
+via the \e modelData role.
+
+The API works just like with \l QStringList, as shown in the previous section.
+
+\note There is no way for the view to know that the contents of a QVariantList
+have changed. If the QVariantList changes, it will be necessary to reset
+the model.
\section2 QObjectList-based model
diff --git a/src/quick/doc/src/concepts/positioning/topic.qdoc b/src/quick/doc/src/concepts/positioning/topic.qdoc
index 92113ece54..b28acd1f89 100644
--- a/src/quick/doc/src/concepts/positioning/topic.qdoc
+++ b/src/quick/doc/src/concepts/positioning/topic.qdoc
@@ -112,7 +112,7 @@ them, and where possible, pristine Anchor layouts should be preferred.
\section1 Anchors
-Anchors allows an item to be placed either adjacent to or inside of another,
+Anchors allow an item to be placed either adjacent to or inside of another,
by attaching one or more of the item's anchor-points (boundaries) to an
anchor-point of the other. These anchors will remain even if the dimensions
or location of one of the items changes, allowing for highly dynamic
diff --git a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
index 3fd92177f9..d80c72e0f1 100644
--- a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
+++ b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
@@ -31,18 +31,14 @@
\section1 Scene Graph Adaptations in Qt Quick
-Originally Qt Quick only had one available renderer for parsing the scene graph
-and rendering the results to a render target. This renderer is now the default
-OpenGL Renderer which supports rendering either using the OpenGL ES 2.0 or
-OpenGL 2.0 (with framebuffer object extensions) APIs. The Qt Quick APIs have
-originally been designed with the assumption that OpenGL is always available.
-However, it is now possible to use other graphics API's to render Qt Quick
-scenes using the scene graph APIs.
+Originally Qt Quick always relied on OpenGL (OpenGL ES 2.0 or OpenGL 2.0) for parsing
+the scene graph and rendering the results to a render target. From Qt 5.8 onwards
+Qt Quick also supports rendering in software and with Direct3D 12.
\section1 Switching between the adaptation used by the application
-The default of the OpenGL, or - in Qt builds with disabled OpenGL support - the
-software adaptation, can be overridden either by using an environment variable
+The default rendering backend is still OpenGL, or - in Qt builds with disabled OpenGL support -
+the software renderer. This can be overridden either by using an environment variable
or a C++ API. The former consists of setting the \c{QT_QUICK_BACKEND} or the
legacy \c{QMLSCENE_DEVICE} environment variable before launching applications.
The latter is done by calling QQuickWindow::setSceneGraphBackend() early in the
diff --git a/src/quick/doc/src/concepts/visualcanvas/visualparent.qdoc b/src/quick/doc/src/concepts/visualcanvas/visualparent.qdoc
index fd5bf51307..f971043b58 100644
--- a/src/quick/doc/src/concepts/visualcanvas/visualparent.qdoc
+++ b/src/quick/doc/src/concepts/visualcanvas/visualparent.qdoc
@@ -125,7 +125,7 @@ the blue rectangle and beneath any of the blue rectangle's children.
Stacking order can be influenced with the \l Item::z property. Z values below 0 will stack below the parent, and if z
values are assigned then siblings will stack in z-order (with creation order used to break ties). Z values only affect
-stacking compared to siblings and the parent item. If you have an item who is obscured by a subtree rooted above its
+stacking compared to siblings and the parent item. If you have an item which is obscured by a subtree rooted above its
parent item, no z value on that item will increase its stacking order to stack above that subtree. To stack that item
above the other subtree you'll have to alter z values farther up in the hierarchy, or re-arrange the visual item
hierarchy.
diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp
index 38b5f054bf..d90f527486 100644
--- a/src/quick/items/context2d/qquickcontext2dtexture.cpp
+++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp
@@ -48,6 +48,7 @@
#include <QOpenGLFramebufferObject>
#include <QOpenGLFramebufferObjectFormat>
#include <QOpenGLFunctions>
+#include <QtGui/private/qopenglextensions_p.h>
#endif
#include <QtCore/QThread>
#include <QtGui/QGuiApplication>
@@ -499,9 +500,9 @@ bool QQuickContext2DFBOTexture::doMultisampling() const
static bool multisamplingSupported = false;
if (!extensionsChecked) {
- const QSet<QByteArray> extensions = QOpenGLContext::currentContext()->extensions();
- multisamplingSupported = extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_multisample"))
- && extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_blit"));
+ QOpenGLExtensions *e = static_cast<QOpenGLExtensions *>(QOpenGLContext::currentContext()->functions());
+ multisamplingSupported = e->hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)
+ && e->hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit);
extensionsChecked = true;
}
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 4ab604b30f..d97c731157 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -2349,8 +2349,11 @@ bool QQuickFlickable::filterMouseEvent(QQuickItem *receiver, QMouseEvent *event)
bool QQuickFlickable::childMouseEventFilter(QQuickItem *i, QEvent *e)
{
Q_D(QQuickFlickable);
- if (!isVisible() || !isEnabled() || !isInteractive())
+ if (!isVisible() || !isEnabled() || !isInteractive()) {
+ d->cancelInteraction();
return QQuickItem::childMouseEventFilter(i, e);
+ }
+
switch (e->type()) {
case QEvent::MouseButtonPress:
case QEvent::MouseMove:
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index f7b9a58329..1a244b0dd9 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2911,14 +2911,15 @@ void QQuickItemPrivate::addChild(QQuickItem *child)
childItems.append(child);
-#if QT_CONFIG(cursor)
QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
+#if QT_CONFIG(cursor)
// if the added child has a cursor and we do not currently have any children
// with cursors, bubble the notification up
if (childPrivate->subtreeCursorEnabled && !subtreeCursorEnabled)
setHasCursorInChild(true);
#endif
+
if (childPrivate->subtreeHoverEnabled && !subtreeHoverEnabled)
setHasHoverInChild(true);
@@ -2939,13 +2940,14 @@ void QQuickItemPrivate::removeChild(QQuickItem *child)
childItems.removeOne(child);
Q_ASSERT(!childItems.contains(child));
-#if QT_CONFIG(cursor)
QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
+#if QT_CONFIG(cursor)
// turn it off, if nothing else is using it
if (childPrivate->subtreeCursorEnabled && subtreeCursorEnabled)
setHasCursorInChild(false);
#endif
+
if (childPrivate->subtreeHoverEnabled && subtreeHoverEnabled)
setHasHoverInChild(false);
@@ -3807,10 +3809,10 @@ QQuickItem::UpdatePaintNodeData::UpdatePaintNodeData()
/*!
This function is called when an item should release graphics
- resources which are not already managed by the nodes returend from
+ resources which are not already managed by the nodes returned from
QQuickItem::updatePaintNode().
- This happens when the item is about to be removed from window it
+ This happens when the item is about to be removed from the window it
was previously rendering to. The item is guaranteed to have a
\l {QQuickItem::window()}{window} when the function is called.
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index bb23b1fd54..c662efe40e 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -689,9 +689,10 @@ void QQuickMouseArea::mousePressEvent(QMouseEvent *event)
#endif
setHovered(true);
d->startScene = event->windowPos();
- d->pressAndHoldTimer.start(pressAndHoldInterval(), this);
setKeepMouseGrab(d->stealMouse);
event->setAccepted(setPressed(event->button(), true, event->source()));
+ if (event->isAccepted())
+ d->pressAndHoldTimer.start(pressAndHoldInterval(), this);
}
}
@@ -738,23 +739,34 @@ void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event)
bool dragY = drag()->axis() & QQuickDrag::YAxis;
QPointF dragPos = d->drag->target()->position();
+ QPointF boundedDragPos = dragPos;
if (dragX) {
- dragPos.setX(qBound(
+ dragPos.setX(startPos.x() + curLocalPos.x() - startLocalPos.x());
+ boundedDragPos.setX(qBound(
d->drag->xmin(),
- startPos.x() + curLocalPos.x() - startLocalPos.x(),
+ dragPos.x(),
d->drag->xmax()));
}
if (dragY) {
- dragPos.setY(qBound(
+ dragPos.setY(startPos.y() + curLocalPos.y() - startLocalPos.y());
+ boundedDragPos.setY(qBound(
d->drag->ymin(),
- startPos.y() + curLocalPos.y() - startLocalPos.y(),
+ dragPos.y(),
d->drag->ymax()));
}
+
+ QPointF targetPos = d->drag->target()->position();
+
if (d->drag->active())
- d->drag->target()->setPosition(dragPos);
+ d->drag->target()->setPosition(boundedDragPos);
+
+ bool dragOverThresholdX = QQuickWindowPrivate::dragOverThreshold(dragPos.x() - startPos.x(),
+ Qt::XAxis, event, d->drag->threshold());
+ bool dragOverThresholdY = QQuickWindowPrivate::dragOverThreshold(dragPos.y() - startPos.y(),
+ Qt::YAxis, event, d->drag->threshold());
- if (!d->overThreshold && (QQuickWindowPrivate::dragOverThreshold(dragPos.x() - startPos.x(), Qt::XAxis, event, d->drag->threshold())
- || QQuickWindowPrivate::dragOverThreshold(dragPos.y() - startPos.y(), Qt::YAxis, event, d->drag->threshold())))
+ if (!d->overThreshold && (((targetPos.x() != boundedDragPos.x()) && dragOverThresholdX) ||
+ ((targetPos.y() != boundedDragPos.y()) && dragOverThresholdY)))
{
d->overThreshold = true;
if (d->drag->smoothed())
diff --git a/src/quick/items/qquickopenglshadereffect.cpp b/src/quick/items/qquickopenglshadereffect.cpp
index 42fcee3c0d..4f4c403483 100644
--- a/src/quick/items/qquickopenglshadereffect.cpp
+++ b/src/quick/items/qquickopenglshadereffect.cpp
@@ -256,10 +256,14 @@ void QQuickOpenGLShaderEffectCommon::connectPropertySignals(QQuickItem *item,
qWarning("QQuickOpenGLShaderEffect: property '%s' does not have notification method!", d.name.constData());
} else {
auto *mapper = signalMappers[shaderType].at(i);
- mapper->setSignalIndex(pd->notifyIndex());
+ mapper->setSignalIndex(itemMetaObject->property(d.propertyIndex).notifySignal().methodIndex());
Q_ASSERT(item->metaObject() == itemMetaObject);
- QObjectPrivate::connectImpl(item, mapper->signalIndex(), item, nullptr, mapper,
- Qt::AutoConnection, nullptr, itemMetaObject);
+ bool ok = QObjectPrivate::connectImpl(item, pd->notifyIndex(), item, nullptr, mapper,
+ Qt::AutoConnection, nullptr, itemMetaObject);
+ if (!ok)
+ qWarning() << "Failed to connect to property" << itemMetaObject->property(d.propertyIndex).name()
+ << "(" << d.propertyIndex << ", signal index" << pd->notifyIndex()
+ << ") of item" << item;
}
} else {
// If the source is set via a dynamic property, like the layer is, then we need this
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp
index 7926607e33..436d7b33ce 100644
--- a/src/quick/items/qquickshadereffect.cpp
+++ b/src/quick/items/qquickshadereffect.cpp
@@ -873,4 +873,9 @@ void QQuickShaderEffectPrivate::updatePolish()
q->m_impl->maybeUpdateShaders();
}
+bool QQuickShaderEffect::isOpenGLShaderEffect() const
+{
+ return m_glImpl != Q_NULLPTR;
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h
index 7885daffbb..d269dc5e50 100644
--- a/src/quick/items/qquickshadereffect_p.h
+++ b/src/quick/items/qquickshadereffect_p.h
@@ -117,6 +117,8 @@ public:
bool isComponentComplete() const;
QString parseLog();
+ bool isOpenGLShaderEffect() const;
+
Q_SIGNALS:
void fragmentShaderChanged();
void vertexShaderChanged();
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 57810e4ec9..f90384b3b6 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -635,8 +635,8 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
// FIXME: make this work for mouse events too and get rid of the asTouchEvent in here.
Q_ASSERT(pointerEvent->asPointerTouchEvent());
- QTouchEvent *event = pointerEvent->asPointerTouchEvent()->touchEventForItem(item);
- if (!event)
+ QScopedPointer<QTouchEvent> event(pointerEvent->asPointerTouchEvent()->touchEventForItem(item));
+ if (event.isNull())
return false;
// For each point, check if it is accepted, if not, try the next point.
@@ -653,7 +653,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
break;
qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << p.id() << "->" << item;
- QScopedPointer<QMouseEvent> mousePress(touchToMouseEvent(QEvent::MouseButtonPress, p, event, item, false));
+ QScopedPointer<QMouseEvent> mousePress(touchToMouseEvent(QEvent::MouseButtonPress, p, event.data(), item, false));
// Send a single press and see if that's accepted
QCoreApplication::sendEvent(item, mousePress.data());
@@ -667,7 +667,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
pointerEventPoint->setGrabber(item);
if (checkIfDoubleClicked(event->timestamp())) {
- QScopedPointer<QMouseEvent> mouseDoubleClick(touchToMouseEvent(QEvent::MouseButtonDblClick, p, event, item, false));
+ QScopedPointer<QMouseEvent> mouseDoubleClick(touchToMouseEvent(QEvent::MouseButtonDblClick, p, event.data(), item, false));
QCoreApplication::sendEvent(item, mouseDoubleClick.data());
event->setAccepted(mouseDoubleClick->isAccepted());
if (!mouseDoubleClick->isAccepted()) {
@@ -684,7 +684,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
} else if (touchMouseDevice == device && p.id() == touchMouseId) {
if (p.state() & Qt::TouchPointMoved) {
if (QQuickItem *mouseGrabberItem = q->mouseGrabberItem()) {
- QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseMove, p, event, mouseGrabberItem, false));
+ QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseMove, p, event.data(), mouseGrabberItem, false));
QCoreApplication::sendEvent(item, me.data());
event->setAccepted(me->isAccepted());
if (me->isAccepted()) {
@@ -695,7 +695,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
// no grabber, check if we care about mouse hover
// FIXME: this should only happen once, not recursively... I'll ignore it just ignore hover now.
// hover for touch???
- QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseMove, p, event, item, false));
+ QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseMove, p, event.data(), item, false));
if (lastMousePosition.isNull())
lastMousePosition = me->windowPos();
QPointF last = lastMousePosition;
@@ -713,7 +713,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
} else if (p.state() & Qt::TouchPointReleased) {
// currently handled point was released
if (QQuickItem *mouseGrabberItem = q->mouseGrabberItem()) {
- QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseButtonRelease, p, event, mouseGrabberItem, false));
+ QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseButtonRelease, p, event.data(), mouseGrabberItem, false));
QCoreApplication::sendEvent(item, me.data());
if (item->acceptHoverEvents() && p.screenPos() != QGuiApplicationPrivate::lastCursorPosition) {
@@ -4495,8 +4495,8 @@ QSGRendererInterface *QQuickWindow::rendererInterface() const
\note The call to the function must happen before constructing the first
QQuickWindow in the application. It cannot be changed afterwards.
- If \a backend is invalid or an error occurs, the default backend (OpenGL or
- software, depending on the Qt configuration) is used.
+ If the selected backend is invalid or an error occurs, the default backend
+ (OpenGL or software, depending on the Qt configuration) is used.
\since 5.8
*/
diff --git a/src/quick/scenegraph/qsgdefaultlayer.cpp b/src/quick/scenegraph/qsgdefaultlayer.cpp
index ad5b57ff83..78037a2fde 100644
--- a/src/quick/scenegraph/qsgdefaultlayer.cpp
+++ b/src/quick/scenegraph/qsgdefaultlayer.cpp
@@ -44,6 +44,7 @@
#include <QtGui/QOpenGLFramebufferObject>
#include <QtGui/QOpenGLFunctions>
+#include <QtGui/private/qopenglextensions_p.h>
#include <QtQuick/private/qsgdepthstencilbuffer_p.h>
@@ -320,9 +321,9 @@ void QSGDefaultLayer::grab()
if (m_context->openglContext()->format().samples() <= 1) {
m_multisampling = false;
} else {
- const QSet<QByteArray> extensions = m_context->openglContext()->extensions();
- m_multisampling = extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_multisample"))
- && extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_blit"));
+ QOpenGLExtensions *e = static_cast<QOpenGLExtensions *>(funcs);
+ m_multisampling = e->hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)
+ && e->hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit);
}
m_multisamplingChecked = true;
}
diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp
index 389b9e0b4e..9ffd1b4b08 100644
--- a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp
+++ b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp
@@ -238,9 +238,9 @@ void QSGDefaultPainterNode::updateGeometry()
void QSGDefaultPainterNode::updateRenderTarget()
{
if (!m_extensionsChecked) {
- const QSet<QByteArray> extensions = m_context->openglContext()->extensions();
- m_multisamplingSupported = extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_multisample"))
- && extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_blit"));
+ QOpenGLExtensions *e = static_cast<QOpenGLExtensions *>(QOpenGLContext::currentContext()->functions());
+ m_multisamplingSupported = e->hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)
+ && e->hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit);
m_extensionsChecked = true;
}
diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp
index 5dd16407b8..4aacb09c97 100644
--- a/src/quick/util/qquickanimatorjob.cpp
+++ b/src/quick/util/qquickanimatorjob.cpp
@@ -47,6 +47,7 @@
#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl)
# include <private/qquickopenglshadereffectnode_p.h>
# include <private/qquickopenglshadereffect_p.h>
+# include <private/qquickshadereffect_p.h>
#endif
#include <private/qanimationgroupjob_p.h>
@@ -625,7 +626,8 @@ QQuickUniformAnimatorJob::QQuickUniformAnimatorJob()
void QQuickUniformAnimatorJob::setTarget(QQuickItem *target)
{
- if (qobject_cast<QQuickOpenGLShaderEffect *>(target) != nullptr)
+ QQuickShaderEffect* effect = qobject_cast<QQuickShaderEffect*>(target);
+ if (effect && effect->isOpenGLShaderEffect())
m_target = target;
}
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp
index 7788635e3e..a026abe762 100644
--- a/src/quick/util/qquickimageprovider.cpp
+++ b/src/quick/util/qquickimageprovider.cpp
@@ -151,6 +151,8 @@ QQuickTextureFactory *QQuickTextureFactory::textureFactoryForImage(const QImage
If you are using QRunnable as base for your QQuickImageResponse
ensure automatic deletion is disabled.
+ See the \l {imageresponseprovider}{Image Response Provider Example} for a complete implementation.
+
\sa QQuickImageProvider
*/
@@ -466,6 +468,8 @@ QQuickTextureFactory *QQuickImageProvider::requestTexture(const QString &id, QSi
\inmodule QtQuick
\brief The QQuickAsyncImageProvider class provides an interface for for asynchronous control of QML image requests.
+ See the \l {imageresponseprovider}{Image Response Provider Example} for a complete implementation.
+
\sa QQuickImageProvider
*/
QQuickAsyncImageProvider::QQuickAsyncImageProvider()
diff --git a/src/src.pro b/src/src.pro
index c2a58c3757..4e2de8da14 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -5,7 +5,7 @@ QT_FOR_CONFIG += network quick-private
SUBDIRS += \
qml
-qtHaveModule(gui) {
+qtHaveModule(gui):qtConfig(animation) {
SUBDIRS += \
quick \
qmltest