Make QQuickItemPrivate::setLastFocusChangeReason virtual
Fix a regression that 644ee4d234
introduced by moving focusReason to QQuickItemPrivate. The already
existing QQuickControl::focusReasonChanged signal was not being
emitted anymore when the focus would change. To fix, make
setLastFocusChangeReason virtual in QQuickItemPrivate so that the
subclasses can override and emit the relevant signals.
Fixes: QTBUG-125725
Pick-to: 6.7 6.8
Change-Id: I88d664ec4fa3cc9262ee2703d63e7e716cac68e9
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
f859f23d07
commit
d887758bf4
|
@ -1744,12 +1744,13 @@ Qt::FocusReason QQuickItemPrivate::lastFocusChangeReason() const
|
|||
return static_cast<Qt::FocusReason>(focusReason);
|
||||
}
|
||||
|
||||
void QQuickItemPrivate::setLastFocusChangeReason(Qt::FocusReason reason)
|
||||
bool QQuickItemPrivate::setLastFocusChangeReason(Qt::FocusReason reason)
|
||||
{
|
||||
if (focusReason == reason)
|
||||
return;
|
||||
return false;
|
||||
|
||||
focusReason = reason;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -564,7 +564,7 @@ public:
|
|||
|
||||
bool setFocusIfNeeded(QEvent::Type);
|
||||
Qt::FocusReason lastFocusChangeReason() const;
|
||||
void setLastFocusChangeReason(Qt::FocusReason reason);
|
||||
virtual bool setLastFocusChangeReason(Qt::FocusReason reason);
|
||||
|
||||
QTransform windowToItemTransform() const;
|
||||
QTransform itemToWindowTransform() const;
|
||||
|
|
|
@ -911,6 +911,19 @@ void QQuickControlPrivate::itemFocusChanged(QQuickItem *item, Qt::FocusReason re
|
|||
setLastFocusChangeReason(reason);
|
||||
}
|
||||
|
||||
bool QQuickControlPrivate::setLastFocusChangeReason(Qt::FocusReason reason)
|
||||
{
|
||||
Q_Q(QQuickControl);
|
||||
Qt::FocusReason oldReason = static_cast<Qt::FocusReason>(focusReason);
|
||||
const auto focusReasonChanged = QQuickItemPrivate::setLastFocusChangeReason(reason);
|
||||
if (focusReasonChanged)
|
||||
emit q->focusReasonChanged();
|
||||
if (isKeyFocusReason(oldReason) != isKeyFocusReason(reason))
|
||||
emit q->visualFocusChanged();
|
||||
|
||||
return focusReasonChanged;
|
||||
}
|
||||
|
||||
QQuickControl::QQuickControl(QQuickItem *parent)
|
||||
: QQuickItem(*(new QQuickControlPrivate), parent)
|
||||
{
|
||||
|
@ -1384,11 +1397,7 @@ Qt::FocusReason QQuickControl::focusReason() const
|
|||
void QQuickControl::setFocusReason(Qt::FocusReason reason)
|
||||
{
|
||||
Q_D(QQuickControl);
|
||||
Qt::FocusReason oldReason = static_cast<Qt::FocusReason>(d->focusReason);
|
||||
d->setLastFocusChangeReason(reason);
|
||||
emit focusReasonChanged();
|
||||
if (isKeyFocusReason(oldReason) != isKeyFocusReason(reason))
|
||||
emit visualFocusChanged();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -1403,7 +1412,7 @@ void QQuickControl::setFocusReason(Qt::FocusReason reason)
|
|||
\l Item::activeFocus. This ensures that key focus is only visualized when
|
||||
interacting with keys - not when interacting via touch or mouse.
|
||||
|
||||
\sa Item::focusReason, Item::activeFocus
|
||||
\sa focusReason, Item::activeFocus
|
||||
*/
|
||||
bool QQuickControl::hasVisualFocus() const
|
||||
{
|
||||
|
@ -1969,22 +1978,12 @@ QFont QQuickControl::defaultFont() const
|
|||
|
||||
void QQuickControl::focusInEvent(QFocusEvent *event)
|
||||
{
|
||||
Q_D(QQuickControl);
|
||||
Qt::FocusReason oldReason = static_cast<Qt::FocusReason>(d->focusReason);
|
||||
QQuickItem::focusInEvent(event);
|
||||
Qt::FocusReason reason = event->reason();
|
||||
if (isKeyFocusReason(oldReason) != isKeyFocusReason(reason))
|
||||
emit visualFocusChanged();
|
||||
}
|
||||
|
||||
void QQuickControl::focusOutEvent(QFocusEvent *event)
|
||||
{
|
||||
Q_D(QQuickControl);
|
||||
Qt::FocusReason oldReason = static_cast<Qt::FocusReason>(d->focusReason);
|
||||
QQuickItem::focusOutEvent(event);
|
||||
Qt::FocusReason reason = event->reason();
|
||||
if (isKeyFocusReason(oldReason) != isKeyFocusReason(reason))
|
||||
emit visualFocusChanged();
|
||||
}
|
||||
|
||||
#if QT_CONFIG(quicktemplates2_hover)
|
||||
|
|
|
@ -155,6 +155,8 @@ public:
|
|||
void itemDestroyed(QQuickItem *item) override;
|
||||
void itemFocusChanged(QQuickItem *item, Qt::FocusReason reason) override;
|
||||
|
||||
bool setLastFocusChangeReason(Qt::FocusReason) override;
|
||||
|
||||
virtual qreal getContentWidth() const;
|
||||
virtual qreal getContentHeight() const;
|
||||
|
||||
|
|
|
@ -472,6 +472,16 @@ QPalette QQuickTextAreaPrivate::defaultPalette() const
|
|||
return QQuickTheme::palette(QQuickTheme::TextArea);
|
||||
}
|
||||
|
||||
bool QQuickTextAreaPrivate::setLastFocusChangeReason(Qt::FocusReason reason)
|
||||
{
|
||||
Q_Q(QQuickTextArea);
|
||||
const auto focusReasonChanged = QQuickItemPrivate::setLastFocusChangeReason(reason);
|
||||
if (focusReasonChanged)
|
||||
emit q->focusReasonChanged();
|
||||
|
||||
return focusReasonChanged;
|
||||
}
|
||||
|
||||
QQuickTextArea::QQuickTextArea(QQuickItem *parent)
|
||||
: QQuickTextEdit(*(new QQuickTextAreaPrivate), parent)
|
||||
{
|
||||
|
@ -663,7 +673,6 @@ void QQuickTextArea::setFocusReason(Qt::FocusReason reason)
|
|||
{
|
||||
Q_D(QQuickTextArea);
|
||||
d->setLastFocusChangeReason(reason);
|
||||
emit focusReasonChanged();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -96,6 +96,8 @@ public:
|
|||
|
||||
QPalette defaultPalette() const override;
|
||||
|
||||
bool setLastFocusChangeReason(Qt::FocusReason reason) override;
|
||||
|
||||
#if QT_CONFIG(quicktemplates2_hover)
|
||||
bool hovered = false;
|
||||
bool explicitHoverEnabled = false;
|
||||
|
|
|
@ -364,6 +364,16 @@ QPalette QQuickTextFieldPrivate::defaultPalette() const
|
|||
return QQuickTheme::palette(QQuickTheme::TextField);
|
||||
}
|
||||
|
||||
bool QQuickTextFieldPrivate::setLastFocusChangeReason(Qt::FocusReason reason)
|
||||
{
|
||||
Q_Q(QQuickTextField);
|
||||
const auto focusReasonChanged = QQuickItemPrivate::setLastFocusChangeReason(reason);
|
||||
if (focusReasonChanged)
|
||||
emit q->focusReasonChanged();
|
||||
|
||||
return focusReasonChanged;
|
||||
}
|
||||
|
||||
QQuickTextField::QQuickTextField(QQuickItem *parent)
|
||||
: QQuickTextInput(*(new QQuickTextFieldPrivate), parent)
|
||||
{
|
||||
|
@ -549,7 +559,6 @@ void QQuickTextField::setFocusReason(Qt::FocusReason reason)
|
|||
{
|
||||
Q_D(QQuickTextField);
|
||||
d->setLastFocusChangeReason(reason);
|
||||
emit focusReasonChanged();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -94,6 +94,8 @@ public:
|
|||
|
||||
QPalette defaultPalette() const override;
|
||||
|
||||
bool setLastFocusChangeReason(Qt::FocusReason reason) override;
|
||||
|
||||
#if QT_CONFIG(quicktemplates2_hover)
|
||||
bool hovered = false;
|
||||
bool explicitHoverEnabled = false;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <QtQuickTestUtils/private/visualtestutils_p.h>
|
||||
#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
|
||||
#include <QtQuickTemplates2/private/qquickcontrol_p.h>
|
||||
#include <QtQuickTemplates2/private/qquicktextfield_p.h>
|
||||
#include <QtQuickControls2/qquickstyle.h>
|
||||
#include <QtQuickControlsTestUtils/private/controlstestutils_p.h>
|
||||
|
||||
|
@ -244,7 +245,7 @@ void tst_focus::reason()
|
|||
QQuickControl *customText = view.findChild<QQuickControl *>("customText");
|
||||
QQuickControl *customItem = view.findChild<QQuickControl *>("customItem");
|
||||
// not a QQuickControl subclass
|
||||
QQuickItem *textfield = view.findChild<QQuickItem *>("textfield");
|
||||
QQuickTextField *textfield = view.findChild<QQuickTextField *>("textfield");
|
||||
|
||||
// helper for clicking into a control
|
||||
const auto itemCenter = [](const QQuickItem *item) -> QPoint {
|
||||
|
@ -273,21 +274,35 @@ void tst_focus::reason()
|
|||
}
|
||||
QCOMPARE(control->focusReason(), Qt::ActiveWindowFocusReason);
|
||||
|
||||
QSignalSpy controlSpy(control, SIGNAL(focusReasonChanged()));
|
||||
QSignalSpy textfieldSpy(textfield, SIGNAL(focusReasonChanged()));
|
||||
QSignalSpy customItemSpy(customItem, SIGNAL(focusReasonChanged()));
|
||||
int controlSpyCount = 0, textfieldSpyCount = 0, customItemSpyCount = 0;
|
||||
QVERIFY(!controlSpy.count());
|
||||
QVERIFY(!textfieldSpy.count());
|
||||
QVERIFY(!customItemSpy.count());
|
||||
|
||||
// test setter/getter
|
||||
control->setFocus(false, Qt::MouseFocusReason);
|
||||
QCOMPARE(control->focusReason(), Qt::MouseFocusReason);
|
||||
QCOMPARE(controlSpy.count(), ++controlSpyCount);
|
||||
control->setFocus(true, Qt::TabFocusReason);
|
||||
QCOMPARE(control->focusReason(), Qt::TabFocusReason);
|
||||
QCOMPARE(controlSpy.count(), ++controlSpyCount);
|
||||
control->setFocus(false, Qt::BacktabFocusReason);
|
||||
QCOMPARE(control->focusReason(), Qt::BacktabFocusReason);
|
||||
QCOMPARE(controlSpy.count(), ++controlSpyCount);
|
||||
control->forceActiveFocus(Qt::ShortcutFocusReason);
|
||||
QCOMPARE(control->focusReason(), Qt::ShortcutFocusReason);
|
||||
QCOMPARE(controlSpy.count(), ++controlSpyCount);
|
||||
control->setFocusReason(Qt::PopupFocusReason);
|
||||
QCOMPARE(control->focusReason(), Qt::PopupFocusReason);
|
||||
QCOMPARE(controlSpy.count(), ++controlSpyCount);
|
||||
|
||||
// programmatic focus changes
|
||||
combobox->setFocus(true, Qt::OtherFocusReason);
|
||||
QCOMPARE(control->focusReason(), Qt::OtherFocusReason);
|
||||
QCOMPARE(controlSpy.count(), ++controlSpyCount);
|
||||
|
||||
QVERIFY(combobox->hasFocus());
|
||||
QVERIFY(combobox->hasActiveFocus());
|
||||
|
@ -324,27 +339,35 @@ void tst_focus::reason()
|
|||
QVERIFY(customItem->hasActiveFocus());
|
||||
QCOMPARE(customText->focusReason(), Qt::TabFocusReason);
|
||||
QCOMPARE(customItem->focusReason(), Qt::TabFocusReason);
|
||||
QCOMPARE(customItemSpy.count(),++customItemSpyCount);
|
||||
customItem->setFocusReason(Qt::NoFocusReason);
|
||||
QCOMPARE(customItemSpy.count(),++customItemSpyCount);
|
||||
|
||||
QTest::keyClick(&view, Qt::Key_Tab);
|
||||
QVERIFY(textfield->hasFocus());
|
||||
QVERIFY(textfield->hasActiveFocus());
|
||||
QCOMPARE(qApp->focusObject(), textfield);
|
||||
QCOMPARE(customItem->focusReason(), Qt::TabFocusReason);
|
||||
QCOMPARE(customItemSpy.count(),++customItemSpyCount);
|
||||
QCOMPARE(textfieldSpy.count(), ++textfieldSpyCount);
|
||||
|
||||
QTest::keyClick(&view, Qt::Key_Tab);
|
||||
QVERIFY(control->hasFocus());
|
||||
QVERIFY(control->hasActiveFocus());
|
||||
QCOMPARE(control->focusReason(), Qt::TabFocusReason);
|
||||
QCOMPARE(controlSpy.count(), ++controlSpyCount);
|
||||
|
||||
// backtab -> BacktabFocusReason
|
||||
QTest::keyClick(&view, Qt::Key_Tab, Qt::ShiftModifier);
|
||||
QVERIFY(textfield->hasFocus());
|
||||
QCOMPARE(control->focusReason(), Qt::BacktabFocusReason);
|
||||
QCOMPARE(controlSpy.count(), ++controlSpyCount);
|
||||
QCOMPARE(textfieldSpy.count(), ++textfieldSpyCount);
|
||||
|
||||
QTest::keyClick(&view, Qt::Key_Tab, Qt::ShiftModifier);
|
||||
QVERIFY(customItem->hasFocus());
|
||||
QCOMPARE(customItem->focusReason(), Qt::BacktabFocusReason);
|
||||
QCOMPARE(customItemSpy.count(),++customItemSpyCount);
|
||||
|
||||
QTest::keyClick(&view, Qt::Key_Tab, Qt::ShiftModifier);
|
||||
QVERIFY(customText->hasFocus());
|
||||
|
@ -399,11 +422,15 @@ void tst_focus::reason()
|
|||
QVERIFY(customItem->hasActiveFocus());
|
||||
QCOMPARE(customText->focusReason(), Qt::MouseFocusReason);
|
||||
QCOMPARE(customItem->focusReason(), Qt::MouseFocusReason);
|
||||
QCOMPARE(customItemSpy.count(),++customItemSpyCount);
|
||||
customItem->setFocusReason(Qt::NoFocusReason);
|
||||
QCOMPARE(customItemSpy.count(),++customItemSpyCount);
|
||||
|
||||
QTest::mouseClick(&view, Qt::LeftButton, {}, itemCenter(textfield));
|
||||
QCOMPARE(customItem->focusReason(), Qt::MouseFocusReason);
|
||||
QCOMPARE(customItemSpy.count(),++customItemSpyCount);
|
||||
customItem->setFocusReason(Qt::NoFocusReason);
|
||||
QCOMPARE(customItemSpy.count(),++customItemSpyCount);
|
||||
customText->setFocusReason(Qt::NoFocusReason);
|
||||
|
||||
#if QT_CONFIG(wheelevent)
|
||||
|
@ -414,11 +441,13 @@ void tst_focus::reason()
|
|||
QGuiApplication::sendEvent(customItem, &wheelEvent);
|
||||
QVERIFY(customItem->hasActiveFocus());
|
||||
QCOMPARE(customItem->focusReason(), Qt::MouseFocusReason);
|
||||
QCOMPARE(customItemSpy.count(),++customItemSpyCount);
|
||||
|
||||
// Popup opens -> PopupFocusReason
|
||||
QTest::mouseClick(&view, Qt::RightButton, {}, itemCenter(control));
|
||||
QTRY_VERIFY(!customItem->hasActiveFocus());
|
||||
QCOMPARE(customItem->focusReason(), Qt::PopupFocusReason);
|
||||
QCOMPARE(customItemSpy.count(),++customItemSpyCount);
|
||||
QTest::keyClick(&view, Qt::Key_Escape); // close the popup
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue