Widgets: Never revoke focus by click on focused widget.

When clicking on a widget currently focused, w/o having Qt::ClickFocus
set as focus policy, the focus should stay on the widget and not get
propagated to the widget's parent.

Task-number: QTBUG-34042

Change-Id: I53f1153829cc7228de02a90e38125b5cf4ee5008
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
This commit is contained in:
Christoph Schleifenbaum 2013-11-16 17:17:15 +01:00 committed by The Qt Project
parent cd93a2c0e1
commit 7e768dde39
2 changed files with 68 additions and 0 deletions

View File

@ -3761,6 +3761,16 @@ void QApplicationPrivate::giveFocusAccordingToFocusPolicy(QWidget *widget, QEven
}
if (focusWidget->isWindow())
break;
// find out whether this widget (or its proxy) already has focus
QWidget *f = focusWidget;
if (focusWidget->d_func()->extra && focusWidget->d_func()->extra->focus_proxy)
f = focusWidget->d_func()->extra->focus_proxy;
// if it has, stop here.
// otherwise a click on the focused widget would remove its focus if ClickFocus isn't set
if (f->hasFocus())
break;
localPos += focusWidget->pos();
focusWidget = focusWidget->parentWidget();
}

View File

@ -153,6 +153,7 @@ private slots:
void focusChanged();
void focusOut();
void focusMouseClick();
void execAfterExit();
@ -1771,6 +1772,63 @@ void tst_QApplication::focusOut()
QTest::qWait(2000);
}
class SpontaneousEvent
{
Q_GADGET
QDOC_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
Q_ENUMS(Type)
public:
enum Type {
Void
};
virtual ~SpontaneousEvent() {}
QEventPrivate *d;
ushort t;
ushort posted : 1;
ushort spont : 1;
};
void tst_QApplication::focusMouseClick()
{
int argc = 1;
QApplication app(argc, &argv0);
QWidget w;
w.setFocusPolicy(Qt::StrongFocus);
QWidget w2(&w);
w2.setFocusPolicy(Qt::TabFocus);
w.show();
w.setFocus();
QTRY_COMPARE(QApplication::focusWidget(), &w);
// front most widget has Qt::TabFocus, parent widget accepts clicks as well
// now send a mouse button press event and check what happens with the focus
// it should be given to the parent widget
QMouseEvent ev(QEvent::MouseButtonPress, QPointF(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
reinterpret_cast<SpontaneousEvent *>(&ev)->spont = 1;
QVERIFY(ev.spontaneous());
qApp->notify(&w2, &ev);
QCOMPARE(QApplication::focusWidget(), &w);
// then we give the inner widget strong focus -> it should get focus
w2.setFocusPolicy(Qt::StrongFocus);
reinterpret_cast<SpontaneousEvent *>(&ev)->spont = 1;
QVERIFY(ev.spontaneous());
qApp->notify(&w2, &ev);
QTRY_COMPARE(QApplication::focusWidget(), &w2);
// now back to tab focus and click again (it already had focus) -> focus should stay
// (focus was revoked as of QTBUG-34042)
w2.setFocusPolicy(Qt::TabFocus);
reinterpret_cast<SpontaneousEvent *>(&ev)->spont = 1;
QVERIFY(ev.spontaneous());
qApp->notify(&w2, &ev);
QCOMPARE(QApplication::focusWidget(), &w2);
}
void tst_QApplication::execAfterExit()
{
int argc = 1;