From e8275c319fe9433682bc95716168c330a3ebdc88 Mon Sep 17 00:00:00 2001
From: Berthold Krevert <berthold.krevert@basyskom.com>
Date: Wed, 30 Apr 2014 20:33:07 +0200
Subject: [PATCH] Store information about focus reason in QQuickWindowPrivate

QtQuickControl's Desktop style needs to know whether the last focus change
was requested by keyboard or not. With this information the Desktop style
is able to set the QStyleOption accordingly. Without the flag, some of
the QStyles (QFusionStyle, QGtkStyle) don't render a focus rectangle.

This patch is needed by #change,84389 in QtQuickControls

Change-Id: Ia06f56b018cd35eea933892a4c50e0aa7328042d
Reviewed-by: J-P Nurmi <jpnurmi@digia.com>
Reviewed-by: Liang Qi <liang.qi@digia.com>
---
 src/quick/items/qquickwindow.cpp              |  5 ++++
 src/quick/items/qquickwindow_p.h              |  2 ++
 .../quick/qquickwindow/tst_qquickwindow.cpp   | 28 +++++++++++++++++++
 3 files changed, 35 insertions(+)

diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index d6cbae7d2a..b9713c7b6a 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -407,6 +407,7 @@ QQuickWindowPrivate::QQuickWindowPrivate()
     , persistentSceneGraph(true)
     , lastWheelEventAccepted(false)
     , componentCompleted(true)
+    , lastFocusReason(Qt::OtherFocusReason)
     , renderTarget(0)
     , renderTargetId(0)
     , incubationController(0)
@@ -710,6 +711,8 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, Q
     QQuickItem *currentActiveFocusItem = activeFocusItem;
     QQuickItem *newActiveFocusItem = 0;
 
+    lastFocusReason = reason;
+
     QVarLengthArray<QQuickItem *, 20> changed;
 
     // Does this change the active focus?
@@ -814,6 +817,8 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item,
     QQuickItem *oldActiveFocusItem = 0;
     QQuickItem *newActiveFocusItem = 0;
 
+    lastFocusReason = reason;
+
     QVarLengthArray<QQuickItem *, 20> changed;
 
     Q_ASSERT(item == contentItem || item == scopePrivate->subFocusItem);
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 218425c08c..8faaf6489b 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -227,6 +227,8 @@ public:
     uint lastWheelEventAccepted : 1;
     bool componentCompleted : 1;
 
+    Qt::FocusReason lastFocusReason;
+
     QOpenGLFramebufferObject *renderTarget;
     uint renderTargetId;
     QSize renderTargetSize;
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index 18b0dd5132..de4067b6e5 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -328,6 +328,7 @@ private slots:
     void animationsWhileHidden();
 
     void focusObject();
+    void focusReason();
 
     void ignoreUnhandledMouseEvents();
 
@@ -1253,6 +1254,33 @@ void tst_qquickwindow::focusObject()
     QCOMPARE(focusObjectSpy.count(), 3);
 }
 
+void tst_qquickwindow::focusReason()
+{
+    QQuickWindow *window = new QQuickWindow;
+    QScopedPointer<QQuickWindow> cleanup(window);
+    window->resize(200, 200);
+    window->show();
+    QVERIFY(QTest::qWaitForWindowExposed(window));
+
+    QQuickItem *firstItem = new QQuickItem;
+    firstItem->setSize(QSizeF(100, 100));
+    firstItem->setParentItem(window->contentItem());
+
+    QQuickItem *secondItem = new QQuickItem;
+    secondItem->setSize(QSizeF(100, 100));
+    secondItem->setParentItem(window->contentItem());
+
+    firstItem->forceActiveFocus(Qt::OtherFocusReason);
+    QCOMPARE(QQuickWindowPrivate::get(window)->lastFocusReason, Qt::OtherFocusReason);
+
+    secondItem->forceActiveFocus(Qt::TabFocusReason);
+    QCOMPARE(QQuickWindowPrivate::get(window)->lastFocusReason, Qt::TabFocusReason);
+
+    firstItem->forceActiveFocus(Qt::BacktabFocusReason);
+    QCOMPARE(QQuickWindowPrivate::get(window)->lastFocusReason, Qt::BacktabFocusReason);
+
+}
+
 void tst_qquickwindow::ignoreUnhandledMouseEvents()
 {
     QQuickWindow *window = new QQuickWindow;
-- 
GitLab