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.
This commit is contained in:
Vlad Zahorodnii 2021-09-14 15:48:39 +03:00
parent 177d35cace
commit 5853cc38a1

View file

@ -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,23 +302,20 @@ 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;
const auto modeResource = privateMode->createResource(resource);
send_mode(resource->handle, modeResource);
send_mode(resource->handle, modeResource->handle);
privateMode->bindResource(modeResource);
privateMode->bindResource(modeResource->handle);
return modeResource;
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) {
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<ModeResource *>(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<ModeResource *>(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;