Implement QWidgetPrivate::focusObject()

QWidgetPrivate::focusObject() always returns nullptr. That has lead to
mismatches between QGuiApplication::focusObject() and
QApplication::focusWidget(), when a widget got focus by the window
system (e.g. mouse click).

This patch implements QWidgetPrivate::focusObject.
It returns the current widget, if it doesn't have a focus proxy.
If it has a focus proxy, it resolves the proxy chain and returns the
deepest focus proxy.
(Note: It does not return QWidget::focusWidget(), because the focus
widget might not yet have been set, when the method is called).

Fixes: QTBUG-92464
Fixes: QTBUG-108522
Pick-to: 6.6 6.5 6.2
Done-With: Liang Qi <liang.qi@qt.io>
Change-Id: Icf01e8ac4fc5f722fbf8e0ca5a562617ae9ae8f2
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Reviewed-by: Liang Qi <liang.qi@qt.io>
This commit is contained in:
Axel Spoerl 2023-05-10 10:14:20 +02:00
parent 3f72b0d5fc
commit f83ea89622
3 changed files with 9 additions and 1 deletions

View File

@ -6853,6 +6853,13 @@ QWidget *QWidget::focusWidget() const
return const_cast<QWidget *>(d_func()->focus_child);
}
QObject *QWidgetPrivate::focusObject()
{
Q_Q(QWidget);
QWidget *proxy = deepestFocusProxy();
return proxy ? proxy : q;
}
/*!
Returns the next widget in this widget's focus chain.

View File

@ -579,7 +579,7 @@ public:
inline QRect mapFromWS(const QRect &r) const
{ return r.translated(data.wrect.topLeft()); }
virtual QObject *focusObject() { return nullptr; }
virtual QObject *focusObject();
virtual QPlatformBackingStoreRhiConfig rhiConfig() const { return {}; }

View File

@ -1687,6 +1687,7 @@ void tst_QCompleter::QTBUG_14292_filesystem()
QTRY_VERIFY(comp.popup()->isVisible());
QCOMPARE(comp.popup()->model()->rowCount(), 2);
QApplication::processEvents();
QCOMPARE(qApp->focusObject(), &edit); // for QTBUG_108522
QTest::keyClick(&edit, 'h');
QCOMPARE(comp.popup()->model()->rowCount(), 2);
QTest::keyClick(&edit, 'e');