aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2019-03-13 10:48:24 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2019-03-13 10:48:24 +0000
commit44fbf97533e297b0871150b7b8689fe7a641ad51 (patch)
tree3fa693a3c98c50df0f277377a96e39c5d86e002b /src
parentca66d4fc23706a0f4ecfc4031f37cdd19facd836 (diff)
parent76be4abbbcfb2fbb14ce532413e0895198e7f0f1 (diff)
Merge "Merge remote-tracking branch 'origin/5.12' into 5.13" into refs/staging/5.13
Diffstat (limited to 'src')
-rw-r--r--src/imports/testlib/toucheventsequence.qdoc2
-rw-r--r--src/qml/animations/qanimationgroupjob.cpp10
-rw-r--r--src/qml/animations/qsequentialanimationgroupjob.cpp4
-rw-r--r--src/qml/compiler/qv4codegen.cpp31
-rw-r--r--src/qml/doc/src/cppintegration/definetypes.qdoc2
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/signals.qdoc32
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp38
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp21
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp8
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp21
-rw-r--r--src/qmltest/doc/src/qtquicktest-index.qdoc2
-rw-r--r--src/qmltest/quicktestevent.cpp4
-rw-r--r--src/quick/handlers/qquickpointhandler.cpp4
-rw-r--r--src/quick/handlers/qquicktaphandler.cpp19
-rw-r--r--src/quick/items/qquickevents.cpp7
-rw-r--r--src/quick/items/qquickflickable.cpp4
-rw-r--r--src/quick/items/qquickitemgrabresult.cpp6
-rw-r--r--src/quick/items/qquicktableview.cpp15
-rw-r--r--src/quick/items/qquicktext.cpp4
-rw-r--r--src/quick/items/qquicktextnodeengine.cpp18
-rw-r--r--src/quick/items/qquickwindow.cpp30
-rw-r--r--src/quickshapes/qquickshape.cpp5
22 files changed, 141 insertions, 146 deletions
diff --git a/src/imports/testlib/toucheventsequence.qdoc b/src/imports/testlib/toucheventsequence.qdoc
index 6f1f3f8863..bd3551a669 100644
--- a/src/imports/testlib/toucheventsequence.qdoc
+++ b/src/imports/testlib/toucheventsequence.qdoc
@@ -51,7 +51,7 @@
Events are delivered to the window which contains the item specified in touchEvent.
- \sa TestCase::touchEvent(), QTest::QTouchEventSequence
+ \sa TestCase::touchEvent()
*/
/*!
diff --git a/src/qml/animations/qanimationgroupjob.cpp b/src/qml/animations/qanimationgroupjob.cpp
index 344791fd83..66599561fc 100644
--- a/src/qml/animations/qanimationgroupjob.cpp
+++ b/src/qml/animations/qanimationgroupjob.cpp
@@ -120,13 +120,9 @@ void QAnimationGroupJob::removeAnimation(QAbstractAnimationJob *animation)
void QAnimationGroupJob::clear()
{
- QAbstractAnimationJob *child = firstChild();
- QAbstractAnimationJob *nextSibling = nullptr;
- while (child != nullptr) {
- child->m_group = nullptr;
- nextSibling = child->nextSibling();
- delete child;
- child = nextSibling;
+ while (QAbstractAnimationJob *child = firstChild()) {
+ removeAnimation(child);
+ delete child;
}
m_firstChild = nullptr;
m_lastChild = nullptr;
diff --git a/src/qml/animations/qsequentialanimationgroupjob.cpp b/src/qml/animations/qsequentialanimationgroupjob.cpp
index 0595141d60..d98546122f 100644
--- a/src/qml/animations/qsequentialanimationgroupjob.cpp
+++ b/src/qml/animations/qsequentialanimationgroupjob.cpp
@@ -206,9 +206,11 @@ int QSequentialAnimationGroupJob::duration() const
void QSequentialAnimationGroupJob::clear()
{
- m_currentAnimation = nullptr;
m_previousLoop = 0;
QAnimationGroupJob::clear();
+
+ // clear() should call removeAnimation(), which will clear m_currentAnimation, eventually.
+ Q_ASSERT(m_currentAnimation == nullptr);
}
void QSequentialAnimationGroupJob::updateCurrentTime(int currentTime)
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 17869bcc84..ac763e592f 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -727,9 +727,6 @@ void Codegen::destructureElementList(const Codegen::Reference &array, PatternEle
bytecodeGenerator->addInstruction(iteratorObjInstr);
iterator.storeConsumeAccumulator();
- bool hasRest = false;
-
- BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
{
auto cleanup = [this, iterator, iteratorDone]() {
iterator.loadInAccumulator();
@@ -760,27 +757,17 @@ void Codegen::destructureElementList(const Codegen::Reference &array, PatternEle
Reference::fromConst(this, Encode(true)).storeOnStack(iteratorDone.stackSlot());
bytecodeGenerator->addInstruction(Instruction::DestructureRestElement());
initializeAndDestructureBindingElement(e, Reference::fromAccumulator(this), isDefinition);
- hasRest = true;
} else {
Instruction::IteratorNext next;
next.value = iteratorValue.stackSlot();
next.done = iteratorDone.stackSlot();
bytecodeGenerator->addInstruction(next);
initializeAndDestructureBindingElement(e, iteratorValue, isDefinition);
- if (hasError) {
- end.link();
+ if (hasError)
return;
- }
}
}
-
- if (hasRest)
- // no need to close the iterator
- bytecodeGenerator->jump().link(end);
}
-
-
- end.link();
}
void Codegen::destructurePattern(Pattern *p, const Reference &rhs)
@@ -1220,7 +1207,6 @@ bool Codegen::visit(ArrayPattern *ast)
BytecodeGenerator::Label in = bytecodeGenerator->newLabel();
BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
- BytecodeGenerator::Label done = bytecodeGenerator->newLabel();
{
auto cleanup = [this, iterator, iteratorDone]() {
@@ -1230,12 +1216,6 @@ bool Codegen::visit(ArrayPattern *ast)
bytecodeGenerator->addInstruction(close);
};
ControlFlowLoop flow(this, &end, &in, cleanup);
- bytecodeGenerator->jump().link(in);
-
- BytecodeGenerator::Label body = bytecodeGenerator->label();
-
- lhsValue.loadInAccumulator();
- pushAccumulator();
in.link();
iterator.loadInAccumulator();
@@ -1243,13 +1223,14 @@ bool Codegen::visit(ArrayPattern *ast)
next.value = lhsValue.stackSlot();
next.done = iteratorDone.stackSlot();
bytecodeGenerator->addInstruction(next);
- bytecodeGenerator->addTracingJumpInstruction(Instruction::JumpFalse()).link(body);
- bytecodeGenerator->jump().link(done);
+ bytecodeGenerator->addTracingJumpInstruction(Instruction::JumpTrue()).link(end);
+ lhsValue.loadInAccumulator();
+ pushAccumulator();
+
+ bytecodeGenerator->jump().link(in);
end.link();
}
-
- done.link();
} else {
RegisterScope innerScope(this);
Reference expr = expression(it->element->initializer);
diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc
index 0cce1895cb..f6f630c749 100644
--- a/src/qml/doc/src/cppintegration/definetypes.qdoc
+++ b/src/qml/doc/src/cppintegration/definetypes.qdoc
@@ -66,6 +66,8 @@ this manner, but the type cannot be used instantiated as a QML object type
from QML. This is useful, for example, if a type has enums that should be
exposed to QML but the type itself should not be instantiable.
+For a quick guide to choosing the correct approach to expose C++ types to QML,
+see \l {Choosing the Correct Integration Method Between C++ and QML}.
\section2 Registering an Instantiable Object Type
diff --git a/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc b/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc
index b643f18154..cd73ccc025 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc
@@ -59,9 +59,9 @@ receiving this signal should be \c onClicked. In the example below, whenever
the button is clicked, the \c onClicked handler is invoked, applying a random
color to the parent \l Rectangle:
-\qml
-import QtQuick 2.\QtMinorVersion
-import QtQuick.Controls 2.\QtMinorVersion
+\qml \QtMinorVersion
+import QtQuick 2.\1
+import QtQuick.Controls 2.\1
Rectangle {
id: rect
@@ -87,8 +87,8 @@ these signals are written in the form \e on<Property>Changed, where
For example, the \l MouseArea type has a \l {MouseArea::pressed}{pressed} property. To receive a notification whenever this property changes, write a signal handler named \c onPressedChanged:
-\qml
-import QtQuick 2.\QtMinorVersion
+\qml \QtMinorVersion
+import QtQuick 2.\1
Rectangle {
id: rect
@@ -116,9 +116,9 @@ received by the root \l Rectangle instead, by placing the \c onClicked handler
in a \l Connections object that has its \l {Connections::target}{target} set to
the \c button:
-\qml
-import QtQuick 2.\QtMinorVersion
-import QtQuick.Controls 2.\QtMinorVersion
+\qml \QtMinorVersion
+import QtQuick 2.\1
+import QtQuick.Controls 2.\1
Rectangle {
id: rect
@@ -151,8 +151,8 @@ For example, \l{Component::completed}{Component.onCompleted} is an attached
signal handler. It is often used to execute some JavaScript code when its
creation process is complete. Here is an example:
-\qml
-import QtQuick 2.\QtMinorVersion
+\qml \QtMinorVersion
+import QtQuick 2.\1
Rectangle {
width: 200; height: 200
@@ -195,9 +195,9 @@ root \l Rectangle object has an \c activated signal, which is emitted whenever t
child \l TapHandler is \c tapped. In this particular example the activated signal
is emitted with the x and y coordinates of the mouse click:
-\qml
+\qml \QtMinorVersion
// SquareButton.qml
-import QtQuick 2.\QtMinorVersion
+import QtQuick 2.\1
Rectangle {
id: root
@@ -237,8 +237,8 @@ signal to be received by a method instead of a signal handler.
Below, the \c messageReceived signal is connected to three methods using the \c connect() method:
-\qml
-import QtQuick 2.\QtMinorVersion
+\qml \QtMinorVersion
+import QtQuick 2.\1
Rectangle {
id: relay
@@ -289,8 +289,8 @@ Rectangle {
By connecting signals to other signals, the \c connect() method can form different
signal chains.
-\qml
-import QtQuick 2.\QtMinorVersion
+\qml \QtMinorVersion
+import QtQuick 2.\1
Rectangle {
id: forwarder
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index d26e888069..13f6912371 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -223,41 +223,9 @@ ReturnedValue NumberPrototype::method_toString(const FunctionObject *b, const Va
return v4->throwError(QStringLiteral("Number.prototype.toString: %0 is not a valid radix").arg(radix));
}
- if (std::isnan(num)) {
- return Encode(v4->newString(QStringLiteral("NaN")));
- } else if (qt_is_inf(num)) {
- return Encode(v4->newString(QLatin1String(num < 0 ? "-Infinity" : "Infinity")));
- }
-
- if (radix != 10) {
- QString str;
- bool negative = false;
- if (num < 0) {
- negative = true;
- num = -num;
- }
- double frac = num - std::floor(num);
- num = Value::toInteger(num);
- do {
- char c = (char)std::fmod(num, radix);
- c = (c < 10) ? (c + '0') : (c - 10 + 'a');
- str.prepend(QLatin1Char(c));
- num = std::floor(num / radix);
- } while (num != 0);
- if (frac != 0) {
- str.append(QLatin1Char('.'));
- do {
- frac = frac * radix;
- char c = (char)std::floor(frac);
- c = (c < 10) ? (c + '0') : (c - 10 + 'a');
- str.append(QLatin1Char(c));
- frac = frac - std::floor(frac);
- } while (frac != 0);
- }
- if (negative)
- str.prepend(QLatin1Char('-'));
- return Encode(v4->newString(str));
- }
+ QString str;
+ RuntimeHelpers::numberToString(&str, num, radix);
+ return Encode(v4->newString(str));
}
return Encode(Value::fromDouble(num).toString(v4));
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index abf48b1034..afa4632e07 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -298,13 +298,22 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix)
if (frac != 0) {
result->append(QLatin1Char('.'));
+ double magnitude = 1;
+ double next = frac;
do {
- frac = frac * radix;
- char c = (char)::floor(frac);
+ next *= radix;
+ const int floored = ::floor(next);
+ char c = char(floored);
c = (c < 10) ? (c + '0') : (c - 10 + 'a');
result->append(QLatin1Char(c));
- frac = frac - ::floor(frac);
- } while (frac != 0);
+ magnitude /= radix;
+ frac -= double(floored) * magnitude;
+ next -= double(floored);
+
+ // The next digit still makes a difference
+ // if a value of "radix" for it would change frac.
+ // Otherwise we've reached the limit of numerical precision.
+ } while (frac > 0 && frac - magnitude != frac);
}
if (negative)
@@ -1600,12 +1609,14 @@ ReturnedValue Runtime::method_tailCall(CppStackFrame *frame, ExecutionEngine *en
const Value &thisObject = tos[StackOffsets::tailCall_thisObject];
Value *argv = reinterpret_cast<Value *>(frame->jsFrame) + tos[StackOffsets::tailCall_argv].int_32();
int argc = tos[StackOffsets::tailCall_argc].int_32();
+ Q_ASSERT(argc >= 0);
if (!function.isFunctionObject())
return engine->throwTypeError();
const FunctionObject &fo = static_cast<const FunctionObject &>(function);
- if (!frame->callerCanHandleTailCall || !fo.canBeTailCalled() || engine->debugger()) {
+ if (!frame->callerCanHandleTailCall || !fo.canBeTailCalled() || engine->debugger()
+ || unsigned(argc) > fo.formalParameterCount()) {
// Cannot tailcall, do a normal call:
return fo.call(&thisObject, argv, argc);
}
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index c519429d48..1b7a433a84 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -250,10 +250,12 @@ QQmlApplicationEngine::~QQmlApplicationEngine()
/*!
Loads the root QML file located at \a url. The object tree defined by the file
is created immediately for local file urls. Remote urls are loaded asynchronously,
- listen to the objectCreated signal to determine when the object
- tree is ready.
+ listen to the \l {QQmlApplicationEngine::objectCreated()}{objectCreated} signal to
+ determine when the object tree is ready.
- If an error occurs, error messages are printed with qWarning.
+ If an error occurs, the \l {QQmlApplicationEngine::objectCreated()}{objectCreated}
+ signal is emitted with a null pointer as parameter and error messages are printed
+ with qWarning.
*/
void QQmlApplicationEngine::load(const QUrl &url)
{
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 53e3f65553..572f58339f 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -353,6 +353,7 @@ void QQmlDelegateModel::componentComplete()
\l{QtQuick.XmlListModel::XmlListModel}{XmlListModel}.
\sa {qml-data-models}{Data Models}
+ \keyword dm-model-property
*/
QVariant QQmlDelegateModel::model() const
{
@@ -493,11 +494,10 @@ void QQmlDelegateModel::setDelegate(QQmlComponent *delegate)
\c view.qml:
\snippet delegatemodel/delegatemodel_rootindex/view.qml 0
- If the \l model is a QAbstractItemModel subclass, the delegate can also
- reference a \c hasModelChildren property (optionally qualified by a
- \e model. prefix) that indicates whether the delegate's model item has
- any child nodes.
-
+ If the \l {dm-model-property}{model} is a QAbstractItemModel subclass,
+ the delegate can also reference a \c hasModelChildren property (optionally
+ qualified by a \e model. prefix) that indicates whether the delegate's
+ model item has any child nodes.
\sa modelIndex(), parentModelIndex()
*/
@@ -699,6 +699,7 @@ QQmlDelegateModelGroup *QQmlDelegateModelPrivate::group_at(
The following example illustrates using groups to select items in a model.
\snippet delegatemodel/delegatemodelgroup.qml 0
+ \keyword dm-groups-property
*/
QQmlListProperty<QQmlDelegateModelGroup> QQmlDelegateModel::groups()
@@ -2274,7 +2275,7 @@ void QQmlDelegateModelAttached::resetCurrentIndex()
}
/*!
- \qmlattachedproperty int QtQml.Models::DelegateModel::model
+ \qmlattachedproperty model QtQml.Models::DelegateModel::model
This attached property holds the data model this delegate instance belongs to.
@@ -2482,7 +2483,8 @@ void QQmlDelegateModelGroupPrivate::destroyingPackage(QQuickPackage *package)
information about group membership and indexes as well as model data. In combination
with the move() function this can be used to implement view sorting, with remove() to filter
items out of a view, or with setGroups() and \l Package delegates to categorize items into
- different views.
+ different views. Different groups can only be sorted independently if they are disjunct. Moving
+ an item in one group will also move it in all other groups it is a part of.
Data from models can be supplemented by inserting data directly into a DelegateModelGroup
with the insert() function. This can be used to introduce mock items into a view, or
@@ -3094,6 +3096,11 @@ void QQmlDelegateModelGroup::setGroups(QQmlV4Function *args)
\qmlmethod QtQml.Models::DelegateModelGroup::move(var from, var to, int count)
Moves \a count at \a from in a group \a to a new position.
+
+ \note The DelegateModel acts as a proxy model: it holds the delegates in a
+ different order than the \l{dm-model-property}{underlying model} has them.
+ Any subsequent changes to the underlying model will not undo whatever
+ reordering you have done via this function.
*/
void QQmlDelegateModelGroup::move(QQmlV4Function *args)
diff --git a/src/qmltest/doc/src/qtquicktest-index.qdoc b/src/qmltest/doc/src/qtquicktest-index.qdoc
index 283e88e2e4..4c0124689b 100644
--- a/src/qmltest/doc/src/qtquicktest-index.qdoc
+++ b/src/qmltest/doc/src/qtquicktest-index.qdoc
@@ -141,7 +141,7 @@
\l QUICK_TEST_MAIN_WITH_SETUP macro can be used. This can be useful for
setting context properties on the QML engine, amongst other things.
- The macro is identical to \l QUICK_TEST_MAIN, except that it takes an
+ The macro is identical to \c QUICK_TEST_MAIN, except that it takes an
additional \c QObject* argument. The test framework will call slots and
invokable functions with the following names:
diff --git a/src/qmltest/quicktestevent.cpp b/src/qmltest/quicktestevent.cpp
index 480811d95c..5b07220c29 100644
--- a/src/qmltest/quicktestevent.cpp
+++ b/src/qmltest/quicktestevent.cpp
@@ -121,6 +121,7 @@ bool QuickTestEvent::keyClickChar(const QString &character, int modifiers, int d
return true;
}
+#if QT_CONFIG(shortcut)
// valueToKeySequence() is copied from qquickshortcut.cpp
static QKeySequence valueToKeySequence(const QVariant &value)
{
@@ -128,13 +129,16 @@ static QKeySequence valueToKeySequence(const QVariant &value)
return QKeySequence(static_cast<QKeySequence::StandardKey>(value.toInt()));
return QKeySequence::fromString(value.toString());
}
+#endif
bool QuickTestEvent::keySequence(const QVariant &keySequence)
{
QWindow *window = activeWindow();
if (!window)
return false;
+#if QT_CONFIG(shortcut)
QTest::keySequence(window, valueToKeySequence(keySequence));
+#endif
return true;
}
diff --git a/src/quick/handlers/qquickpointhandler.cpp b/src/quick/handlers/qquickpointhandler.cpp
index 6d6ba07f5c..30f62332ba 100644
--- a/src/quick/handlers/qquickpointhandler.cpp
+++ b/src/quick/handlers/qquickpointhandler.cpp
@@ -59,8 +59,8 @@ QT_BEGIN_NAMESPACE
occurs within the bounds of the \l {PointerHandler::parent}, and
no sibling PointHandler within the same \l {PointerHandler::parent}
has yet acquired a passive grab on that point, and if the other
- constraints such as \l[QML]{SinglePointHandler::acceptedButtons},
- \l {PointerDeviceHandler::acceptedDevices} etc. are satisfied, it's
+ constraints such as \l {PointerDeviceHandler::acceptedButtons}{acceptedButtons}, \l {PointerDeviceHandler::acceptedDevices}{acceptedDevices} etc.
+ are satisfied, it's
eligible, and the PointHandler then acquires a passive grab. In
this way, the \l {PointerHandler::parent} acts like an exclusive
group: there can be multiple instances of PointHandler, and the
diff --git a/src/quick/handlers/qquicktaphandler.cpp b/src/quick/handlers/qquicktaphandler.cpp
index b4b6bd574e..081645da71 100644
--- a/src/quick/handlers/qquicktaphandler.cpp
+++ b/src/quick/handlers/qquicktaphandler.cpp
@@ -230,7 +230,7 @@ void QQuickTapHandler::timerEvent(QTimerEvent *event)
will not take the exclusive grab, but merely a passive grab.
\value TapHandler.WithinBounds
- If the event point leaves the bounds of the \l parent Item, the tap
+ If the event point leaves the bounds of the \c parent Item, the tap
gesture is canceled. The TapHandler will take the exclusive grab on
press, but will release the grab as soon as the boundary constraint
is no longer satisfied.
@@ -238,7 +238,7 @@ void QQuickTapHandler::timerEvent(QTimerEvent *event)
\value TapHandler.ReleaseWithinBounds
At the time of release (the mouse button is released or the finger
is lifted), if the event point is outside the bounds of the
- \l parent Item, a tap gesture is not recognized. This corresponds to
+ \c parent Item, a tap gesture is not recognized. This corresponds to
typical behavior for button widgets: you can cancel a click by
dragging outside the button, and you can also change your mind by
dragging back inside the button before release. Note that it's
@@ -383,7 +383,7 @@ void QQuickTapHandler::updateTimeHeld()
/*!
\qmlsignal QtQuick::TapHandler::tapped
- This signal is emitted each time the \l parent Item is tapped.
+ This signal is emitted each time the \c parent Item is tapped.
That is, if you press and release a touchpoint or button within a time
period less than \l longPressThreshold, while any movement does not exceed
@@ -395,7 +395,7 @@ void QQuickTapHandler::updateTimeHeld()
\qmlsignal QtQuick::TapHandler::singleTapped
\since 5.11
- This signal is emitted when the \l parent Item is tapped once.
+ This signal is emitted when the \c parent Item is tapped once.
After an amount of time greater than QStyleHints::mouseDoubleClickInterval,
it can be tapped again; but if the time until the next tap is less,
\l tapCount will increase.
@@ -405,7 +405,7 @@ void QQuickTapHandler::updateTimeHeld()
\qmlsignal QtQuick::TapHandler::doubleTapped
\since 5.11
- This signal is emitted when the \l parent Item is tapped twice within a
+ This signal is emitted when the \c parent Item is tapped twice within a
short span of time (QStyleHints::mouseDoubleClickInterval) and distance
(QPlatformTheme::MouseDoubleClickDistance or
QPlatformTheme::TouchDoubleTapDistance). This signal always occurs after
@@ -415,11 +415,18 @@ void QQuickTapHandler::updateTimeHeld()
/*!
\qmlsignal QtQuick::TapHandler::longPressed
- This signal is emitted when the \l parent Item is pressed and held for a
+ This signal is emitted when the \c parent Item is pressed and held for a
time period greater than \l longPressThreshold. That is, if you press and
hold a touchpoint or button, while any movement does not exceed the drag
threshold, then the \c longPressed signal will be emitted at the time that
\l timeHeld exceeds \l longPressThreshold.
*/
+/*!
+ \qmlsignal QtQuick::TapHandler::tapCountChanged
+
+ This signal is emitted when the \c parent Item is tapped once or more (within
+ a specified time and distance span) and when the present \c tapCount differs
+ from the previous \c tapCount.
+*/
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index 2eaab164a0..c43eab6b8a 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -864,8 +864,11 @@ void QQuickEventPoint::setGrabberItem(QQuickItem *grabber)
QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(grabber->window());
windowPriv->sendUngrabEvent(oldGrabberItem, windowPriv->isDeliveringTouchAsMouse());
}
- for (QPointer<QQuickPointerHandler> passiveGrabber : m_passiveGrabbers)
- passiveGrabber->onGrabChanged(passiveGrabber, OverrideGrabPassive, this);
+ if (grabber) {
+ for (QPointer<QQuickPointerHandler> passiveGrabber : m_passiveGrabbers)
+ if (passiveGrabber)
+ passiveGrabber->onGrabChanged(passiveGrabber, OverrideGrabPassive, this);
+ }
}
}
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index cf882e8c9e..d6dddc3f1c 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -786,7 +786,7 @@ void QQuickFlickable::setContentX(qreal pos)
d->hData.vTime = d->timeline.time();
if (isMoving() || isFlicking())
movementEnding(true, false);
- if (-pos != d->hData.move.value())
+ if (!qFuzzyCompare(-pos, d->hData.move.value()))
d->hData.move.setValue(-pos);
}
@@ -804,7 +804,7 @@ void QQuickFlickable::setContentY(qreal pos)
d->vData.vTime = d->timeline.time();
if (isMoving() || isFlicking())
movementEnding(false, true);
- if (-pos != d->vData.move.value())
+ if (!qFuzzyCompare(-pos, d->vData.move.value()))
d->vData.move.setValue(-pos);
}
diff --git a/src/quick/items/qquickitemgrabresult.cpp b/src/quick/items/qquickitemgrabresult.cpp
index b45cb09c4b..f298803c7f 100644
--- a/src/quick/items/qquickitemgrabresult.cpp
+++ b/src/quick/items/qquickitemgrabresult.cpp
@@ -226,10 +226,12 @@ bool QQuickItemGrabResult::event(QEvent *e)
Q_D(QQuickItemGrabResult);
if (e->type() == Event_Grab_Completed) {
// JS callback
- if (d->qmlEngine && d->callback.isCallable())
+ if (d->qmlEngine && d->callback.isCallable()) {
d->callback.call(QJSValueList() << d->qmlEngine->newQObject(this));
- else
+ deleteLater();
+ } else {
Q_EMIT ready();
+ }
return true;
}
return QObject::event(e);
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index 675208d75c..ac3397d2a9 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -133,7 +133,7 @@
width, unless the \l columnWidthProvider property is explicitly set. Once
the column width is found, all other items in the same column are resized
to this width, even if new items that are flicked in later have larger
- \c implicitWidth. Setting an explicit \l width on an item is ignored and
+ \c implicitWidth. Setting an explicit \c width on an item is ignored and
overwritten.
\note The calculated width of a column is discarded when it is flicked out
@@ -265,9 +265,10 @@
applies to \c row and \c column. Properties of the model are also available
depending upon the type of \l {qml-data-models}{Data Model}.
- A delegate should specify its size using \l implicitWidth and \l implicitHeight.
- The TableView lays out the items based on that information. Explicit \l width or
- \l height settings are ignored and overwritten.
+ A delegate should specify its size using \l [QML]{Item::implicitWidth}{implicitWidth} and
+ \l [QML]{Item::implicitHeight}{implicitHeight}.
+ The TableView lays out the items based on that information. Explicit width or
+ height settings are ignored and overwritten.
\note Delegates are instantiated as needed and may be destroyed at any time.
They are also reused if the \l reuseItems property is set to \c true. You
@@ -289,7 +290,7 @@
/*!
\qmlproperty real QtQuick::TableView::contentWidth
- This property holds the width of the \l contentView, which is also
+ This property holds the width of the \l view, which is also
the width of the table (including margins). As a TableView cannot
always know the exact width of the table without loading all columns
in the model, the \c contentWidth is usually an estimated width based on
@@ -307,7 +308,7 @@
/*!
\qmlproperty real QtQuick::TableView::contentHeight
- This property holds the height of the \l contentView, which is also
+ This property holds the height of the \l view, which is also
the height of the table (including margins). As a TableView cannot
always know the exact height of the table without loading all rows
in the model, the \c contentHeight is usually an estimated height
@@ -328,7 +329,7 @@
Responding to changes in the model are batched so that they are handled
only once per frame. This means the TableView delays showing any changes
while a script is being run. The same is also true when changing
- properties such as \l rowSpacing or \l leftMargin.
+ properties such as \l rowSpacing or \l {Item::anchors.leftMargin}{leftMargin}.
This method forces the TableView to immediately update the layout so
that any recent changes take effect.
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 9e447d40ac..73b151168e 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -442,7 +442,7 @@ void QQuickTextPrivate::updateSize()
if (internalWidthUpdate)
return;
- extra->doc->setPageSize(QSizeF());
+ extra->doc->setPageSize(QSizeF(q->width(), -1));
if (q->widthValid() && (wrapMode != QQuickText::NoWrap || extra->doc->idealWidth() < availableWidth()))
extra->doc->setTextWidth(availableWidth());
else
@@ -1247,7 +1247,7 @@ void QQuickTextPrivate::ensureDoc()
if (!extra.isAllocated() || !extra->doc) {
Q_Q(QQuickText);
extra.value().doc = new QQuickTextDocumentWithImageResources(q);
- extra->doc->setPageSize(QSizeF(0, 0));
+ extra->doc->setPageSize(QSizeF(q->width(), -1));
extra->doc->setDocumentMargin(0);
extra->doc->setBaseUrl(q->baseUrl());
qmlobject_connect(extra->doc, QQuickTextDocumentWithImageResources, SIGNAL(imagesLoaded()),
diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp
index d84932b8d0..a1b5eb1faf 100644
--- a/src/quick/items/qquicktextnodeengine.cpp
+++ b/src/quick/items/qquicktextnodeengine.cpp
@@ -967,9 +967,14 @@ void QQuickTextNodeEngine::addTextBlock(QTextDocument *textDocument, const QText
QVarLengthArray<QTextLayout::FormatRange> colorChanges;
mergeFormats(block.layout(), &colorChanges);
- QPointF blockPosition = textDocument->documentLayout()->blockBoundingRect(block).topLeft() + position;
+ const QTextCharFormat charFormat = block.charFormat();
+ const QRectF blockBoundingRect = textDocument->documentLayout()->blockBoundingRect(block).translated(position);
+
+ if (charFormat.background().style() != Qt::NoBrush)
+ m_backgrounds.append(qMakePair(blockBoundingRect, charFormat.background().color()));
+
if (QTextList *textList = block.textList()) {
- QPointF pos = blockPosition;
+ QPointF pos = blockBoundingRect.topLeft();
QTextLayout *layout = block.layout();
if (layout->lineCount() > 0) {
QTextLine firstLine = layout->lineAt(0);
@@ -982,7 +987,6 @@ void QQuickTextNodeEngine::addTextBlock(QTextDocument *textDocument, const QText
if (block.textDirection() == Qt::RightToLeft)
pos.rx() += textRect.width();
- const QTextCharFormat charFormat = block.charFormat();
QFont font(charFormat.font());
QFontMetricsF fontMetrics(font);
QTextListFormat listFormat = textList->format();
@@ -1043,11 +1047,11 @@ void QQuickTextNodeEngine::addTextBlock(QTextDocument *textDocument, const QText
int fontHeight = fontMetrics.descent() + fontMetrics.ascent();
int valign = charFormat.verticalAlignment();
if (valign == QTextCharFormat::AlignSuperScript)
- setPosition(QPointF(blockPosition.x(), blockPosition.y() - fontHeight / 2));
+ setPosition(QPointF(blockBoundingRect.x(), blockBoundingRect.y() - fontHeight / 2));
else if (valign == QTextCharFormat::AlignSubScript)
- setPosition(QPointF(blockPosition.x(), blockPosition.y() + fontHeight / 6));
+ setPosition(QPointF(blockBoundingRect.x(), blockBoundingRect.y() + fontHeight / 6));
else
- setPosition(blockPosition);
+ setPosition(blockBoundingRect.topLeft());
if (text.contains(QChar::ObjectReplacementCharacter)) {
QTextFrame *frame = qobject_cast<QTextFrame *>(textDocument->objectForFormat(charFormat));
@@ -1101,7 +1105,7 @@ void QQuickTextNodeEngine::addTextBlock(QTextDocument *textDocument, const QText
#if QT_CONFIG(im)
if (preeditLength >= 0 && textPos <= block.position() + preeditPosition) {
- setPosition(blockPosition);
+ setPosition(blockBoundingRect.topLeft());
textPos = block.position() + preeditPosition;
QTextLine line = block.layout()->lineForTextPosition(preeditPosition);
if (!currentLine().isValid()
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 2305a22cf7..d448d74b99 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -1613,7 +1613,9 @@ bool QQuickWindow::event(QEvent *e)
bool accepted = enter->isAccepted();
bool delivered = d->deliverHoverEvent(d->contentItem, enter->windowPos(), d->lastMousePosition,
QGuiApplication::keyboardModifiers(), 0L, accepted);
+ d->lastMousePosition = enter->windowPos();
enter->setAccepted(accepted);
+ d->updateCursor(mapFromGlobal(QCursor::pos()));
return delivered;
}
break;
@@ -2535,18 +2537,22 @@ bool QQuickWindowPrivate::deliverPressOrReleaseEvent(QQuickPointerEvent *event,
int pointCount = event->pointCount();
QVector<QQuickItem *> targetItems;
bool isTouchEvent = (event->asPointerTouchEvent() != nullptr);
- if (isTouchEvent && event->isPressEvent() && isDeliveringTouchAsMouse() &&
- pointerEventInstance(touchMouseDevice)->pointById(touchMouseId)->grabberPointerHandler()) {
- // When a second point is pressed, if the first point's existing
- // grabber was a pointer handler while a filtering parent is filtering
- // the same first point _as mouse_: we're starting over with delivery,
- // so we need to allow the second point to now be sent as a synth-mouse
- // instead of the first one, so that filtering parents (maybe even the
- // same one) can get a chance to see the second touchpoint as a
- // synth-mouse and perhaps grab it. Ideally we would always do this
- // when a new touchpoint is pressed, but this compromise fixes
- // QTBUG-70998 and avoids breaking tst_FlickableInterop::touchDragSliderAndFlickable
- cancelTouchMouseSynthesis();
+ if (isTouchEvent && event->isPressEvent() && isDeliveringTouchAsMouse()) {
+ if (const QQuickEventPoint *point = pointerEventInstance(touchMouseDevice)->pointById(touchMouseId)) {
+ // When a second point is pressed, if the first point's existing
+ // grabber was a pointer handler while a filtering parent is filtering
+ // the same first point _as mouse_: we're starting over with delivery,
+ // so we need to allow the second point to now be sent as a synth-mouse
+ // instead of the first one, so that filtering parents (maybe even the
+ // same one) can get a chance to see the second touchpoint as a
+ // synth-mouse and perhaps grab it. Ideally we would always do this
+ // when a new touchpoint is pressed, but this compromise fixes
+ // QTBUG-70998 and avoids breaking tst_FlickableInterop::touchDragSliderAndFlickable
+ if (point->grabberPointerHandler())
+ cancelTouchMouseSynthesis();
+ } else {
+ qCWarning(DBG_TOUCH_TARGET) << "during delivery of touch press, synth-mouse ID" << touchMouseId << "is missing from" << event;
+ }
}
for (int i = 0; i < pointCount; ++i) {
auto point = event->point(i);
diff --git a/src/quickshapes/qquickshape.cpp b/src/quickshapes/qquickshape.cpp
index 489d1c86f7..262d0b3e9a 100644
--- a/src/quickshapes/qquickshape.cpp
+++ b/src/quickshapes/qquickshape.cpp
@@ -805,9 +805,8 @@ QQuickShape::Status QQuickShape::status() const
\since QtQuick.Shapes 1.11
This property determines the definition of \l {QQuickItem::contains()}{contains()}
- for the Shape. It is useful in case you add
- \l {Qt Quick Pointer Handlers QML Types}{Pointer Handlers} and you
- want to react only when the mouse or touchpoint is fully inside the Shape.
+ for the Shape. It is useful in case you add \l {Qt Quick Input Handlers} and you want to
+ react only when the mouse or touchpoint is fully inside the Shape.
\value Shape.BoundingRectContains
The default implementation of \l QQuickItem::contains() checks only