From 67f589209dc856be3ac6261f51023125343812ce Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Mon, 12 Mar 2012 18:48:05 +1000 Subject: [PATCH] Don't assert if focus is already clear. Already cleared focus should exit the function without terminating the runtime. Task-number: QTBUG-24714 Change-Id: Ia8c6be0d88e43d1f71112acc7bac3eb674f22de8 Reviewed-by: Martin Jones --- src/quick/items/qquickcanvas.cpp | 8 ++++++-- .../qquickitem/data/multipleFocusClears.qml | 18 ++++++++++++++++++ tests/auto/quick/qquickitem/tst_qquickitem.cpp | 11 +++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 tests/auto/quick/qquickitem/data/multipleFocusClears.qml diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp index 26360229e9..a6c2a90407 100644 --- a/src/quick/items/qquickcanvas.cpp +++ b/src/quick/items/qquickcanvas.cpp @@ -607,7 +607,6 @@ void QQuickCanvasPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item, { Q_Q(QQuickCanvas); - Q_UNUSED(item); Q_ASSERT(item); Q_ASSERT(scope || item == rootItem); @@ -618,7 +617,12 @@ void QQuickCanvasPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item, qWarning() << " activeFocusItem:" << (QObject *)activeFocusItem; #endif - QQuickItemPrivate *scopePrivate = scope ? QQuickItemPrivate::get(scope) : 0; + QQuickItemPrivate *scopePrivate = 0; + if (scope) { + scopePrivate = QQuickItemPrivate::get(scope); + if ( !scopePrivate->subFocusItem ) + return;//No focus, nothing to do. + } QQuickItem *oldActiveFocusItem = 0; QQuickItem *newActiveFocusItem = 0; diff --git a/tests/auto/quick/qquickitem/data/multipleFocusClears.qml b/tests/auto/quick/qquickitem/data/multipleFocusClears.qml new file mode 100644 index 0000000000..f68a8901ab --- /dev/null +++ b/tests/auto/quick/qquickitem/data/multipleFocusClears.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Rectangle { + width: 200 + height: 200 + + FocusScope { + id: focusScope + anchors.fill: parent + + TextInput { + anchors.centerIn: parent + text: "Some text" + onActiveFocusChanged: if (!activeFocus) focusScope.focus = false + Component.onCompleted: forceActiveFocus() + } + } +} diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp index 7a589a48cd..9fdfa78559 100644 --- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp @@ -138,6 +138,7 @@ private slots: void scopedFocus(); void addedToCanvas(); void changeParent(); + void multipleFocusClears(); void constructor(); void setParentItem(); @@ -675,6 +676,16 @@ void tst_qquickitem::changeParent() } +void tst_qquickitem::multipleFocusClears() +{ + //Multiple clears of focus inside a focus scope shouldn't crash. QTBUG-24714 + QQuickView *view = new QQuickView; + view->setSource(testFileUrl("multipleFocusClears.qml")); + view->show(); + ensureFocus(view); + QTRY_VERIFY(QGuiApplication::focusWindow() == view); +} + void tst_qquickitem::constructor() { QQuickItem *root = new QQuickItem;