From fbe8aff43983de064bfe9d6e683d28f35996e733 Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Tue, 12 Jan 2021 11:10:50 +0000 Subject: [PATCH] Send SurfaceInterface::enter events after clients bind to outputs The following order of events are legal: Typically order is: - server announces a new output - client binds to a new output - server updates the surface to be on new output But we can have events occur in the following order: - server announces a new output - server updates the surface to be on new output - client binds to a new output At which point when we update the surface there is no ID to tell the client which output the surface is on. This patch watches for clients binding to output and updates appropriately. --- src/wayland/output_interface.cpp | 2 ++ src/wayland/output_interface.h | 6 ++++++ src/wayland/surface_interface.cpp | 10 +++++++++- src/wayland/surface_interface_p.h | 2 ++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/wayland/output_interface.cpp b/src/wayland/output_interface.cpp index 9f752f8f4d..df23a4b472 100644 --- a/src/wayland/output_interface.cpp +++ b/src/wayland/output_interface.cpp @@ -337,6 +337,8 @@ void OutputInterface::Private::bind(wl_client *client, uint32_t version, uint32_ sendDone(r); c->flush(); + + emit q->bound(display->getConnection(client), r.resource); } void OutputInterface::Private::unbind(wl_resource *resource) diff --git a/src/wayland/output_interface.h b/src/wayland/output_interface.h index 13dbedce1c..f800f827a4 100644 --- a/src/wayland/output_interface.h +++ b/src/wayland/output_interface.h @@ -148,6 +148,12 @@ Q_SIGNALS: **/ void dpmsModeRequested(KWaylandServer::OutputInterface::DpmsMode mode); + /** + * Emitted when a client binds to a given output + * @internal + */ + void bound(ClientConnection *client, wl_resource *boundResource); + private: class Private; Private *d_func() const; diff --git a/src/wayland/surface_interface.cpp b/src/wayland/surface_interface.cpp index 2f1a736534..c6762ff59f 100644 --- a/src/wayland/surface_interface.cpp +++ b/src/wayland/surface_interface.cpp @@ -832,6 +832,7 @@ void SurfaceInterface::setOutputs(const QVector &outputs) d->send_leave(outputResource); } disconnect(d->outputDestroyedConnections.take(*it)); + disconnect(d->outputBoundConnections.take(*it)); } QVector addedOutputsOutputs = outputs; for (auto it = d->outputs.constBegin(), end = d->outputs.constEnd(); it != end; ++it) { @@ -849,8 +850,15 @@ void SurfaceInterface::setOutputs(const QVector &outputs) if (outputs.removeOne(o)) { setOutputs(outputs); }}); + + Q_ASSERT(!d->outputBoundConnections.contains(o)); + d->outputBoundConnections[o] = connect(o, &OutputInterface::bound, this, [this](ClientConnection *c, wl_resource *outputResource) { + if (c != client()) { + return; + } + d->send_enter(outputResource); + }); } - // TODO: send enter when the client binds the OutputInterface another time d->outputs = outputs; for (auto child : d->current.children) { diff --git a/src/wayland/surface_interface_p.h b/src/wayland/surface_interface_p.h index c1a14a3d78..79631c3f6c 100644 --- a/src/wayland/surface_interface_p.h +++ b/src/wayland/surface_interface_p.h @@ -117,6 +117,8 @@ public: LockedPointerV1Interface *lockedPointer = nullptr; ConfinedPointerV1Interface *confinedPointer = nullptr; QHash outputDestroyedConnections; + QHash outputBoundConnections; + QVector idleInhibitors; ViewportInterface *viewportExtension = nullptr; SurfaceInterface *dataProxy = nullptr;