aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-06-13 09:04:09 +0200
committerLiang Qi <liang.qi@qt.io>2016-06-13 19:06:06 +0200
commit4d2f743baaf6869693f4540df668e1b998154785 (patch)
treeba712b420e5d299be28faf641d30585ae8dce4e7 /src/quick/items
parent0c5a9ff9876cb1af53317720d1de8baae003e21d (diff)
parent0932a59971f606f07b41da19f3974d51b7008180 (diff)
Merge remote-tracking branch 'origin/5.7' into dev
Conflicts: src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp Change-Id: I26d6435a29cac3840bb567ade5149c2562a94bf9
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp10
-rw-r--r--src/quick/items/qquickflickable.cpp2
-rw-r--r--src/quick/items/qquickitem.cpp33
-rw-r--r--src/quick/items/qquickitemgrabresult.cpp5
-rw-r--r--src/quick/items/qquickmousearea.cpp21
-rw-r--r--src/quick/items/qquickmousearea_p_p.h1
-rw-r--r--src/quick/items/qquickpathview.cpp2
-rw-r--r--src/quick/items/qquicktextnodeengine.cpp5
-rw-r--r--src/quick/items/qquickwindow.cpp31
9 files changed, 84 insertions, 26 deletions
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index 7ffb715346..b340d9bf94 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -679,10 +679,14 @@ void QQuickCanvasItem::itemChange(QQuickItem::ItemChange change, const QQuickIte
QSGRenderContext *context = QQuickWindowPrivate::get(d->window)->context;
// Rendering to FramebufferObject needs a valid OpenGL context.
- if (context != 0 && (d->renderTarget != FramebufferObject || context->isValid()))
- sceneGraphInitialized();
- else
+ if (context != 0 && (d->renderTarget != FramebufferObject || context->isValid())) {
+ // Defer the call. In some (arguably incorrect) cases we get here due
+ // to ItemSceneChange with the user-supplied property values not yet
+ // set. Work this around by a deferred invoke. (QTBUG-49692)
+ QMetaObject::invokeMethod(this, "sceneGraphInitialized", Qt::QueuedConnection);
+ } else {
connect(d->window, SIGNAL(sceneGraphInitialized()), SLOT(sceneGraphInitialized()));
+ }
}
void QQuickCanvasItem::updatePolish()
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 1853a1d948..1bcc3cc0f9 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -65,7 +65,9 @@ static const int FlickThreshold = 15;
// will ensure the Flickable retains the grab on consecutive flicks.
static const int RetainGrabVelocity = 100;
+#ifdef Q_OS_OSX
static const int MovementEndingTimerInterval = 100;
+#endif
static qreal EaseOvershoot(qreal t) {
return qAtan(t);
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 9a13198d7d..1bffaf92d0 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -423,21 +423,44 @@ void QQuickItemKeyFilter::componentComplete()
/*!
\qmlproperty Item QtQuick::KeyNavigation::left
+
+ This property holds the item to assign focus to
+ when the left cursor key is pressed.
+*/
+
+/*!
\qmlproperty Item QtQuick::KeyNavigation::right
+
+ This property holds the item to assign focus to
+ when the right cursor key is pressed.
+*/
+
+/*!
\qmlproperty Item QtQuick::KeyNavigation::up
+
+ This property holds the item to assign focus to
+ when the up cursor key is pressed.
+*/
+
+/*!
\qmlproperty Item QtQuick::KeyNavigation::down
- These properties hold the item to assign focus to
- when the left, right, up or down cursor keys
- are pressed.
+ This property holds the item to assign focus to
+ when the down cursor key is pressed.
*/
/*!
\qmlproperty Item QtQuick::KeyNavigation::tab
+
+ This property holds the item to assign focus to
+ when the Tab key is pressed.
+*/
+
+/*!
\qmlproperty Item QtQuick::KeyNavigation::backtab
- These properties hold the item to assign focus to
- when the Tab key or Shift+Tab key combination (Backtab) are pressed.
+ This property holds the item to assign focus to
+ when the Shift+Tab key combination (Backtab) is pressed.
*/
QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent)
diff --git a/src/quick/items/qquickitemgrabresult.cpp b/src/quick/items/qquickitemgrabresult.cpp
index 019352c57a..0db5323863 100644
--- a/src/quick/items/qquickitemgrabresult.cpp
+++ b/src/quick/items/qquickitemgrabresult.cpp
@@ -299,7 +299,7 @@ QQuickItemGrabResult *QQuickItemGrabResultPrivate::create(QQuickItem *item, cons
* Use \a targetSize to specify the size of the target image. By default, the
* result will have the same size as item.
*
- * If the grab could not be initiated, the function returns a \c null.
+ * If the grab could not be initiated, the function returns \c null.
*
* \note This function will render the item to an offscreen surface and
* copy that surface from the GPU's memory into the CPU's memory, which can
@@ -326,7 +326,8 @@ QSharedPointer<QQuickItemGrabResult> QQuickItem::grabToImage(const QSize &target
* Grabs the item into an in-memory image.
*
* The grab happens asynchronously and the JavaScript function \a callback is
- * invoked when the grab is completed.
+ * invoked when the grab is completed. The callback takes one argument, which
+ * is the result of the grab operation; an \l ItemGrabResult object.
*
* Use \a targetSize to specify the size of the target image. By default, the result
* will have the same size as the item.
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index 66aff5c2f4..0219bc809f 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -57,7 +57,7 @@ DEFINE_BOOL_CONFIG_OPTION(qmlVisualTouchDebugging, QML_VISUAL_TOUCH_DEBUGGING)
QQuickMouseAreaPrivate::QQuickMouseAreaPrivate()
: enabled(true), scrollGestureEnabled(true), hovered(false), longPress(false),
moved(false), stealMouse(false), doubleClick(false), preventStealing(false),
- propagateComposedEvents(false), pressed(0)
+ propagateComposedEvents(false), overThreshold(false), pressed(0)
#ifndef QT_NO_DRAGANDDROP
, drag(0)
#endif
@@ -720,7 +720,7 @@ void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event)
curLocalPos = event->windowPos();
}
- if (keepMouseGrab() && d->stealMouse && !d->drag->active())
+ if (keepMouseGrab() && d->stealMouse && d->overThreshold && !d->drag->active())
d->drag->setActive(true);
QPointF startPos = d->drag->target()->parentItem()
@@ -746,16 +746,19 @@ void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event)
if (d->drag->active())
d->drag->target()->setPosition(dragPos);
- if (!keepMouseGrab()
- && (QQuickWindowPrivate::dragOverThreshold(dragPos.x() - startPos.x(), Qt::XAxis, event, d->drag->threshold())
- || QQuickWindowPrivate::dragOverThreshold(dragPos.y() - startPos.y(), Qt::YAxis, event, d->drag->threshold()))) {
- setKeepMouseGrab(true);
- d->stealMouse = true;
-
+ 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())))
+ {
+ d->overThreshold = true;
if (d->drag->smoothed())
d->startScene = event->windowPos();
}
+ if (!keepMouseGrab() && d->overThreshold) {
+ setKeepMouseGrab(true);
+ d->stealMouse = true;
+ }
+
d->moved = true;
}
#endif
@@ -774,6 +777,7 @@ void QQuickMouseArea::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(QQuickMouseArea);
d->stealMouse = false;
+ d->overThreshold = false;
if (!d->enabled && !d->pressed) {
QQuickItem::mouseReleaseEvent(event);
} else {
@@ -887,6 +891,7 @@ void QQuickMouseArea::ungrabMouse()
d->pressed = 0;
d->stealMouse = false;
d->doubleClick = false;
+ d->overThreshold = false;
setKeepMouseGrab(false);
#ifndef QT_NO_DRAGANDDROP
diff --git a/src/quick/items/qquickmousearea_p_p.h b/src/quick/items/qquickmousearea_p_p.h
index 794a8cc6ff..b59e02910f 100644
--- a/src/quick/items/qquickmousearea_p_p.h
+++ b/src/quick/items/qquickmousearea_p_p.h
@@ -93,6 +93,7 @@ public:
bool doubleClick : 1;
bool preventStealing : 1;
bool propagateComposedEvents : 1;
+ bool overThreshold : 1;
Qt::MouseButtons pressed;
#ifndef QT_NO_DRAGANDDROP
QQuickDrag *drag;
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index e3d218ff01..7bb52853bc 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -1026,7 +1026,7 @@ void QQuickPathView::setHighlightMoveDuration(int duration)
/*!
\qmlproperty real QtQuick::PathView::dragMargin
- This property holds the maximum distance from the path that initiate mouse dragging.
+ This property holds the maximum distance from the path that initiates mouse dragging.
By default the path can only be dragged by clicking on an item. If
dragMargin is greater than zero, a drag can be initiated by clicking
diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp
index 98da3ca777..11249be8c6 100644
--- a/src/quick/items/qquicktextnodeengine.cpp
+++ b/src/quick/items/qquicktextnodeengine.cpp
@@ -642,9 +642,12 @@ void QQuickTextNodeEngine::addBorder(const QRectF &rect, qreal border,
void QQuickTextNodeEngine::addFrameDecorations(QTextDocument *document, QTextFrame *frame)
{
QTextDocumentLayout *documentLayout = qobject_cast<QTextDocumentLayout *>(document->documentLayout());
- QTextFrameFormat frameFormat = frame->format().toFrameFormat();
+ if (Q_UNLIKELY(!documentLayout))
+ return;
+ QTextFrameFormat frameFormat = frame->format().toFrameFormat();
QTextTable *table = qobject_cast<QTextTable *>(frame);
+
QRectF boundingRect = table == 0
? documentLayout->frameBoundingRect(frame)
: documentLayout->tableBoundingRect(table);
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index b3ca563f16..478e01388e 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -834,8 +834,10 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, Q
QQuickItemPrivate *scopePrivate = scope ? QQuickItemPrivate::get(scope) : 0;
QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ QQuickItem *oldActiveFocusItem = 0;
QQuickItem *currentActiveFocusItem = activeFocusItem;
QQuickItem *newActiveFocusItem = 0;
+ bool sendFocusIn = false;
lastFocusReason = reason;
@@ -843,7 +845,6 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, Q
// Does this change the active focus?
if (item == contentItem || scopePrivate->activeFocus) {
- QQuickItem *oldActiveFocusItem = 0;
oldActiveFocusItem = activeFocusItem;
if (item->isEnabled()) {
newActiveFocusItem = item;
@@ -862,8 +863,6 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, Q
#endif
activeFocusItem = 0;
- QFocusEvent event(QEvent::FocusOut, reason);
- q->sendEvent(oldActiveFocusItem, &event);
QQuickItem *afi = oldActiveFocusItem;
while (afi && afi != scope) {
@@ -908,7 +907,19 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, Q
afi = afi->parentItem();
}
updateFocusItemTransform();
+ sendFocusIn = true;
+ }
+
+ // Now that all the state is changed, emit signals & events
+ // We must do this last, as this process may result in further changes to
+ // focus.
+ if (oldActiveFocusItem) {
+ QFocusEvent event(QEvent::FocusOut, reason);
+ q->sendEvent(oldActiveFocusItem, &event);
+ }
+ // Make sure that the FocusOut didn't result in another focus change.
+ if (sendFocusIn && activeFocusItem == newActiveFocusItem) {
QFocusEvent event(QEvent::FocusIn, reason);
q->sendEvent(newActiveFocusItem, &event);
}
@@ -961,9 +972,6 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item,
activeFocusItem = 0;
if (oldActiveFocusItem) {
- QFocusEvent event(QEvent::FocusOut, reason);
- q->sendEvent(oldActiveFocusItem, &event);
-
QQuickItem *afi = oldActiveFocusItem;
while (afi && afi != scope) {
if (QQuickItemPrivate::get(afi)->activeFocus) {
@@ -993,7 +1001,18 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item,
Q_ASSERT(newActiveFocusItem == scope);
activeFocusItem = scope;
updateFocusItemTransform();
+ }
+
+ // Now that all the state is changed, emit signals & events
+ // We must do this last, as this process may result in further changes to
+ // focus.
+ if (oldActiveFocusItem) {
+ QFocusEvent event(QEvent::FocusOut, reason);
+ q->sendEvent(oldActiveFocusItem, &event);
+ }
+ // Make sure that the FocusOut didn't result in another focus change.
+ if (newActiveFocusItem && activeFocusItem == newActiveFocusItem) {
QFocusEvent event(QEvent::FocusIn, reason);
q->sendEvent(newActiveFocusItem, &event);
}