From 5853cc38a174e08845e612a6abffbcaf12d3efbb Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Tue, 14 Sep 2021 15:48:39 +0300 Subject: [PATCH] Send kde_output_device_v1.current_mode to the right resource Currently, send_current_mode() is called for every mode resource, no matter whether the given output resource and mode resource belong to the same client, libwayland-server doesn't like that and it prints a warning about a compositor bug. With this change, the output device will remember the mode resources for every output resource and avoid sending current_mode events with modes that belong to other clients. --- src/wayland/outputdevice_v2_interface.cpp | 51 ++++++++++++++++++----- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/src/wayland/outputdevice_v2_interface.cpp b/src/wayland/outputdevice_v2_interface.cpp index f0c1f0fc0c..98a4d19ce4 100644 --- a/src/wayland/outputdevice_v2_interface.cpp +++ b/src/wayland/outputdevice_v2_interface.cpp @@ -91,9 +91,16 @@ protected: class OutputDeviceModeV2InterfacePrivate : public QtWaylandServer::kde_output_device_mode_v2 { public: + struct ModeResource : Resource { + OutputDeviceV2InterfacePrivate::Resource *output; + }; + OutputDeviceModeV2InterfacePrivate(OutputDeviceModeV2Interface *q, const QSize &size, int refreshRate, OutputDeviceModeV2Interface::ModeFlags flags); ~OutputDeviceModeV2InterfacePrivate() override; + Resource *createResource(OutputDeviceV2InterfacePrivate::Resource *output); + Resource *findResource(OutputDeviceV2InterfacePrivate::Resource *output) const; + void bindResource(wl_resource *resource); static OutputDeviceModeV2InterfacePrivate *get(OutputDeviceModeV2Interface *mode) { return mode->d.data(); } @@ -103,6 +110,9 @@ public: QSize m_size; int m_refreshRate = 60000; OutputDeviceModeV2Interface::ModeFlags m_flags; + +protected: + Resource *kde_output_device_mode_v2_allocate() override; }; OutputDeviceV2InterfacePrivate::OutputDeviceV2InterfacePrivate(OutputDeviceV2Interface *q, Display *display) @@ -292,22 +302,19 @@ wl_resource *OutputDeviceV2InterfacePrivate::sendNewMode(Resource *resource, Out { auto privateMode = OutputDeviceModeV2InterfacePrivate::get(mode); // bind mode to client - const auto modeResource = privateMode->add(resource->client(), resource->version())->handle; - - send_mode(resource->handle, modeResource); + const auto modeResource = privateMode->createResource(resource); - privateMode->bindResource(modeResource); + send_mode(resource->handle, modeResource->handle); - return modeResource; + privateMode->bindResource(modeResource->handle); + + return modeResource->handle; } void OutputDeviceV2InterfacePrivate::sendCurrentMode(Resource *outputResource, OutputDeviceModeV2Interface *mode) { - // mode must already be known to the client - const auto modeResources = OutputDeviceModeV2InterfacePrivate::get(mode)->resourceMap(); - for (auto modeResource : modeResources) { - send_current_mode(outputResource->handle, modeResource->handle); - } + const auto modeResource = OutputDeviceModeV2InterfacePrivate::get(mode)->findResource(outputResource); + send_current_mode(outputResource->handle, modeResource->handle); } void OutputDeviceV2InterfacePrivate::sendGeometry(Resource *resource) @@ -763,6 +770,30 @@ OutputDeviceModeV2InterfacePrivate::~OutputDeviceModeV2InterfacePrivate() } } +OutputDeviceModeV2InterfacePrivate::Resource *OutputDeviceModeV2InterfacePrivate::createResource(OutputDeviceV2InterfacePrivate::Resource *output) +{ + const auto modeResource = static_cast(add(output->client(), output->version())); + modeResource->output = output; + return modeResource; +} + +OutputDeviceModeV2InterfacePrivate::Resource *OutputDeviceModeV2InterfacePrivate::findResource(OutputDeviceV2InterfacePrivate::Resource *output) const +{ + const auto resources = resourceMap(); + for (const auto &resource : resources) { + auto modeResource = static_cast(resource); + if (modeResource->output == output) { + return resource; + } + } + return nullptr; +} + +OutputDeviceModeV2InterfacePrivate::Resource *OutputDeviceModeV2InterfacePrivate::kde_output_device_mode_v2_allocate() +{ + return new ModeResource; +} + QSize OutputDeviceModeV2Interface::size() const { return d->m_size;