summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com>2009-08-24 14:10:22 (GMT)
committerAndreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com>2009-08-24 14:15:25 (GMT)
commit1a71668483380f45cacda30cc55424d09def0636 (patch)
tree3835f12ad1702cc8ad318485f5d131aa2f94d301
parentc5b34ea67668e60a61c463633eaae0e629fee606 (diff)
downloadQt-1a71668483380f45cacda30cc55424d09def0636.zip
Qt-1a71668483380f45cacda30cc55424d09def0636.tar.gz
Qt-1a71668483380f45cacda30cc55424d09def0636.tar.bz2
Fix Qt::ClickFocus for QGraphicsProxyWidget.
This fixes click-focus for the Embedded Dialogs demo and the Pad Navigator demo. In Qt 4.6, the behavior of the spontaneous-bit in events has changed. This has happened in a number of submits that also modify Graphics View to have the correct behavior. Somewhere on the line, the spontaneous bit has been reset, preventing QApplicationPrivate's ClickFocus handling to kick in. This again causes the Embedded Dialogs demo to not give focus to widgets that are clicked. This fix is not likely to be 100% correct. What it does is ensure that the spont-bit survives a call to qt_sendSpontaneousEvent (as this bit is for some reason reset at the end of QApplicationPrivate::notify_helper), and this fixes the most apparent regression in ClickFocus handling. Pending closer review. The fix includes an autotest that should be kept if the fix is reverted. Reviewed-by: bnilsen
-rw-r--r--src/corelib/kernel/qcoreevent.h1
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp8
-rw-r--r--tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp85
3 files changed, 93 insertions, 1 deletions
diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h
index babb89d..75af3e7 100644
--- a/src/corelib/kernel/qcoreevent.h
+++ b/src/corelib/kernel/qcoreevent.h
@@ -324,6 +324,7 @@ private:
friend class QGraphicsView;
friend class QGraphicsViewPrivate;
friend class QGraphicsScenePrivate;
+ friend class QGraphicsWidget;
};
class Q_CORE_EXPORT QTimerEvent : public QEvent
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
index 157fbe5..033723a 100644
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ b/src/gui/graphicsview/qgraphicswidget.cpp
@@ -168,6 +168,8 @@ QT_BEGIN_NAMESPACE
\sa QGraphicsProxyWidget, QGraphicsItem, {Widgets and Layouts}
*/
+bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
+
/*!
Constructs a QGraphicsWidget instance. The optional \a parent argument is
passed to QGraphicsItem's constructor. The optional \a wFlags argument
@@ -1097,7 +1099,11 @@ QVariant QGraphicsWidget::propertyChange(const QString &propertyName, const QVar
*/
bool QGraphicsWidget::sceneEvent(QEvent *event)
{
- return QCoreApplication::sendEvent(this, event) || QGraphicsItem::sceneEvent(event);
+ bool spont = event->spontaneous();
+ if (spont ? qt_sendSpontaneousEvent(this, event) : QApplication::sendEvent(this, event))
+ return true;
+ event->spont = spont;
+ return QGraphicsItem::sceneEvent(event);
}
/*!
diff --git a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
index 7536855..462dbfa 100644
--- a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
+++ b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
@@ -180,6 +180,7 @@ private slots:
void comboboxWindowFlags();
void updateAndDelete();
void inputMethod();
+ void clickFocus();
};
// Subclass that exposes the protected functions.
@@ -3299,6 +3300,90 @@ void tst_QGraphicsProxyWidget::inputMethod()
}
}
+void tst_QGraphicsProxyWidget::clickFocus()
+{
+ QGraphicsScene scene;
+ scene.setItemIndexMethod(QGraphicsScene::NoIndex);
+ QGraphicsProxyWidget *proxy = scene.addWidget(new QLineEdit);
+
+ EventSpy proxySpy(proxy);
+ EventSpy widgetSpy(proxy->widget());
+
+ QGraphicsView view(&scene);
+ view.setFrameStyle(0);
+ view.resize(300, 300);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QTest::qWait(250);
+
+ QVERIFY(!proxy->hasFocus());
+ QVERIFY(!proxy->widget()->hasFocus());
+
+ QCOMPARE(proxySpy.counts[QEvent::FocusIn], 0);
+ QCOMPARE(proxySpy.counts[QEvent::FocusOut], 0);
+ QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 0);
+ QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 0);
+
+ // Spontaneous mouse click sets focus on a clickable widget.
+ QPointF lineEditCenter = proxy->mapToScene(proxy->boundingRect().center());
+ QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(lineEditCenter));
+ QVERIFY(proxy->hasFocus());
+ QVERIFY(proxy->widget()->hasFocus());
+ QCOMPARE(proxySpy.counts[QEvent::FocusIn], 1);
+ QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 1);
+
+ scene.setFocusItem(0);
+ QVERIFY(!proxy->hasFocus());
+ QVERIFY(!proxy->widget()->hasFocus());
+ QCOMPARE(proxySpy.counts[QEvent::FocusOut], 1);
+ QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 1);
+
+ // Non-spontaneous mouse click sets focus if the widget has been clicked before
+ {
+ QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
+ event.setScenePos(lineEditCenter);
+ event.setButton(Qt::LeftButton);
+ qApp->sendEvent(&scene, &event);
+ QVERIFY(proxy->hasFocus());
+ QVERIFY(proxy->widget()->hasFocus());
+ QCOMPARE(proxySpy.counts[QEvent::FocusIn], 2);
+ QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 2);
+ }
+
+ scene.setFocusItem(0);
+ proxy->setWidget(new QLineEdit); // resets focusWidget
+ QVERIFY(!proxy->hasFocus());
+ QVERIFY(!proxy->widget()->hasFocus());
+ QCOMPARE(proxySpy.counts[QEvent::FocusOut], 2);
+ QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 2);
+
+ // Non-spontaneous mouse click does not set focus on the embedded widget.
+ {
+ QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
+ event.setScenePos(lineEditCenter);
+ event.setButton(Qt::LeftButton);
+ qApp->sendEvent(&scene, &event);
+ QVERIFY(!proxy->hasFocus());
+ QVERIFY(!proxy->widget()->hasFocus());
+ QCOMPARE(proxySpy.counts[QEvent::FocusIn], 2);
+ QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 2);
+ }
+
+ scene.setFocusItem(0);
+ QVERIFY(!proxy->hasFocus());
+ QVERIFY(!proxy->widget()->hasFocus());
+ QCOMPARE(proxySpy.counts[QEvent::FocusOut], 2);
+ QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 2);
+
+ // Spontaneous click on non-clickable widget does not give focus.
+ proxy->widget()->setFocusPolicy(Qt::NoFocus);
+ QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(lineEditCenter));
+ QVERIFY(!proxy->hasFocus());
+ QVERIFY(!proxy->widget()->hasFocus());
+}
+
QTEST_MAIN(tst_QGraphicsProxyWidget)
#include "tst_qgraphicsproxywidget.moc"