/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <qtest.h>
#include <qtesttouch.h>
#include <QtTest/QSignalSpy>
#include <QtQml/qqmlcomponent.h>
#include <QtQml/qqmlcontext.h>
#include <QtQuick/qquickview.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/private/qquickitem_p.h>
#include "../../shared/util.h"
#include <QtGui/QWindow>
#include <QtGui/QScreen>
#include <QtGui/QImage>
#include <QtCore/QDebug>
#include <QtQml/qqmlengine.h>

#include <QtCore/QLoggingCategory>
#include <QtGui/qstylehints.h>
#include <QtWidgets/QBoxLayout>
#include <QtWidgets/QLabel>

#include <QtQuickWidgets/QQuickWidget>

Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests")

class MouseRecordingQQWidget : public QQuickWidget
{
public:
    explicit MouseRecordingQQWidget(QWidget *parent = nullptr) : QQuickWidget(parent) {
        setAttribute(Qt::WA_AcceptTouchEvents);
    }

protected:
    void mousePressEvent(QMouseEvent *event) override {
        qCDebug(lcTests) << event;
        m_mouseEvents << *event;
        QQuickWidget::mousePressEvent(event);
    }
    void mouseMoveEvent(QMouseEvent *event) override {
        qCDebug(lcTests) << event;
        m_mouseEvents << *event;
        QQuickWidget::mouseMoveEvent(event);
    }
    void mouseReleaseEvent(QMouseEvent *event) override {
        qCDebug(lcTests) << event;
        m_mouseEvents << *event;
        QQuickWidget::mouseReleaseEvent(event);
    }

public:
    QList<QMouseEvent> m_mouseEvents;
};

class MouseRecordingItem : public QQuickItem
{
public:
    MouseRecordingItem(bool acceptTouch, QQuickItem *parent = nullptr)
        : QQuickItem(parent)
        , m_acceptTouch(acceptTouch)
    {
        setSize(QSizeF(300, 300));
        setAcceptedMouseButtons(Qt::LeftButton);
    }

protected:
    void touchEvent(QTouchEvent* event) override {
        event->setAccepted(m_acceptTouch);
        m_touchEvents << *event;
        qCDebug(lcTests) << "accepted?" << event->isAccepted() << event;
    }
    void mousePressEvent(QMouseEvent *event) override {
        qCDebug(lcTests) << event;
        m_mouseEvents << *event;
    }
    void mouseMoveEvent(QMouseEvent *event) override {
        qCDebug(lcTests) << event;
        m_mouseEvents << *event;
    }
    void mouseReleaseEvent(QMouseEvent *event) override {
        qCDebug(lcTests) << event;
        m_mouseEvents << *event;
    }

public:
    QList<QMouseEvent> m_mouseEvents;
    QList<QTouchEvent> m_touchEvents;

private:
    bool m_acceptTouch;
};

class tst_qquickwidget : public QQmlDataTest
{
    Q_OBJECT
public:
    tst_qquickwidget();

private slots:
    void showHide();
    void reparentAfterShow();
    void changeGeometry();
    void resizemodeitem();
    void layoutSizeChange();
    void errors();
    void engine();
    void readback();
    void renderingSignals();
    void grab();
    void grabBeforeShow();
    void reparentToNewWindow();
    void nullEngine();
    void keyEvents();
    void shortcuts();
    void enterLeave();
    void mouseEventWindowPos();
    void synthMouseFromTouch_data();
    void synthMouseFromTouch();
    void tabKey();
    void resizeOverlay();

private:
    QTouchDevice *device = QTest::createTouchDevice();
    const QRect m_availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
};

tst_qquickwidget::tst_qquickwidget()
{
}

void tst_qquickwidget::showHide()
{
    QWidget window;

    QQuickWidget *childView = new QQuickWidget(&window);
    childView->setSource(testFileUrl("rectangle.qml"));

    window.show();
    QVERIFY(QTest::qWaitForWindowExposed(&window));
    QVERIFY(!childView->quickWindow()->isVisible()); // this window is always not visible see QTBUG-65761
    QVERIFY(childView->quickWindow()->visibility() != QWindow::Hidden);

    window.hide();
    QVERIFY(!childView->quickWindow()->isVisible());
    QCOMPARE(childView->quickWindow()->visibility(), QWindow::Hidden);
}

void tst_qquickwidget::reparentAfterShow()
{
    QWidget window;

    QQuickWidget *childView = new QQuickWidget(&window);
    childView->setSource(testFileUrl("rectangle.qml"));
    window.show();
    QVERIFY(QTest::qWaitForWindowExposed(&window));

    QScopedPointer<QQuickWidget> toplevelView(new QQuickWidget);
    toplevelView->setParent(&window);
    toplevelView->setSource(testFileUrl("rectangle.qml"));
    toplevelView->show();
    QVERIFY(QTest::qWaitForWindowExposed(&window));
}

void tst_qquickwidget::changeGeometry()
{
    QWidget window;

    QQuickWidget *childView = new QQuickWidget(&window);
    childView->setSource(testFileUrl("rectangle.qml"));

    window.show();
    QVERIFY(QTest::qWaitForWindowExposed(&window));

    childView->setGeometry(100,100,100,100);
}

void tst_qquickwidget::resizemodeitem()
{
    QWidget window;
    window.setGeometry(m_availableGeometry.left(), m_availableGeometry.top(), 400, 400);

    QScopedPointer<QQuickWidget> view(new QQuickWidget);
    view->setParent(&window);
    view->setResizeMode(QQuickWidget::SizeRootObjectToView);
    QCOMPARE(QSize(0,0), view->initialSize());
    view->setSource(testFileUrl("resizemodeitem.qml"));
    QQuickItem* item = qobject_cast<QQuickItem*>(view->rootObject());
    QVERIFY(item);
    window.show();

    view->showNormal();
    // initial size from root object
    QCOMPARE(item->width(), 200.0);
    QCOMPARE(item->height(), 200.0);
    QCOMPARE(view->size(), QSize(200, 200));
    QCOMPARE(view->size(), view->sizeHint());
    QCOMPARE(view->size(), view->initialSize());

    // size update from view
    view->resize(QSize(80,100));

    QTRY_COMPARE(item->width(), 80.0);
    QCOMPARE(item->height(), 100.0);
    QCOMPARE(view->size(), QSize(80, 100));
    QCOMPARE(view->size(), view->sizeHint());

    view->setResizeMode(QQuickWidget::SizeViewToRootObject);

    // size update from view disabled
    view->resize(QSize(60,80));
    QCOMPARE(item->width(), 80.0);
    QCOMPARE(item->height(), 100.0);
    QTRY_COMPARE(view->size(), QSize(60, 80));

    // size update from root object
    item->setWidth(250);
    item->setHeight(350);
    QCOMPARE(item->width(), 250.0);
    QCOMPARE(item->height(), 350.0);
    QTRY_COMPARE(view->size(), QSize(250, 350));
    QCOMPARE(view->size(), QSize(250, 350));
    QCOMPARE(view->size(), view->sizeHint());

    // reset window
    window.hide();
    view.reset(new QQuickWidget(&window));
    view->setResizeMode(QQuickWidget::SizeViewToRootObject);
    view->setSource(testFileUrl("resizemodeitem.qml"));
    item = qobject_cast<QQuickItem*>(view->rootObject());
    QVERIFY(item);
    window.show();

    view->showNormal();

    // initial size for root object
    QCOMPARE(item->width(), 200.0);
    QCOMPARE(item->height(), 200.0);
    QCOMPARE(view->size(), view->sizeHint());
    QCOMPARE(view->size(), view->initialSize());

    // size update from root object
    item->setWidth(80);
    item->setHeight(100);
    QCOMPARE(item->width(), 80.0);
    QCOMPARE(item->height(), 100.0);
    QTRY_COMPARE(view->size(), QSize(80, 100));
    QCOMPARE(view->size(), view->sizeHint());

    // size update from root object disabled
    view->setResizeMode(QQuickWidget::SizeRootObjectToView);
    item->setWidth(60);
    item->setHeight(80);
    QCOMPARE(view->width(), 80);
    QCOMPARE(view->height(), 100);
    QCOMPARE(QSize(item->width(), item->height()), view->sizeHint());

    // size update from view
    view->resize(QSize(200,300));
    QTRY_COMPARE(item->width(), 200.0);
    QCOMPARE(item->height(), 300.0);
    QCOMPARE(view->size(), QSize(200, 300));
    QCOMPARE(view->size(), view->sizeHint());

    window.hide();

    // if we set a specific size for the view then it should keep that size
    // for SizeRootObjectToView mode.
    view.reset(new QQuickWidget(&window));
    view->resize(300, 300);
    view->setResizeMode(QQuickWidget::SizeRootObjectToView);
    QCOMPARE(QSize(0,0), view->initialSize());
    view->setSource(testFileUrl("resizemodeitem.qml"));
    view->resize(300, 300);
    item = qobject_cast<QQuickItem*>(view->rootObject());
    QVERIFY(item);
    window.show();

    view->showNormal();

    // initial size from root object
    QCOMPARE(item->width(), 300.0);
    QCOMPARE(item->height(), 300.0);
    QTRY_COMPARE(view->size(), QSize(300, 300));
    QCOMPARE(view->size(), view->sizeHint());
    QCOMPARE(view->initialSize(), QSize(200, 200)); // initial object size
}

void tst_qquickwidget::layoutSizeChange()
{
    QWidget window;
    window.resize(400, 400);

    QVBoxLayout *layout = new QVBoxLayout(&window);
    layout->setContentsMargins(0,0,0,0);
    layout->setSpacing(0);
    QScopedPointer<QQuickWidget> view(new QQuickWidget);
    layout->addWidget(view.data());
    QLabel *label = new QLabel("Label");
    layout->addWidget(label);
    layout->addStretch(1);


    view->resize(300,300);
    view->setResizeMode(QQuickWidget::SizeViewToRootObject);
    QCOMPARE(QSize(0,0), view->initialSize());
    view->setSource(testFileUrl("rectangle.qml"));
    QQuickItem* item = qobject_cast<QQuickItem*>(view->rootObject());
    QVERIFY(item);
    QCOMPARE(item->height(), 200.0);
    window.show();
    QVERIFY(QTest::qWaitForWindowExposed(&window, 5000));
    QTRY_COMPARE(view->height(), 200);
    QTRY_COMPARE(label->y(), 200);

    item->setSize(QSizeF(100,100));
    QCOMPARE(item->height(), 100.0);
    QTRY_COMPARE(view->height(), 100);
    QTRY_COMPARE(label->y(), 100);
}

void tst_qquickwidget::errors()
{
    QQuickWidget *view = new QQuickWidget;
    QScopedPointer<QQuickWidget> cleanupView(view);
    QVERIFY(view->errors().isEmpty()); // don't crash

    QQmlTestMessageHandler messageHandler;
    view->setSource(testFileUrl("error1.qml"));
    QCOMPARE(view->status(), QQuickWidget::Error);
    QCOMPARE(view->errors().count(), 1);
}

void tst_qquickwidget::engine()
{
    QScopedPointer<QQmlEngine> engine(new QQmlEngine);
    QScopedPointer<QQuickWidget> view(new QQuickWidget(engine.data(), nullptr));
    QScopedPointer<QQuickWidget> view2(new QQuickWidget(view->engine(), nullptr));

    QVERIFY(view->engine());
    QVERIFY(view2->engine());
    QCOMPARE(view->engine(), view2->engine());
}

void tst_qquickwidget::readback()
{
    QWidget window;

    QScopedPointer<QQuickWidget> view(new QQuickWidget);
    view->setSource(testFileUrl("rectangle.qml"));

    view->show();
    QVERIFY(QTest::qWaitForWindowExposed(view.data()));

    QImage img = view->grabFramebuffer();
    QVERIFY(!img.isNull());
    QCOMPARE(img.width(), view->width());
    QCOMPARE(img.height(), view->height());

    QRgb pix = img.pixel(5, 5);
    QCOMPARE(pix, qRgb(255, 0, 0));
}

void tst_qquickwidget::renderingSignals()
{
    QQuickWidget widget;
    QQuickWindow *window = widget.quickWindow();
    QVERIFY(window);

    QSignalSpy beforeRenderingSpy(window, &QQuickWindow::beforeRendering);
    QSignalSpy beforeSyncSpy(window, &QQuickWindow::beforeSynchronizing);
    QSignalSpy afterRenderingSpy(window, &QQuickWindow::afterRendering);

    QVERIFY(beforeRenderingSpy.isValid());
    QVERIFY(beforeSyncSpy.isValid());
    QVERIFY(afterRenderingSpy.isValid());

    QCOMPARE(beforeRenderingSpy.size(), 0);
    QCOMPARE(beforeSyncSpy.size(), 0);
    QCOMPARE(afterRenderingSpy.size(), 0);

    widget.setSource(testFileUrl("rectangle.qml"));

    QCOMPARE(beforeRenderingSpy.size(), 0);
    QCOMPARE(beforeSyncSpy.size(), 0);
    QCOMPARE(afterRenderingSpy.size(), 0);

    widget.show();
    QVERIFY(QTest::qWaitForWindowExposed(&widget));

    QTRY_VERIFY(beforeRenderingSpy.size() > 0);
    QTRY_VERIFY(beforeSyncSpy.size() > 0);
    QTRY_VERIFY(afterRenderingSpy.size() > 0);
}

void tst_qquickwidget::grab()
{
    QQuickWidget view;
    view.setSource(testFileUrl("rectangle.qml"));
    QPixmap pixmap = view.grab();
    QRgb pixel = pixmap.toImage().pixel(5, 5);
    QCOMPARE(pixel, qRgb(255, 0, 0));
}

// QTBUG-49929, verify that Qt Designer grabbing the contents before drag
// does not crash due to missing GL contexts or similar.
void tst_qquickwidget::grabBeforeShow()
{
    QQuickWidget widget;
    QVERIFY(!widget.grab().isNull());
}

void tst_qquickwidget::reparentToNewWindow()
{
    QWidget window1;
    QWidget window2;

    QQuickWidget *qqw = new QQuickWidget(&window1);
    qqw->setSource(testFileUrl("rectangle.qml"));
    window1.show();
    QVERIFY(QTest::qWaitForWindowExposed(&window1));
    window2.show();
    QVERIFY(QTest::qWaitForWindowExposed(&window2));

    QSignalSpy afterRenderingSpy(qqw->quickWindow(), &QQuickWindow::afterRendering);
    qqw->setParent(&window2);
    qqw->show();

    QTRY_VERIFY(afterRenderingSpy.size() > 0);

    QImage img = qqw->grabFramebuffer();
    QCOMPARE(img.pixel(5, 5), qRgb(255, 0, 0));
}

void tst_qquickwidget::nullEngine()
{
    QQuickWidget widget;
    // Default should have no errors, even with a null qml engine
    QVERIFY(widget.errors().isEmpty());
    QCOMPARE(widget.status(), QQuickWidget::Null);

    // A QML engine should be created lazily.
    QVERIFY(widget.rootContext());
    QVERIFY(widget.engine());
}

class KeyHandlingWidget : public QQuickWidget
{
public:
    void keyPressEvent(QKeyEvent *e) override {
        if (e->key() == Qt::Key_A)
            ok = true;
    }

    bool ok = false;
};

void tst_qquickwidget::keyEvents()
{
    // A QQuickWidget should behave like a normal widget when it comes to event handling.
    // Verify that key events actually reach the widget. (QTBUG-45757)
    KeyHandlingWidget widget;
    widget.setSource(testFileUrl("rectangle.qml"));
    widget.show();
    QVERIFY(QTest::qWaitForWindowExposed(widget.window()));

    // Note: send the event to the QWindow, not the QWidget, in order
    // to simulate the full event processing chain.
    QTest::keyClick(widget.window()->windowHandle(), Qt::Key_A);

    QTRY_VERIFY(widget.ok);
}

class ShortcutEventFilter : public QObject
{
public:
    bool eventFilter(QObject *obj, QEvent *e) override {
        if (e->type() == QEvent::ShortcutOverride)
            shortcutOk = true;

        return QObject::eventFilter(obj, e);
    }

    bool shortcutOk = false;
};

void tst_qquickwidget::shortcuts()
{
    // Verify that ShortcutOverride events do not get lost. (QTBUG-60988)
    KeyHandlingWidget widget;
    widget.setSource(testFileUrl("rectangle.qml"));
    widget.show();
    QVERIFY(QTest::qWaitForWindowExposed(widget.window()));

    // Send to the widget, verify that the QQuickWindow sees it.

    ShortcutEventFilter filter;
    widget.quickWindow()->installEventFilter(&filter);

    QKeyEvent e(QEvent::ShortcutOverride, Qt::Key_A, Qt::ControlModifier);
    QCoreApplication::sendEvent(&widget, &e);

    QTRY_VERIFY(filter.shortcutOk);
}

void tst_qquickwidget::enterLeave()
{
    QQuickWidget view;
    view.setSource(testFileUrl("enterleave.qml"));

    // Ensure the cursor is away from the window first
    const auto outside = m_availableGeometry.topLeft() + QPoint(50, 50);
    QCursor::setPos(outside);
    QTRY_VERIFY(QCursor::pos() == outside);

    view.move(m_availableGeometry.topLeft() + QPoint(100, 100));
    view.show();
    QVERIFY(QTest::qWaitForWindowExposed(&view));
    QQuickItem *rootItem = view.rootObject();
    QVERIFY(rootItem);
    const QPoint frameOffset = view.geometry().topLeft() - view.frameGeometry().topLeft();

    QTRY_VERIFY(!rootItem->property("hasMouse").toBool());
    // Check the enter
    QCursor::setPos(view.pos() + QPoint(50, 50) + frameOffset);
    QTRY_VERIFY(rootItem->property("hasMouse").toBool());
    // Now check the leave
    QCursor::setPos(outside);
    QTRY_VERIFY(!rootItem->property("hasMouse").toBool());
}

void tst_qquickwidget::mouseEventWindowPos()
{
    QWidget widget;
    widget.resize(100, 100);
    QQuickWidget *quick = new QQuickWidget(&widget);
    quick->setSource(testFileUrl("mouse.qml"));
    quick->move(50, 50);
    widget.show();
    QVERIFY(QTest::qWaitForWindowExposed(&widget));
    QQuickItem *rootItem = quick->rootObject();
    QVERIFY(rootItem);

    QVERIFY(!rootItem->property("wasClicked").toBool());
    QVERIFY(!rootItem->property("wasDoubleClicked").toBool());
    // Moving an item under the mouse cursor will trigger a mouse move event.
    // The above quick->move() will trigger a mouse move event on macOS.
    // Discard that in order to get a clean slate for the actual tests.
    rootItem->setProperty("wasMoved", QVariant(false));

    QWindow *window = widget.windowHandle();
    QVERIFY(window);

    QTest::mouseMove(window, QPoint(60, 60));
    QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(60, 60));
    QTRY_VERIFY(rootItem->property("wasClicked").toBool());
    QTest::mouseDClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(60, 60));
    QTRY_VERIFY(rootItem->property("wasDoubleClicked").toBool());
    QTest::mouseMove(window, QPoint(70, 70));
    QTRY_VERIFY(rootItem->property("wasMoved").toBool());
}

void tst_qquickwidget::synthMouseFromTouch_data()
{
    QTest::addColumn<bool>("synthMouse"); // AA_SynthesizeMouseForUnhandledTouchEvents
    QTest::addColumn<bool>("acceptTouch"); // QQuickItem::touchEvent: setAccepted()

    QTest::newRow("no synth, accept") << false << true; // suitable for touch-capable UIs
    QTest::newRow("no synth, don't accept") << false << false;
    QTest::newRow("synth and accept") << true << true;
    QTest::newRow("synth, don't accept") << true << false; // the default
}

void tst_qquickwidget::synthMouseFromTouch()
{
    QFETCH(bool, synthMouse);
    QFETCH(bool, acceptTouch);

    QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, synthMouse);
    QWidget window;
    window.setAttribute(Qt::WA_AcceptTouchEvents);
    QScopedPointer<MouseRecordingQQWidget> childView(new MouseRecordingQQWidget(&window));
    MouseRecordingItem *item = new MouseRecordingItem(acceptTouch, nullptr);
    childView->setContent(QUrl(), nullptr, item);
    window.resize(300, 300);
    childView->resize(300, 300);
    window.show();
    QVERIFY(QTest::qWaitForWindowActive(&window));
    QVERIFY(!childView->quickWindow()->isVisible()); // this window is always not visible see QTBUG-65761
    QVERIFY(item->isVisible());

    QPoint p1 = QPoint(20, 20);
    QPoint p2 = QPoint(30, 30);
    QTest::touchEvent(&window, device).press(0, p1, &window);
    QTest::touchEvent(&window, device).move(0, p2, &window);
    QTest::touchEvent(&window, device).release(0, p2, &window);

    QCOMPARE(item->m_touchEvents.count(), !synthMouse && !acceptTouch ? 1 : 3);
    QCOMPARE(item->m_mouseEvents.count(), (acceptTouch || !synthMouse) ? 0 : 3);
    QCOMPARE(childView->m_mouseEvents.count(), 0);
    for (const QMouseEvent &ev : item->m_mouseEvents)
        QCOMPARE(ev.source(), Qt::MouseEventSynthesizedByQt);
}

void tst_qquickwidget::tabKey()
{
    if (QGuiApplication::styleHints()->tabFocusBehavior() != Qt::TabFocusAllControls)
        QSKIP("This function doesn't support NOT iterating all.");
    QWidget window1;
    QQuickWidget *qqw = new QQuickWidget(&window1);
    qqw->setSource(testFileUrl("activeFocusOnTab.qml"));
    QQuickWidget *qqw2 = new QQuickWidget(&window1);
    qqw2->setSource(testFileUrl("noActiveFocusOnTab.qml"));
    qqw2->move(100, 0);
    window1.show();
    qqw->setFocus();
    QVERIFY(QTest::qWaitForWindowExposed(&window1, 5000));
    QVERIFY(qqw->hasFocus());
    QQuickItem *item = qobject_cast<QQuickItem *>(qqw->rootObject());
    QQuickItem *topItem = item->findChild<QQuickItem *>("topRect");
    QQuickItem *middleItem = item->findChild<QQuickItem *>("middleRect");
    QQuickItem *bottomItem = item->findChild<QQuickItem *>("bottomRect");
    topItem->forceActiveFocus();
    QVERIFY(topItem->property("activeFocus").toBool());
    QTest::keyClick(qqw, Qt::Key_Tab);
    QTRY_VERIFY(middleItem->property("activeFocus").toBool());
    QTest::keyClick(qqw, Qt::Key_Tab);
    QTRY_VERIFY(bottomItem->property("activeFocus").toBool());
    QTest::keyClick(qqw, Qt::Key_Backtab);
    QTRY_VERIFY(middleItem->property("activeFocus").toBool());

    qqw2->setFocus();
    QQuickItem *item2 = qobject_cast<QQuickItem *>(qqw2->rootObject());
    QQuickItem *topItem2 = item2->findChild<QQuickItem *>("topRect2");
    QTRY_VERIFY(qqw2->hasFocus());
    QVERIFY(topItem2->property("activeFocus").toBool());
    QTest::keyClick(qqw2, Qt::Key_Tab);
    QTRY_VERIFY(qqw->hasFocus());
    QVERIFY(middleItem->property("activeFocus").toBool());
}

class Overlay : public QQuickItem, public QQuickItemChangeListener
{
    Q_OBJECT

public:
    Overlay() = default;

    ~Overlay()
    {
        QQuickItemPrivate::get(parentItem())->removeItemChangeListener(this, QQuickItemPrivate::Geometry);
    }

    // componentCompleted() is too early to add the listener, as parentItem()
    // is still null by that stage, so we use this function instead.
    void startListening()
    {
        QQuickItemPrivate::get(parentItem())->addItemChangeListener(this, QQuickItemPrivate::Geometry);
    }

private:
    virtual void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &/*oldGeometry*/) override
    {
        auto window = QQuickItemPrivate::get(this)->window;
        if (!window)
            return;

        setSize(window->size());
    }
};

// Test that an item that resizes itself based on the window size can use a
// Geometry item change listener to respond to changes in size. This is a
// simplified test to mimic a use case involving Overlay from Qt Quick Controls 2.
void tst_qquickwidget::resizeOverlay()
{
    QWidget widget;
    auto contentVerticalLayout = new QVBoxLayout(&widget);
    contentVerticalLayout->setMargin(0);

    qmlRegisterType<Overlay>("Test", 1, 0, "Overlay");

    auto quickWidget = new QQuickWidget(testFileUrl("resizeOverlay.qml"), &widget);
    QCOMPARE(quickWidget->status(), QQuickWidget::Ready);
    quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
    contentVerticalLayout->addWidget(quickWidget);

    auto rootItem = qobject_cast<QQuickItem*>(quickWidget->rootObject());
    QVERIFY(rootItem);

    auto overlay = rootItem->property("overlay").value<Overlay*>();
    QVERIFY(overlay);
    QVERIFY(overlay->parentItem());
    overlay->startListening();

    widget.resize(200, 200);
    widget.show();
    QCOMPARE(rootItem->width(), 200);
    QCOMPARE(rootItem->height(), 200);
    QCOMPARE(overlay->width(), rootItem->width());
    QCOMPARE(overlay->height(), rootItem->height());

    widget.resize(300, 300);
    QCOMPARE(rootItem->width(), 300);
    QCOMPARE(rootItem->height(), 300);
    QCOMPARE(overlay->width(), rootItem->width());
    QCOMPARE(overlay->height(), rootItem->height());
}

QTEST_MAIN(tst_qquickwidget)

#include "tst_qquickwidget.moc"
