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>
This commit is contained in:
parent
b3621cfe7c
commit
6cf44bf690
@ -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();
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user