From e3764dff8581f0d48bb4728144d58c66dbc1657d Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Thu, 5 Dec 2019 13:41:32 +0100 Subject: [PATCH 1/3] Client tests: Fix missing frame event Change-Id: I8bda37560ff8b3c97699831427b0a148f8a5970c Reviewed-by: David Edmundson --- tests/auto/wayland/xdgshell/tst_xdgshell.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/wayland/xdgshell/tst_xdgshell.cpp b/tests/auto/wayland/xdgshell/tst_xdgshell.cpp index ac5c24988f8..d1c2882a0f7 100644 --- a/tests/auto/wayland/xdgshell/tst_xdgshell.cpp +++ b/tests/auto/wayland/xdgshell/tst_xdgshell.cpp @@ -219,8 +219,8 @@ void tst_xdgshell::popup() p->sendFrame(c); uint serial = p->sendButton(client(), BTN_LEFT, Pointer::button_state_pressed); p->sendButton(c, BTN_LEFT, Pointer::button_state_released); - return serial; p->sendFrame(c); + return serial; }); QTRY_VERIFY(window.m_popup); From e86d1995461b79a184783189c2d91ab56f11d878 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Thu, 5 Dec 2019 12:24:07 +0100 Subject: [PATCH 2/3] Client: Always close popups when hiding a window It's not just popups that may have popups open on them. Always close open popups when hiding a window to prevent dangling pointers. [ChangeLog][QPA plugin] Fixed a crash when re-showing a popup after hiding its parent. Fixes: QTBUG-80562 Change-Id: I7cdac5c7a30e0add5ebf00259401e4d74626ce96 Reviewed-by: Paul Olav Tvete Reviewed-by: David Edmundson --- src/plugins/platforms/wayland/qwaylandwindow.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 950486c0cfe..0df99d9fe6c 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -426,8 +426,7 @@ void QWaylandWindow::setVisible(bool visible) // QWaylandShmBackingStore::beginPaint(). } else { sendExposeEvent(QRect()); - if (window()->type() == Qt::Popup) - closePopups(this); + closePopups(this); reset(); } } From d637993c5fcf21f93c531e4e8fdc2e43892514ae Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Thu, 5 Dec 2019 12:51:22 +0100 Subject: [PATCH 3/3] Add client test for hiding the toplevel parent of a popup This used to cause undefined behavior. Task-number: QTBUG-80562 Change-Id: I0397b7b304f316616d2a713063bc5a634dc081bc Reviewed-by: Paul Olav Tvete --- tests/auto/wayland/xdgshell/tst_xdgshell.cpp | 45 ++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tests/auto/wayland/xdgshell/tst_xdgshell.cpp b/tests/auto/wayland/xdgshell/tst_xdgshell.cpp index d1c2882a0f7..2277bbb80ab 100644 --- a/tests/auto/wayland/xdgshell/tst_xdgshell.cpp +++ b/tests/auto/wayland/xdgshell/tst_xdgshell.cpp @@ -46,6 +46,7 @@ private slots: void popup(); void tooltipOnPopup(); void switchPopups(); + void hidePopupParent(); void pongs(); void minMaxSize(); void windowGeometry(); @@ -429,6 +430,50 @@ void tst_xdgshell::switchPopups() QCOMPOSITOR_TRY_VERIFY(xdgPopup()->m_xdgSurface->m_committedConfigureSerial); } +void tst_xdgshell::hidePopupParent() +{ + class Window : public QRasterWindow { + public: + void mousePressEvent(QMouseEvent *event) override + { + QRasterWindow::mousePressEvent(event); + m_popup.reset(new QRasterWindow); + m_popup->setTransientParent(this); + m_popup->setFlags(Qt::Popup); + m_popup->resize(100, 100); + m_popup->show(); + } + QScopedPointer m_popup; + }; + Window window; + window.resize(200, 200); + window.show(); + + QCOMPOSITOR_TRY_VERIFY(xdgToplevel()); + exec([=] { xdgToplevel()->sendCompleteConfigure(); }); + QCOMPOSITOR_TRY_VERIFY(xdgToplevel()->m_xdgSurface->m_committedConfigureSerial); + + 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()); + exec([=] { + xdgPopup()->sendConfigure(QRect(100, 100, 100, 100)); + xdgPopup()->m_xdgSurface->sendConfigure(); + }); + QCOMPOSITOR_TRY_VERIFY(xdgPopup()->m_xdgSurface->m_committedConfigureSerial); + + window.hide(); + QCOMPOSITOR_TRY_VERIFY(!xdgToplevel()); +} + void tst_xdgshell::pongs() { // Create and show a window to trigger shell integration initialzation,