From d6706c5ce4f82530134848b78be9420cf99dae66 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Tue, 30 Aug 2022 12:56:23 +0300 Subject: [PATCH] wayland: Prevent sending xdg_output properties if wl_output is removed If the wl_output has been removed, kwin can crash all Qt clients by sending a wl_output.done event. Also, it makes no sense to send output events after the corresponding output has been removed. CCBUG: 451028 --- src/wayland/output_interface.cpp | 5 +++++ src/wayland/output_interface.h | 1 + src/wayland/xdgoutput_v1_interface.cpp | 14 ++++++++------ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/wayland/output_interface.cpp b/src/wayland/output_interface.cpp index 64ca49a48c..9f06d37814 100644 --- a/src/wayland/output_interface.cpp +++ b/src/wayland/output_interface.cpp @@ -184,6 +184,11 @@ KWin::Output *OutputInterface::handle() const return d->handle; } +bool OutputInterface::isRemoved() const +{ + return d->isGlobalRemoved(); +} + void OutputInterface::remove() { if (d->isGlobalRemoved()) { diff --git a/src/wayland/output_interface.h b/src/wayland/output_interface.h index 8a5a58d13f..95f1c7b261 100644 --- a/src/wayland/output_interface.h +++ b/src/wayland/output_interface.h @@ -51,6 +51,7 @@ public: explicit OutputInterface(Display *display, KWin::Output *handle, QObject *parent = nullptr); ~OutputInterface() override; + bool isRemoved() const; void remove(); KWin::Output *handle() const; diff --git a/src/wayland/xdgoutput_v1_interface.cpp b/src/wayland/xdgoutput_v1_interface.cpp index 2620782715..23e0eb2aa4 100644 --- a/src/wayland/xdgoutput_v1_interface.cpp +++ b/src/wayland/xdgoutput_v1_interface.cpp @@ -195,6 +195,10 @@ void XdgOutputV1InterfacePrivate::zxdg_output_v1_destroy(Resource *resource) void XdgOutputV1InterfacePrivate::zxdg_output_v1_bind_resource(Resource *resource) { + if (!output || output->isRemoved()) { + return; + } + sendLogicalPosition(resource, pos); sendLogicalSize(resource, size); if (resource->version() >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) { @@ -212,7 +216,7 @@ void XdgOutputV1InterfacePrivate::zxdg_output_v1_bind_resource(Resource *resourc void XdgOutputV1InterfacePrivate::sendLogicalSize(Resource *resource, const QSize &size) { - if (!output) { + if (!output || output->isRemoved()) { return; } ClientConnection *connection = output->display()->getConnection(resource->client()); @@ -223,7 +227,7 @@ void XdgOutputV1InterfacePrivate::sendLogicalSize(Resource *resource, const QSiz void XdgOutputV1InterfacePrivate::sendLogicalPosition(Resource *resource, const QPoint &pos) { - if (!output) { + if (!output || output->isRemoved()) { return; } ClientConnection *connection = output->display()->getConnection(resource->client()); @@ -234,14 +238,12 @@ void XdgOutputV1InterfacePrivate::sendLogicalPosition(Resource *resource, const void XdgOutputV1InterfacePrivate::sendDone(Resource *resource) { - if (!doneOnce) { + if (!doneOnce || !output || output->isRemoved()) { return; } if (wl_resource_get_version(resource->handle) >= 3) { - if (output) { - output->done(resource->client()); - } + output->done(resource->client()); } else { send_done(resource->handle); }