summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Klokkhammer Helsing <johan.helsing@qt.io>2017-10-18 11:05:48 +0200
committerJohan Helsing <johan.helsing@qt.io>2017-10-20 10:02:03 +0000
commitefac7d4b2944a2caae935ef489f1753ec8444d77 (patch)
tree7bc8143e507f4e41bd8287215ebbe477ec52590c
parent266fa60fb83efcb38211377d22766c45dae52722 (diff)
Fix crash when wl-shell setType is called with a hidden parent
Fall back to creating a toplevel instead Change-Id: If7db27d08b79e4f9f8c82fa8f9bf73abdb2585d9 Reviewed-by: David Edmundson <davidedmundson@kde.org> Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
-rw-r--r--src/client/qwaylandwlshellsurface.cpp6
-rw-r--r--tests/auto/client/client/tst_client.cpp44
2 files changed, 48 insertions, 2 deletions
diff --git a/src/client/qwaylandwlshellsurface.cpp b/src/client/qwaylandwlshellsurface.cpp
index 77434e98b..92223f45e 100644
--- a/src/client/qwaylandwlshellsurface.cpp
+++ b/src/client/qwaylandwlshellsurface.cpp
@@ -185,6 +185,7 @@ void QWaylandWlShellSurface::updateTransientParent(QWindow *parent)
|| testShowWithoutActivating(m_window->window()))
flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE;
+ Q_ASSERT(parent_wayland_window->object());
set_transient(parent_wayland_window->object(),
transientPos.x(),
transientPos.y(),
@@ -211,15 +212,16 @@ void QWaylandWlShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevic
transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top());
}
+ Q_ASSERT(parent_wayland_window->object());
set_popup(device->wl_seat(), serial, parent_wayland_window->object(),
transientPos.x(), transientPos.y(), 0);
}
void QWaylandWlShellSurface::setType(Qt::WindowType type, QWaylandWindow *transientParent)
{
- if (type == Qt::Popup && transientParent)
+ if (type == Qt::Popup && transientParent && transientParent->object())
setPopup(transientParent, m_window->display()->lastInputDevice(), m_window->display()->lastInputSerial());
- else if (transientParent)
+ else if (transientParent && transientParent->object())
updateTransientParent(transientParent->window());
else
setTopLevel();
diff --git a/tests/auto/client/client/tst_client.cpp b/tests/auto/client/client/tst_client.cpp
index 8acddfbe7..1eee90f49 100644
--- a/tests/auto/client/client/tst_client.cpp
+++ b/tests/auto/client/client/tst_client.cpp
@@ -143,6 +143,8 @@ private slots:
void touchDrag();
void mouseDrag();
void dontCrashOnMultipleCommits();
+ void hiddenTransientParent();
+ void hiddenPopupParent();
private:
MockCompositor *compositor;
@@ -360,6 +362,48 @@ void tst_WaylandClient::dontCrashOnMultipleCommits()
QTRY_VERIFY(!compositor->surface());
}
+void tst_WaylandClient::hiddenTransientParent()
+{
+ QWindow parent;
+ QWindow transient;
+
+ transient.setTransientParent(&parent);
+
+ parent.show();
+ QTRY_VERIFY(compositor->surface());
+
+ parent.hide();
+ QTRY_VERIFY(!compositor->surface());
+
+ transient.show();
+ QTRY_VERIFY(compositor->surface());
+}
+
+void tst_WaylandClient::hiddenPopupParent()
+{
+ TestWindow toplevel;
+ toplevel.show();
+
+ // wl_shell relies on a mouse event in order to send a serial and seat
+ // with the set_popup request.
+ QSharedPointer<MockSurface> surface;
+ QTRY_VERIFY(surface = compositor->surface());
+ QPoint mousePressPos(16, 16);
+ QCOMPARE(toplevel.mousePressEventCount, 0);
+ compositor->sendMousePress(surface, mousePressPos);
+ QTRY_COMPARE(toplevel.mousePressEventCount, 1);
+
+ QWindow popup;
+ popup.setTransientParent(&toplevel);
+ popup.setFlag(Qt::Popup, true);
+
+ toplevel.hide();
+ QTRY_VERIFY(!compositor->surface());
+
+ popup.show();
+ QTRY_VERIFY(compositor->surface());
+}
+
int main(int argc, char **argv)
{
setenv("XDG_RUNTIME_DIR", ".", 1);