From 1b16acceb174b89c7a95e204bcbc46e3a8857da4 Mon Sep 17 00:00:00 2001
From: Michael Brasser <michael.brasser@jollamobile.com>
Date: Thu, 5 Dec 2013 11:35:44 -0600
Subject: [PATCH] Only emit focusObjectChanged when an actual change occurs.

Change-Id: If18b460a8773e5cac597c02c51836b79711c20f4
Done-with: Matthew Vogt <matthew.vogt@jollamobile.com>
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Reviewed-by: Alan Alpert <aalpert@blackberry.com>
---
 src/quick/items/qquickwindow.cpp                  |  8 ++++++--
 tests/auto/quick/qquickwindow/data/focus.qml      |  4 ++++
 .../auto/quick/qquickwindow/tst_qquickwindow.cpp  | 15 +++++++++++++++
 3 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 3a8e177bbb..c111090520 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -660,6 +660,7 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, Q
     QQuickItemPrivate *scopePrivate = scope ? QQuickItemPrivate::get(scope) : 0;
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
 
+    QQuickItem *currentActiveFocusItem = activeFocusItem;
     QQuickItem *newActiveFocusItem = 0;
 
     QVarLengthArray<QQuickItem *, 20> changed;
@@ -736,7 +737,8 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, Q
         q->sendEvent(newActiveFocusItem, &event);
     }
 
-    emit q->focusObjectChanged(activeFocusItem);
+    if (activeFocusItem != currentActiveFocusItem)
+        emit q->focusObjectChanged(activeFocusItem);
 
     if (!changed.isEmpty())
         notifyFocusChangesRecur(changed.data(), changed.count() - 1);
@@ -763,6 +765,7 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item,
             return;//No focus, nothing to do.
     }
 
+    QQuickItem *currentActiveFocusItem = activeFocusItem;
     QQuickItem *oldActiveFocusItem = 0;
     QQuickItem *newActiveFocusItem = 0;
 
@@ -819,7 +822,8 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item,
         q->sendEvent(newActiveFocusItem, &event);
     }
 
-    emit q->focusObjectChanged(activeFocusItem);
+    if (activeFocusItem != currentActiveFocusItem)
+        emit q->focusObjectChanged(activeFocusItem);
 
     if (!changed.isEmpty())
         notifyFocusChangesRecur(changed.data(), changed.count() - 1);
diff --git a/tests/auto/quick/qquickwindow/data/focus.qml b/tests/auto/quick/qquickwindow/data/focus.qml
index 899b999cdc..fa8ae9dc69 100644
--- a/tests/auto/quick/qquickwindow/data/focus.qml
+++ b/tests/auto/quick/qquickwindow/data/focus.qml
@@ -12,4 +12,8 @@ Window.Window {
      Item {
           objectName: "item2"
      }
+
+     FocusScope {
+         Item { objectName: "item3" }
+     }
 }
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index b09f80a634..107d1d71f7 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -1145,20 +1145,35 @@ void tst_qquickwindow::focusObject()
     QQuickWindow *window = qobject_cast<QQuickWindow*>(created);
     QVERIFY(window);
 
+    QSignalSpy focusObjectSpy(window, SIGNAL(focusObjectChanged(QObject*)));
+
     window->show();
     QVERIFY(QTest::qWaitForWindowExposed(window));
     window->requestActivate();
     QVERIFY(QTest::qWaitForWindowActive(window));
 
+    QCOMPARE(window->contentItem(), window->focusObject());
+    QCOMPARE(focusObjectSpy.count(), 1);
+
     QQuickItem *item1 = window->findChild<QQuickItem*>("item1");
     QVERIFY(item1);
     item1->setFocus(true);
     QCOMPARE(item1, window->focusObject());
+    QCOMPARE(focusObjectSpy.count(), 2);
 
     QQuickItem *item2 = window->findChild<QQuickItem*>("item2");
     QVERIFY(item2);
     item2->setFocus(true);
     QCOMPARE(item2, window->focusObject());
+    QCOMPARE(focusObjectSpy.count(), 3);
+
+    // set focus for item in non-focused focus scope and
+    // ensure focusObject does not change and signal is not emitted
+    QQuickItem *item3 = window->findChild<QQuickItem*>("item3");
+    QVERIFY(item3);
+    item3->setFocus(true);
+    QCOMPARE(item2, window->focusObject());
+    QCOMPARE(focusObjectSpy.count(), 3);
 }
 
 void tst_qquickwindow::ignoreUnhandledMouseEvents()
-- 
GitLab