Validate surface is valid when sending TextInput leave event

Summary:
It's possible for the surface to be unbound when we send the leave
event; we've called Resource::unbind() of Surface, so the Surface has,
deleteLater called, but it's still a valid object, and the first check
passes.

We get in this situation because when a surface is destroyed, we're
handling text input from the same source event.

Sending a nullpointer is a protocol error, and wayland kindly closes the
connection.

This fixes my constant:
"Did the Wayland server die" error messages when running clients.

Test Plan:
Got errors after setting up qt virtual keyboard.
Had reproducible case.
Restarted kwin after this patch, now doesn't crash.

Reviewers: #plasma, graesslin

Subscribers: apol, graesslin, plasma-devel, #frameworks

Tags: #plasma_on_wayland, #frameworks

Differential Revision: https://phabricator.kde.org/D5712
This commit is contained in:
David Edmundson 2017-05-05 16:43:35 +02:00
parent 6df5c8733e
commit 67521b975b
2 changed files with 17 additions and 2 deletions

View file

@ -306,6 +306,21 @@ void TextInputTest::testEnterLeave()
QCOMPARE(textInputChangedSpy.count(), 3); QCOMPARE(textInputChangedSpy.count(), 3);
// should still be the same text input // should still be the same text input
QCOMPARE(m_seatInterface->focusedTextInput(), serverTextInput); QCOMPARE(m_seatInterface->focusedTextInput(), serverTextInput);
//reset
textInput->enable(surface.data());
QVERIFY(enabledChangedSpy.wait());
//trigger an enter again and leave, but this
//time we try sending an event after the surface is unbound
//but not yet destroyed. It should work without errors
QCOMPARE(textInput->enteredSurface(), surface.data());
connect(serverSurface, &Resource::unbound, [=]() {
m_seatInterface->setFocusedKeyboardSurface(nullptr);
});
//delete the client and wait for the server to catch up
QSignalSpy unboundSpy(serverSurface, &QObject::destroyed);
surface.reset();
QVERIFY(unboundSpy.wait());
} }
void TextInputTest::testShowHidePanel_data() void TextInputTest::testShowHidePanel_data()

View file

@ -96,7 +96,7 @@ void TextInputUnstableV2Interface::Private::requestDeactivate(SeatInterface *sea
void TextInputUnstableV2Interface::Private::sendEnter(SurfaceInterface *surface, quint32 serial) void TextInputUnstableV2Interface::Private::sendEnter(SurfaceInterface *surface, quint32 serial)
{ {
if (!resource) { if (!resource || !surface || !surface->resource()) {
return; return;
} }
zwp_text_input_v2_send_enter(resource, serial, surface->resource()); zwp_text_input_v2_send_enter(resource, serial, surface->resource());
@ -104,7 +104,7 @@ void TextInputUnstableV2Interface::Private::sendEnter(SurfaceInterface *surface,
void TextInputUnstableV2Interface::Private::sendLeave(quint32 serial, SurfaceInterface *surface) void TextInputUnstableV2Interface::Private::sendLeave(quint32 serial, SurfaceInterface *surface)
{ {
if (!resource || !surface) { if (!resource || !surface || !surface->resource()) {
return; return;
} }
zwp_text_input_v2_send_leave(resource, serial, surface->resource()); zwp_text_input_v2_send_leave(resource, serial, surface->resource());