QGraphicsProxyWidget: forward Window(De)Activate events
The nested widget might be a QGraphicsView as well (documented to be supported), and QGraphicsScene maintains it's own activation status by counting Window(De)Activate events. We need to make sure that the embedded widget is informed about its activation status so that deeper nested children can receive focus. Forward WindowActivate/Deactivate events to the nested widget, which will pass it on to all its children. Add test case, which without this fix fails when verifying the inner scene's isActive state, or later when testing that focusInEvent is delivered to the embedded widget. Fixes: QTBUG-94091 Pick-to: 5.15 6.1 6.2 Change-Id: I4e0ecef50685ed081d15c7f76b6c1a4a40ed2682 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
parent
d48058f197
commit
01aeb5f7e4
@ -832,6 +832,10 @@ bool QGraphicsProxyWidget::event(QEvent *event)
|
||||
return QGraphicsWidget::event(event);
|
||||
|
||||
switch (event->type()) {
|
||||
case QEvent::WindowActivate:
|
||||
case QEvent::WindowDeactivate:
|
||||
QCoreApplication::sendEvent(d->widget, event);
|
||||
break;
|
||||
case QEvent::StyleChange:
|
||||
// Propagate style changes to the embedded widget.
|
||||
if (!d->styleChangeMode) {
|
||||
|
@ -227,6 +227,7 @@ private slots:
|
||||
void replayMouseMove();
|
||||
void itemsUnderMouse();
|
||||
void embeddedViews();
|
||||
void embeddedViewsWithFocus();
|
||||
void scrollAfterResize_data();
|
||||
void scrollAfterResize();
|
||||
void moveItemWhileScrolling_data();
|
||||
@ -3668,6 +3669,60 @@ void tst_QGraphicsView::embeddedViews()
|
||||
delete v1;
|
||||
}
|
||||
|
||||
/*!
|
||||
Verify that a nested graphics view and embedded widgets receive window
|
||||
activation and focus correctly.
|
||||
|
||||
See QTBUG-94091.
|
||||
*/
|
||||
void tst_QGraphicsView::embeddedViewsWithFocus()
|
||||
{
|
||||
class FocusWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
FocusWidget() { setFocusPolicy(Qt::StrongFocus); }
|
||||
QSize sizeHint() const override { return QSize(100, 100); }
|
||||
|
||||
int focusCount = 0;
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *) override {} // accept event to avoid warning
|
||||
void focusInEvent(QFocusEvent *) override { ++focusCount; }
|
||||
void focusOutEvent(QFocusEvent *) override { --focusCount; }
|
||||
};
|
||||
|
||||
QGraphicsScene *innerScene = new QGraphicsScene;
|
||||
FocusWidget *innerWidget = new FocusWidget;
|
||||
innerScene->addWidget(innerWidget);
|
||||
QGraphicsView *innerView = new QGraphicsView(innerScene);
|
||||
|
||||
QGraphicsScene outerScene;
|
||||
FocusWidget *outerWidget = new FocusWidget;
|
||||
QGraphicsProxyWidget *outerProxy = outerScene.addWidget(outerWidget);
|
||||
QGraphicsProxyWidget *nestedProxy = outerScene.addWidget(innerView);
|
||||
outerProxy->setPos(0, 0);
|
||||
nestedProxy->setPos(0, outerWidget->sizeHint().height());
|
||||
QGraphicsView outerView(&outerScene);
|
||||
outerView.show();
|
||||
outerView.activateWindow();
|
||||
QVERIFY(QTest::qWaitForWindowActive(&outerView));
|
||||
const QPoint outerCenter(QPoint(innerWidget->sizeHint().width() / 2,
|
||||
innerWidget->sizeHint().height() / 2));
|
||||
const QPoint innerCenter(outerCenter + QPoint(0, innerWidget->sizeHint().height()));
|
||||
QCOMPARE(outerView.itemAt(outerCenter), outerProxy);
|
||||
QCOMPARE(outerView.itemAt(innerCenter), nestedProxy);
|
||||
QVERIFY(outerScene.isActive());
|
||||
QVERIFY(innerScene->isActive());
|
||||
|
||||
QCOMPARE(outerWidget->focusCount, 0);
|
||||
QCOMPARE(innerWidget->focusCount, 0);
|
||||
QTest::mouseClick(outerView.viewport(), Qt::LeftButton, {}, outerCenter);
|
||||
QCOMPARE(outerWidget->focusCount, 1);
|
||||
QCOMPARE(innerWidget->focusCount, 0);
|
||||
QTest::mouseClick(outerView.viewport(), Qt::LeftButton, {}, innerCenter);
|
||||
QCOMPARE(outerWidget->focusCount, 0);
|
||||
QCOMPARE(innerWidget->focusCount, 1);
|
||||
}
|
||||
|
||||
void tst_QGraphicsView::scrollAfterResize_data()
|
||||
{
|
||||
QTest::addColumn<bool>("reverse");
|
||||
|
Loading…
Reference in New Issue
Block a user