summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Edmundson <[email protected]>2025-06-03 08:21:30 +0300
committerDavid Edmundson <[email protected]>2025-06-06 15:13:15 +0300
commit1ede87a73590d737a31d265ee42a2f3135b0fd86 (patch)
tree20b9388f309c9a1431c24dc4f1619fe91fce7571
parent25fdc044f58d426c3056409e2883becdc3cf0bd1 (diff)
wayland: Add unit test for sibling client grabbing popups being createdHEADdev
Task-number: QTBUG-119110 Change-Id: Ie31da8073d0107f6515ce2e0152cb2bbc97c8582 Reviewed-by: David Redondo <[email protected]>
-rw-r--r--tests/auto/wayland/xdgshell/tst_xdgshell.cpp63
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"