QGraphicsProxyWidget: fix handling of proxy focus
If a widget inside a QGPW has a proxy focus, the code would keep sending focus in events to the proxy even if the proxy was already focused. Amend the check in place to prevent this from happening. Change-Id: Id28d3bfe4f396da5c9477df713441ca7d506662f Fixes: QTBUG-51856 Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
parent
382619de65
commit
78edc18057
@ -6309,7 +6309,7 @@ void QWidget::setFocus(Qt::FocusReason reason)
|
||||
previousProxyFocus = topData->proxyWidget->widget()->focusWidget();
|
||||
if (previousProxyFocus && previousProxyFocus->focusProxy())
|
||||
previousProxyFocus = previousProxyFocus->focusProxy();
|
||||
if (previousProxyFocus == this && !topData->proxyWidget->d_func()->proxyIsGivingFocus)
|
||||
if (previousProxyFocus == f && !topData->proxyWidget->d_func()->proxyIsGivingFocus)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +89,7 @@ private slots:
|
||||
void focusNextPrevChild();
|
||||
void focusOutEvent_data();
|
||||
void focusOutEvent();
|
||||
void focusProxy_QTBUG_51856();
|
||||
void hoverEnterLeaveEvent_data();
|
||||
void hoverEnterLeaveEvent();
|
||||
void hoverMoveEvent_data();
|
||||
@ -864,6 +865,75 @@ void tst_QGraphicsProxyWidget::focusOutEvent()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QGraphicsProxyWidget::focusProxy_QTBUG_51856()
|
||||
{
|
||||
// QSpinBox has an internal QLineEdit; this QLineEdit has the spinbox
|
||||
// as its focus proxy.
|
||||
struct FocusedSpinBox : QSpinBox
|
||||
{
|
||||
int focusCount = 0;
|
||||
|
||||
bool event(QEvent *event) override
|
||||
{
|
||||
switch (event->type()) {
|
||||
case QEvent::FocusIn:
|
||||
++focusCount;
|
||||
break;
|
||||
case QEvent::FocusOut:
|
||||
--focusCount;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QSpinBox::event(event);
|
||||
}
|
||||
};
|
||||
|
||||
QGraphicsScene scene;
|
||||
QGraphicsView view(&scene);
|
||||
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
|
||||
scene.addItem(proxy);
|
||||
view.show();
|
||||
view.raise();
|
||||
view.activateWindow();
|
||||
QVERIFY(QTest::qWaitForWindowActive(&view));
|
||||
|
||||
FocusedSpinBox *spinBox = new FocusedSpinBox;
|
||||
|
||||
proxy->setWidget(spinBox);
|
||||
proxy->show();
|
||||
proxy->setFocus();
|
||||
QVERIFY(proxy->hasFocus());
|
||||
QEXPECT_FAIL("", "Widget should have focus but doesn't", Continue);
|
||||
QVERIFY(spinBox->hasFocus());
|
||||
QEXPECT_FAIL("", "Widget should have focus but doesn't", Continue);
|
||||
QCOMPARE(spinBox->focusCount, 1);
|
||||
|
||||
enum { Count = 10 };
|
||||
|
||||
for (int i = 0; i < Count; ++i) {
|
||||
for (int clickCount = 0; clickCount < Count; ++clickCount) {
|
||||
auto proxyCenter = proxy->boundingRect().center();
|
||||
auto proxyCenterInScene = proxy->mapToScene(proxyCenter);
|
||||
auto proxyCenterInView = view.mapFromScene(proxyCenterInScene);
|
||||
|
||||
QTest::mouseClick(view.viewport(), Qt::LeftButton, {}, proxyCenterInView);
|
||||
QTRY_COMPARE(spinBox->focusCount, 1);
|
||||
}
|
||||
|
||||
QLineEdit *edit = new QLineEdit(&view);
|
||||
edit->show();
|
||||
QTRY_VERIFY(edit->isVisible());
|
||||
edit->setFocus();
|
||||
QTRY_VERIFY(edit->hasFocus());
|
||||
QTRY_VERIFY(!proxy->hasFocus());
|
||||
QTRY_COMPARE(proxy->focusOut, i + 1);
|
||||
QTRY_VERIFY(!spinBox->hasFocus());
|
||||
QTRY_COMPARE(spinBox->focusCount, 0);
|
||||
delete edit;
|
||||
}
|
||||
}
|
||||
|
||||
class EventLogger : public QWidget
|
||||
{
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user