diff options
author | David Edmundson <[email protected]> | 2025-06-03 08:21:30 +0300 |
---|---|---|
committer | David Edmundson <[email protected]> | 2025-06-06 15:13:15 +0300 |
commit | 1ede87a73590d737a31d265ee42a2f3135b0fd86 (patch) | |
tree | 20b9388f309c9a1431c24dc4f1619fe91fce7571 | |
parent | 25fdc044f58d426c3056409e2883becdc3cf0bd1 (diff) |
Task-number: QTBUG-119110
Change-Id: Ie31da8073d0107f6515ce2e0152cb2bbc97c8582
Reviewed-by: David Redondo <[email protected]>
-rw-r--r-- | tests/auto/wayland/xdgshell/tst_xdgshell.cpp | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/tests/auto/wayland/xdgshell/tst_xdgshell.cpp b/tests/auto/wayland/xdgshell/tst_xdgshell.cpp index b144625a3a3..51f0a6dea9b 100644 --- a/tests/auto/wayland/xdgshell/tst_xdgshell.cpp +++ b/tests/auto/wayland/xdgshell/tst_xdgshell.cpp @@ -38,6 +38,7 @@ private slots: void initiallySuspended(); void modality(); void modalityWithoutTransientParent(); + void grabbingSiblingPopups(); }; void tst_xdgshell::initTestCase() @@ -935,5 +936,67 @@ void tst_xdgshell::modalityWithoutTransientParent() QCOMPOSITOR_TRY_VERIFY(!xdgDialog()); } +void tst_xdgshell::grabbingSiblingPopups() +{ + class Window : public QRasterWindow { + public: + void mousePressEvent(QMouseEvent *event) override + { + QRasterWindow::mousePressEvent(event); + auto popup = new QRasterWindow; + popup->setTransientParent(this); + popup->setFlags(Qt::Popup); + popup->resize(100, 100); + popup->show(); + m_popups << popup; + } + QList<QRasterWindow*> m_popups; + }; + + Window window; + window.resize(200, 200); + window.show(); + + QCOMPOSITOR_TRY_VERIFY(xdgToplevel()); + exec([&] { xdgToplevel()->sendCompleteConfigure(); }); + + auto triggerPopup = [&](int popupIndex) { + // we need a click to be able to create a grabbing popup + exec([&] { + auto *surface = xdgToplevel()->surface(); + auto *p = pointer(); + auto *c = client(); + p->sendEnter(surface, {100, 100}); + p->sendFrame(c); + p->sendButton(c, BTN_LEFT, Pointer::button_state_pressed); + p->sendButton(c, BTN_LEFT, Pointer::button_state_released); + p->sendFrame(c); + }); + + QCOMPOSITOR_TRY_VERIFY(xdgPopup(popupIndex)); + exec([&] { + xdgPopup(popupIndex)->sendConfigure(QRect(100, 100, 100, 100)); + xdgPopup(popupIndex)->m_xdgSurface->sendConfigure(); + }); + }; + + triggerPopup(0); + // QtWayland will make popup1 a child of popup0, despite them being siblings at a Qt level + triggerPopup(1); + + // This is illegal from a wayland POV as popup2 is the latest grabbing popup + // popup2 must be closed first but we should handle it gracefully + // and not trigger an error in the compositor + delete window.m_popups.takeFirst(); + + // check the compositor does not throw an error when the popup is closed + auto native = qGuiApp->platformNativeInterface(); + auto display = static_cast<struct ::wl_display *>(native->nativeResourceForIntegration("wl_display")); + wl_display_roundtrip(display); + + // cleanup + delete window.m_popups.takeFirst(); +} + QCOMPOSITOR_TEST_MAIN(tst_xdgshell) #include "tst_xdgshell.moc" |