Update SurfaceInterface outputs when an output global gets destroyed
Summary: As per existing TODO. A new signal is added on Global to emit so we can process the result whist we still have a valid object. The name is overly explicit to try and logically separate it from QObject::destroyed(). Test Plan: Updated existing unit test. Reviewers: #plasma, graesslin Reviewed By: #plasma, graesslin Subscribers: graesslin, anthonyfieroni, plasma-devel, #frameworks Tags: #frameworks, #plasma_on_wayland Differential Revision: https://phabricator.kde.org/D7531
This commit is contained in:
parent
ec8887ad27
commit
9b564c4069
5 changed files with 24 additions and 8 deletions
|
@ -1077,11 +1077,11 @@ void TestWaylandSurface::testOutput()
|
|||
QCOMPARE(enteredSpy.count(), 2);
|
||||
QCOMPARE(leftSpy.count(), 1);
|
||||
|
||||
//test the client handles a misbehaving server that removes a display before updating clients
|
||||
m_display->removeOutput(serverOutput);
|
||||
QCOMPARE(leftSpy.count(), 1);
|
||||
QVERIFY(s->outputs().isEmpty());
|
||||
|
||||
//delete output client is on.
|
||||
//client should get an exit and be left on no outputs (which is allowed)
|
||||
serverOutput->deleteLater();
|
||||
QVERIFY(leftSpy.wait());
|
||||
QCOMPARE(serverSurface->outputs(), QVector<OutputInterface*>());
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(TestWaylandSurface)
|
||||
|
|
|
@ -70,6 +70,7 @@ void Global::destroy()
|
|||
if (!d->global) {
|
||||
return;
|
||||
}
|
||||
emit aboutToDestroyGlobal();
|
||||
wl_global_destroy(d->global);
|
||||
d->global = nullptr;
|
||||
}
|
||||
|
|
|
@ -90,6 +90,14 @@ public:
|
|||
**/
|
||||
operator wl_global*() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* This signal is emitted when the client is in the process of removing the wl_global.
|
||||
* At the time the signal is emitted the global is still valid and allows to perform
|
||||
* cleanup tasks.
|
||||
*/
|
||||
void aboutToDestroyGlobal();
|
||||
|
||||
protected:
|
||||
class Private;
|
||||
explicit Global(Private *d, QObject *parent = nullptr);
|
||||
|
|
|
@ -793,19 +793,25 @@ void SurfaceInterface::setOutputs(const QVector<OutputInterface *> &outputs)
|
|||
for (wl_resource *r : resources) {
|
||||
wl_surface_send_leave(d->resource, r);
|
||||
}
|
||||
disconnect(d->outputDestroyedConnections.take(*it));
|
||||
}
|
||||
// TODO: send leave when OutputInterface gets destroyed
|
||||
|
||||
QVector<OutputInterface *> addedOutputsOutputs = outputs;
|
||||
for (auto it = d->outputs.constBegin(), end = d->outputs.constEnd(); it != end; ++it) {
|
||||
const auto o = *it;
|
||||
addedOutputsOutputs.removeOne(o);
|
||||
}
|
||||
for (auto it = addedOutputsOutputs.constBegin(), end = addedOutputsOutputs.constEnd(); it != end; ++it) {
|
||||
const auto resources = (*it)->clientResources(client());
|
||||
const auto o = *it;
|
||||
const auto resources = o->clientResources(client());
|
||||
for (wl_resource *r : resources) {
|
||||
wl_surface_send_enter(d->resource, r);
|
||||
}
|
||||
d->outputDestroyedConnections[o] = connect(o, &Global::aboutToDestroyGlobal, this, [this, o] {
|
||||
Q_D();
|
||||
auto outputs = d->outputs;
|
||||
if (outputs.removeOne(o)) {
|
||||
setOutputs(outputs);
|
||||
}});
|
||||
}
|
||||
// TODO: send enter when the client binds the OutputInterface another time
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ public:
|
|||
|
||||
QPointer<LockedPointerInterface> lockedPointer;
|
||||
QPointer<ConfinedPointerInterface> confinedPointer;
|
||||
QHash<OutputInterface*, QMetaObject::Connection> outputDestroyedConnections;
|
||||
|
||||
private:
|
||||
QMetaObject::Connection constrainsOneShotConnection;
|
||||
|
|
Loading…
Reference in a new issue