aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2011-10-24 13:57:12 +1000
committerQt by Nokia <qt-info@nokia.com>2011-10-24 09:11:14 +0200
commit0307f5a7b271eea75e5d9c12c65caaf578a3384b (patch)
tree6d5aed0faccf08f494368086818d1495c6cebd53
parentceecaa430a334420d7c041277707a8e438438d5e (diff)
Fix item focus following canvas focus.
Restore canvas focus handling so that active item focus is added and removed as the canvas focus changes. Task-number: QTBUG-17320 Change-Id: Ief60f35da2f3a563f397ce026ca6fea289a200c4 Reviewed-by: Martin Jones <martin.jones@nokia.com>
-rw-r--r--src/declarative/items/qquickcanvas.cpp21
-rw-r--r--src/declarative/items/qquickcanvas.h3
-rw-r--r--tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp36
-rw-r--r--tests/auto/declarative/qquickitem/tst_qquickitem.cpp13
-rw-r--r--tests/auto/declarative/qquickitem2/tst_qquickitem.cpp47
-rw-r--r--tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp25
-rw-r--r--tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp24
7 files changed, 83 insertions, 86 deletions
diff --git a/src/declarative/items/qquickcanvas.cpp b/src/declarative/items/qquickcanvas.cpp
index 8f87ce7a9c..52ef421213 100644
--- a/src/declarative/items/qquickcanvas.cpp
+++ b/src/declarative/items/qquickcanvas.cpp
@@ -348,6 +348,17 @@ void QQuickCanvas::hideEvent(QHideEvent *)
d->thread->stopRendering();
}
+void QQuickCanvas::focusOutEvent(QFocusEvent *)
+{
+ Q_D(QQuickCanvas);
+ d->rootItem->setFocus(false);
+}
+
+void QQuickCanvas::focusInEvent(QFocusEvent *)
+{
+ Q_D(QQuickCanvas);
+ d->rootItem->setFocus(true);
+}
/*!
@@ -484,10 +495,6 @@ void QQuickCanvasPrivate::init(QQuickCanvas *c)
rootItemPrivate->canvas = q;
rootItemPrivate->flags |= QQuickItem::ItemIsFocusScope;
- // QML always has focus. It is important that this call happens after the rootItem
- // has a canvas..
- rootItem->setFocus(true);
-
bool threaded = !qmlNoThreadedRenderer();
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL)) {
@@ -626,13 +633,13 @@ void QQuickCanvasPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, F
}
if (!(options & DontChangeFocusProperty)) {
- // if (item != rootItem || q->hasFocus()) { // ### refactor: focus handling...
+ if (item != rootItem || QGuiApplication::focusWindow() == q) {
itemPrivate->focus = true;
changed << item;
- // }
+ }
}
- if (newActiveFocusItem) { // ### refactor: && q->hasFocus()) {
+ if (newActiveFocusItem && QGuiApplication::focusWindow() == q) {
activeFocusItem = newActiveFocusItem;
QQuickItemPrivate::get(newActiveFocusItem)->activeFocus = true;
diff --git a/src/declarative/items/qquickcanvas.h b/src/declarative/items/qquickcanvas.h
index 8b69744161..e9b1b60613 100644
--- a/src/declarative/items/qquickcanvas.h
+++ b/src/declarative/items/qquickcanvas.h
@@ -101,6 +101,9 @@ protected:
virtual void showEvent(QShowEvent *);
virtual void hideEvent(QHideEvent *);
+ virtual void focusInEvent(QFocusEvent *);
+ virtual void focusOutEvent(QFocusEvent *);
+
virtual bool event(QEvent *);
virtual void keyPressEvent(QKeyEvent *);
virtual void keyReleaseEvent(QKeyEvent *);
diff --git a/tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp b/tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp
index 6e7dd98940..ffb9660262 100644
--- a/tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp
+++ b/tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp
@@ -121,6 +121,7 @@ void tst_qquickfocusscope::basic()
view->requestActivateWindow();
QTest::qWaitForWindowShown(view);
+ QTRY_VERIFY(view == qGuiApp->focusWindow());
QVERIFY(view->isTopLevel());
QVERIFY(item0->hasActiveFocus() == true);
@@ -165,6 +166,7 @@ void tst_qquickfocusscope::nested()
view->requestActivateWindow();
QTest::qWaitForWindowShown(view);
+ QTRY_VERIFY(view == qGuiApp->focusWindow());
QVERIFY(item1->hasActiveFocus() == true);
QVERIFY(item2->hasActiveFocus() == true);
@@ -191,6 +193,7 @@ void tst_qquickfocusscope::noFocus()
view->show();
view->requestActivateWindow();
QTest::qWaitForWindowShown(view);
+ QTRY_VERIFY(view == qGuiApp->focusWindow());
QVERIFY(item0->hasActiveFocus() == false);
QVERIFY(item1->hasActiveFocus() == false);
@@ -283,6 +286,7 @@ void tst_qquickfocusscope::forceFocus()
view->show();
view->requestActivateWindow();
QTest::qWaitForWindowShown(view);
+ QTRY_VERIFY(view == qGuiApp->focusWindow());
QVERIFY(item0->hasActiveFocus() == true);
QVERIFY(item1->hasActiveFocus() == true);
@@ -318,12 +322,8 @@ void tst_qquickfocusscope::noParentFocus()
view->show();
view->requestActivateWindow();
- qApp->processEvents();
-
-#ifdef Q_WS_X11
- // to be safe and avoid failing setFocus with window managers
- qt_x11_wait_for_window_manager(view);
-#endif
+ QTest::qWaitForWindowShown(view);
+ QTRY_VERIFY(view == qGuiApp->focusWindow());
QVERIFY(view->rootObject()->property("focus1") == false);
QVERIFY(view->rootObject()->property("focus2") == false);
@@ -352,6 +352,7 @@ void tst_qquickfocusscope::signalEmission()
view->requestActivateWindow();
QTest::qWaitForWindowShown(view);
+ QTRY_VERIFY(view == qGuiApp->focusWindow());
QVariant blue(QColor("blue"));
QVariant red(QColor("red"));
@@ -417,12 +418,8 @@ void tst_qquickfocusscope::forceActiveFocus()
view->show();
view->requestActivateWindow();
- qApp->processEvents();
-
-#ifdef Q_WS_X11
- // to be safe and avoid failing setFocus with window managers
- qt_x11_wait_for_window_manager(view);
-#endif
+ QTest::qWaitForWindowShown(view);
+ QTRY_VERIFY(view == qGuiApp->focusWindow());
QQuickItem *rootObject = view->rootObject();
QVERIFY(rootObject);
@@ -533,6 +530,8 @@ void tst_qquickfocusscope::canvasFocus()
QQuickView *view = new QQuickView;
view->setSource(QUrl::fromLocalFile(TESTDATA("canvasFocus.qml")));
+ QQuickView alternateView;
+
QQuickItem *rootObject = view->rootObject();
QVERIFY(rootObject);
@@ -558,8 +557,6 @@ void tst_qquickfocusscope::canvasFocus()
QSignalSpy scope2ActiveFocusSpy(scope2, SIGNAL(activeFocusChanged(bool)));
QSignalSpy item2ActiveFocusSpy(item2, SIGNAL(activeFocusChanged(bool)));
- QEXPECT_FAIL("", "QTBUG-21054 - Root item hasFocus returns true already", Abort);
-
QCOMPARE(rootItem->hasFocus(), false);
QCOMPARE(rootItem->hasActiveFocus(), false);
QCOMPARE(scope1->hasFocus(), true);
@@ -575,6 +572,7 @@ void tst_qquickfocusscope::canvasFocus()
view->requestActivateWindow();
QTest::qWaitForWindowShown(view);
+ QTRY_VERIFY(view == qGuiApp->focusWindow());
// Now the canvas has focus, active focus given to item1
QCOMPARE(rootItem->hasFocus(), true);
@@ -595,7 +593,12 @@ void tst_qquickfocusscope::canvasFocus()
QCOMPARE(item1ActiveFocusSpy.count(), 1);
- view->hide();
+ // view->hide(); // seemingly doesn't remove focus, so have an another view steal it.
+ alternateView.show();
+ alternateView.requestActivateWindow();
+ QTest::qWaitForWindowShown(&alternateView);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == &alternateView);
+
QCOMPARE(rootItem->hasFocus(), false);
QCOMPARE(rootItem->hasActiveFocus(), false);
QCOMPARE(scope1->hasFocus(), true);
@@ -636,6 +639,9 @@ void tst_qquickfocusscope::canvasFocus()
// give the canvas focus, and item2 will get active focus
view->show();
+ view->requestActivateWindow();
+ QTest::qWaitForWindowShown(view);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == view);
QCOMPARE(rootItem->hasFocus(), true);
QCOMPARE(rootItem->hasActiveFocus(), true);
diff --git a/tests/auto/declarative/qquickitem/tst_qquickitem.cpp b/tests/auto/declarative/qquickitem/tst_qquickitem.cpp
index 694fdc0b0c..35346c8236 100644
--- a/tests/auto/declarative/qquickitem/tst_qquickitem.cpp
+++ b/tests/auto/declarative/qquickitem/tst_qquickitem.cpp
@@ -239,6 +239,7 @@ void tst_qquickitem::simpleFocus()
{
QQuickCanvas canvas;
ensureFocus(&canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
QQuickItem *l1c1 = new TestItem(canvas.rootItem());
QQuickItem *l1c2 = new TestItem(canvas.rootItem());
@@ -289,6 +290,7 @@ void tst_qquickitem::scopedFocus()
{
QQuickCanvas canvas;
ensureFocus(&canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
QQuickItem *l1c1 = new TestItem(canvas.rootItem());
QQuickItem *l1c2 = new TestItem(canvas.rootItem());
@@ -368,6 +370,7 @@ void tst_qquickitem::addedToCanvas()
{
QQuickCanvas canvas;
ensureFocus(&canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
QQuickItem *item = new TestItem;
@@ -387,6 +390,7 @@ void tst_qquickitem::addedToCanvas()
{
QQuickCanvas canvas;
ensureFocus(&canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
QQuickItem *item = new TestItem(canvas.rootItem());
@@ -415,6 +419,7 @@ void tst_qquickitem::addedToCanvas()
{
QQuickCanvas canvas;
ensureFocus(&canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
QQuickItem *tree = new TestItem;
QQuickItem *c1 = new TestItem(tree);
@@ -438,6 +443,7 @@ void tst_qquickitem::addedToCanvas()
{
QQuickCanvas canvas;
ensureFocus(&canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
QQuickItem *tree = new TestFocusScope;
QQuickItem *c1 = new TestItem(tree);
QQuickItem *c2 = new TestItem(tree);
@@ -465,6 +471,7 @@ void tst_qquickitem::addedToCanvas()
{
QQuickCanvas canvas;
ensureFocus(&canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
QQuickItem *tree = new TestFocusScope;
QQuickItem *c1 = new TestItem(tree);
QQuickItem *c2 = new TestItem(tree);
@@ -490,6 +497,7 @@ void tst_qquickitem::addedToCanvas()
{
QQuickCanvas canvas;
ensureFocus(&canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
QQuickItem *child = new TestItem(canvas.rootItem());
QQuickItem *tree = new TestFocusScope;
QQuickItem *c1 = new TestItem(tree);
@@ -529,6 +537,7 @@ void tst_qquickitem::changeParent()
{
QQuickCanvas canvas;
ensureFocus(&canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
QQuickItem *child = new TestItem(canvas.rootItem());
FocusState focusState;
@@ -550,6 +559,7 @@ void tst_qquickitem::changeParent()
{
QQuickCanvas canvas;
ensureFocus(&canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
QQuickItem *child = new TestItem(canvas.rootItem());
QQuickItem *child2 = new TestItem(canvas.rootItem());
@@ -570,6 +580,7 @@ void tst_qquickitem::changeParent()
{
QQuickCanvas canvas;
ensureFocus(&canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
QQuickItem *child = new TestItem(canvas.rootItem());
QQuickItem *child2 = new TestFocusScope(canvas.rootItem());
QQuickItem *item = new TestItem(child);
@@ -591,6 +602,7 @@ void tst_qquickitem::changeParent()
{
QQuickCanvas canvas;
ensureFocus(&canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
QQuickItem *child = new TestItem(canvas.rootItem());
QQuickItem *child2 = new TestFocusScope(canvas.rootItem());
QQuickItem *item = new TestItem(child2);
@@ -612,6 +624,7 @@ void tst_qquickitem::changeParent()
{
QQuickCanvas canvas;
ensureFocus(&canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
QQuickItem *child = new TestItem(canvas.rootItem());
QQuickItem *child2 = new TestFocusScope(canvas.rootItem());
QQuickItem *item = new TestItem(child2);
diff --git a/tests/auto/declarative/qquickitem2/tst_qquickitem.cpp b/tests/auto/declarative/qquickitem2/tst_qquickitem.cpp
index 711ca17ae1..648dbe29bb 100644
--- a/tests/auto/declarative/qquickitem2/tst_qquickitem.cpp
+++ b/tests/auto/declarative/qquickitem2/tst_qquickitem.cpp
@@ -213,12 +213,9 @@ void tst_QQuickItem::keys()
canvas->setSource(QUrl::fromLocalFile(TESTDATA("keystest.qml")));
canvas->show();
- qApp->processEvents();
-
- QEvent wa(QEvent::WindowActivate);
- QApplication::sendEvent(canvas, &wa);
- QFocusEvent fe(QEvent::FocusIn);
- QApplication::sendEvent(canvas, &fe);
+ canvas->requestActivateWindow();
+ QTest::qWaitForWindowShown(canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == canvas);
QVERIFY(canvas->rootObject());
QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), true);
@@ -334,16 +331,13 @@ void tst_QQuickItem::keysProcessingOrder()
canvas->setSource(QUrl::fromLocalFile(TESTDATA("keyspriority.qml")));
canvas->show();
- qApp->processEvents();
+ canvas->requestActivateWindow();
+ QTest::qWaitForWindowShown(canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == canvas);
KeyTestItem *testItem = qobject_cast<KeyTestItem*>(canvas->rootObject());
QVERIFY(testItem);
- QEvent wa(QEvent::WindowActivate);
- QApplication::sendEvent(canvas, &wa);
- QFocusEvent fe(QEvent::FocusIn);
- QApplication::sendEvent(canvas, &fe);
-
QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
QApplication::sendEvent(canvas, &key);
QCOMPARE(testObject->mKey, int(Qt::Key_A));
@@ -546,12 +540,9 @@ void tst_QQuickItem::keyNavigation()
canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml")));
canvas->show();
- qApp->processEvents();
-
- QEvent wa(QEvent::WindowActivate);
- QApplication::sendEvent(canvas, &wa);
- QFocusEvent fe(QEvent::FocusIn);
- QApplication::sendEvent(canvas, &fe);
+ canvas->requestActivateWindow();
+ QTest::qWaitForWindowShown(canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == canvas);
QQuickItem *item = findItem<QQuickItem>(canvas->rootObject(), "item1");
QVERIFY(item);
@@ -626,7 +617,9 @@ void tst_QQuickItem::keyNavigation_RightToLeft()
canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml")));
canvas->show();
- qApp->processEvents();
+ canvas->requestActivateWindow();
+ QTest::qWaitForWindowShown(canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == canvas);
QQuickItem *rootItem = qobject_cast<QQuickItem*>(canvas->rootObject());
QVERIFY(rootItem);
@@ -679,12 +672,9 @@ void tst_QQuickItem::keyNavigation_skipNotVisible()
canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml")));
canvas->show();
- qApp->processEvents();
-
- QEvent wa(QEvent::WindowActivate);
- QApplication::sendEvent(canvas, &wa);
- QFocusEvent fe(QEvent::FocusIn);
- QApplication::sendEvent(canvas, &fe);
+ canvas->requestActivateWindow();
+ QTest::qWaitForWindowShown(canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == canvas);
QQuickItem *item = findItem<QQuickItem>(canvas->rootObject(), "item1");
QVERIFY(item);
@@ -757,7 +747,9 @@ void tst_QQuickItem::keyNavigation_implicitSetting()
canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest_implicit.qml")));
canvas->show();
- qApp->processEvents();
+ canvas->requestActivateWindow();
+ QTest::qWaitForWindowShown(canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == canvas);
QEvent wa(QEvent::WindowActivate);
QApplication::sendEvent(canvas, &wa);
@@ -1056,8 +1048,9 @@ void tst_QQuickItem::propertyChanges()
canvas->setBaseSize(QSize(300, 300));
canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
canvas->show();
-
+ canvas->requestActivateWindow();
QTest::qWaitForWindowShown(canvas);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == canvas);
QQuickItem *item = findItem<QQuickItem>(canvas->rootObject(), "item");
QQuickItem *parentItem = findItem<QQuickItem>(canvas->rootObject(), "parentItem");
diff --git a/tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp
index a0d36d6e9d..86c33a64d8 100644
--- a/tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp
@@ -1683,31 +1683,18 @@ void tst_qquicktextedit::cursorVisible()
QCOMPARE(edit.isCursorVisible(), true);
QCOMPARE(spy.count(), 5);
- QEXPECT_FAIL("", "Most likely a side-effect of QTBUG-21489", Abort);
- view.setWindowState(Qt::WindowNoState);
+ QQuickView alternateView;
+ alternateView.show();
+ alternateView.requestActivateWindow();
+ QTest::qWaitForWindowShown(&alternateView);
+
QCOMPARE(edit.isCursorVisible(), false);
QCOMPARE(spy.count(), 6);
view.requestActivateWindow();
+ QTest::qWaitForWindowShown(&view);
QCOMPARE(edit.isCursorVisible(), true);
QCOMPARE(spy.count(), 7);
-
- // on mac, setActiveWindow(0) on mac does not deactivate the current application
- // (you have to switch to a different app or hide the current app to trigger this)
-#if !defined(Q_WS_MAC)
- // on mac, setActiveWindow(0) on mac does not deactivate the current application
- // (you have to switch to a different app or hide the current app to trigger this)
-// QApplication::setActiveWindow(0);
-// QTRY_COMPARE(QApplication::focusWindow(), static_cast<QWidget *>(0));
-// QCOMPARE(edit.isCursorVisible(), false);
-// QCOMPARE(spy.count(), 8);
-
-// view.requestActivateWindow();
-// QTest::qWaitForWindowShown(&view);
-// QTRY_COMPARE(view.windowState(), Qt::WindowActive);
-// QCOMPARE(edit.isCursorVisible(), true);
-// QCOMPARE(spy.count(), 9);
-#endif
}
void tst_qquicktextedit::delegateLoading_data()
diff --git a/tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp
index 8c8166b2f1..23224d0452 100644
--- a/tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp
@@ -1798,30 +1798,18 @@ void tst_qquicktextinput::cursorVisible()
QCOMPARE(input.isCursorVisible(), true);
QCOMPARE(spy.count(), 5);
- view.setWindowState(Qt::WindowNoState);
- QEXPECT_FAIL("", "Most likely a side-effect of QTBUG-21489", Abort);
+ QQuickView alternateView;
+ alternateView.show();
+ alternateView.requestActivateWindow();
+ QTest::qWaitForWindowShown(&alternateView);
+
QCOMPARE(input.isCursorVisible(), false);
QCOMPARE(spy.count(), 6);
view.requestActivateWindow();
+ QTest::qWaitForWindowShown(&view);
QCOMPARE(input.isCursorVisible(), true);
QCOMPARE(spy.count(), 7);
-
- // on mac, setActiveWindow(0) on mac does not deactivate the current application
- // (you have to switch to a different app or hide the current app to trigger this)
-#if !defined(Q_WS_MAC)
- // QGuiApplication has no equivalent of setActiveWindow(0). Is this different to clearing the
- // active state of the window or can it be removed?
-// QApplication::setActiveWindow(0);
-// QTRY_COMPARE(QApplication::focusWindow(), static_cast<QWidget *>(0));
-// QCOMPARE(input.isCursorVisible(), false);
-// QCOMPARE(spy.count(), 8);
-
-// view.requestActivateWindow();
-// QTRY_COMPARE(view.windowState(), Qt::WindowActive);
-// QCOMPARE(input.isCursorVisible(), true);
-// QCOMPARE(spy.count(), 9);
-#endif
}
void tst_qquicktextinput::cursorRectangle()