QWidget: React to platform surface being created or destroyed
The platform window may create or destroy its surface from other entry points than the QWidget API, in which case QWidget needs to sync up its own state to match. In particular WA_WState_Created and the winId needs to be recomputed. Fixes: QTBUG-69289 Fixes: QTBUG-77350 Fixes: QTBUG-80859 Change-Id: I769e58ead3c2efcf8c451c363108848feade9388 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io> (cherry picked from commit 009abcd7b66738bece6cf354776dfb2ef401636b) Reviewed-by: Liang Qi <liang.qi@qt.io>
This commit is contained in:
parent
9d43d55b21
commit
e2f35fa684
@ -8934,6 +8934,23 @@ bool QWidget::event(QEvent *event)
|
||||
}
|
||||
}
|
||||
switch (event->type()) {
|
||||
case QEvent::PlatformSurface: {
|
||||
// Sync up QWidget's view of whether or not the widget has been created
|
||||
switch (static_cast<QPlatformSurfaceEvent*>(event)->surfaceEventType()) {
|
||||
case QPlatformSurfaceEvent::SurfaceCreated:
|
||||
if (!testAttribute(Qt::WA_WState_Created))
|
||||
create();
|
||||
break;
|
||||
case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed:
|
||||
if (testAttribute(Qt::WA_WState_Created)) {
|
||||
// Child windows have already been destroyed by QWindow,
|
||||
// so we skip them here.
|
||||
destroy(false, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QEvent::MouseMove:
|
||||
mouseMoveEvent((QMouseEvent*)event);
|
||||
break;
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include <QtGui/qpaintengine.h>
|
||||
#include <QtGui/qbackingstore.h>
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <QtGui/qpa/qplatformwindow.h>
|
||||
#include <QtGui/qscreen.h>
|
||||
#include <qmenubar.h>
|
||||
#include <qcompleter.h>
|
||||
@ -221,6 +222,7 @@ private slots:
|
||||
void setFixedSize();
|
||||
|
||||
void ensureCreated();
|
||||
void createAndDestroy();
|
||||
void winIdChangeEvent();
|
||||
void persistentWinId();
|
||||
void showNativeChild();
|
||||
@ -4134,6 +4136,58 @@ public:
|
||||
int winIdChangeEventCount() const { return m_winIdList.count(); }
|
||||
};
|
||||
|
||||
class CreateDestroyWidget : public WinIdChangeWidget
|
||||
{
|
||||
public:
|
||||
void create() { QWidget::create(); }
|
||||
void destroy() { QWidget::destroy(); }
|
||||
};
|
||||
|
||||
void tst_QWidget::createAndDestroy()
|
||||
{
|
||||
CreateDestroyWidget widget;
|
||||
|
||||
// Create and destroy via QWidget
|
||||
widget.create();
|
||||
QVERIFY(widget.testAttribute(Qt::WA_WState_Created));
|
||||
QCOMPARE(widget.winIdChangeEventCount(), 1);
|
||||
QVERIFY(widget.internalWinId());
|
||||
|
||||
widget.destroy();
|
||||
QVERIFY(!widget.testAttribute(Qt::WA_WState_Created));
|
||||
QCOMPARE(widget.winIdChangeEventCount(), 2);
|
||||
QVERIFY(!widget.internalWinId());
|
||||
|
||||
// Create via QWidget, destroy via QWindow
|
||||
widget.create();
|
||||
QVERIFY(widget.testAttribute(Qt::WA_WState_Created));
|
||||
QCOMPARE(widget.winIdChangeEventCount(), 3);
|
||||
QVERIFY(widget.internalWinId());
|
||||
|
||||
widget.windowHandle()->destroy();
|
||||
QVERIFY(!widget.testAttribute(Qt::WA_WState_Created));
|
||||
QCOMPARE(widget.winIdChangeEventCount(), 4);
|
||||
QVERIFY(!widget.internalWinId());
|
||||
|
||||
// Create via QWidget again
|
||||
widget.create();
|
||||
QVERIFY(widget.testAttribute(Qt::WA_WState_Created));
|
||||
QCOMPARE(widget.winIdChangeEventCount(), 5);
|
||||
QVERIFY(widget.internalWinId());
|
||||
|
||||
// Destroy via QWindow, create via QWindow
|
||||
widget.windowHandle()->destroy();
|
||||
QVERIFY(widget.windowHandle());
|
||||
QVERIFY(!widget.testAttribute(Qt::WA_WState_Created));
|
||||
QCOMPARE(widget.winIdChangeEventCount(), 6);
|
||||
QVERIFY(!widget.internalWinId());
|
||||
|
||||
widget.windowHandle()->create();
|
||||
QVERIFY(widget.testAttribute(Qt::WA_WState_Created));
|
||||
QCOMPARE(widget.winIdChangeEventCount(), 7);
|
||||
QVERIFY(widget.internalWinId());
|
||||
}
|
||||
|
||||
void tst_QWidget::winIdChangeEvent()
|
||||
{
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user