diff --git a/autotests/integration/outputmanagement_test.cpp b/autotests/integration/outputmanagement_test.cpp index f723f2214e..729d809665 100644 --- a/autotests/integration/outputmanagement_test.cpp +++ b/autotests/integration/outputmanagement_test.cpp @@ -43,6 +43,7 @@ private Q_SLOTS: void cleanup(); void testOutputDeviceDisabled(); + void testOutputDeviceRemoved(); }; void TestOutputManagement::initTestCase() @@ -50,6 +51,7 @@ void TestOutputManagement::initTestCase() qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType(); qRegisterMetaType("AbstractOutput *"); qRegisterMetaType(); qRegisterMetaType(); @@ -172,5 +174,68 @@ void TestOutputManagement::testOutputDeviceDisabled() QCOMPARE(outputDisabledSpy.count(), 0); } +void TestOutputManagement::testOutputDeviceRemoved() +{ + // This tests checks that OutputConfiguration::apply aka Platform::requestOutputsChange works as expected + // when removing a virtual OutputDevice + + QScopedPointer surface(Test::createSurface()); + QScopedPointer shellSurface(Test::createXdgShellStableSurface(surface.data())); + auto size = QSize(200,200); + + QSignalSpy outputEnteredSpy(surface.data(), &Surface::outputEntered); + QSignalSpy outputLeftSpy(surface.data(), &Surface::outputLeft); + + QSignalSpy outputEnabledSpy(kwinApp()->platform(), &Platform::outputEnabled); + QSignalSpy outputDisabledSpy(kwinApp()->platform(), &Platform::outputDisabled); + QSignalSpy outputRemovedSpy(kwinApp()->platform(), &Platform::outputRemoved); + + auto c = Test::renderAndWaitForShown(surface.data(), size, Qt::blue); + //move to be in the first screen + c->move(QPoint(100,100)); + //we don't don't know where the compositor first placed this window, + //this might fire, it might not + outputEnteredSpy.wait(5); + outputEnteredSpy.clear(); + QCOMPARE(waylandServer()->display()->outputs().count(), 2); + + QCOMPARE(surface->outputs().count(), 1); + Output *firstOutput = surface->outputs().first(); + QCOMPARE(firstOutput->globalPosition(), QPoint(0,0)); + QSignalSpy modesChangedSpy(firstOutput, &Output::modeChanged); + + QSignalSpy screenChangedSpy(screens(), &KWin::Screens::changed); + + QCOMPARE(Test::waylandOutputDevices().count(), 2); + + OutputDevice *device = Test::waylandOutputDevices().first(); + QCOMPARE(device->enabled(), OutputDevice::Enablement::Enabled); + + QSignalSpy outputDeviceEnabledChangedSpy(device, &OutputDevice::enabledChanged); + + AbstractOutput *output = kwinApp()->platform()->outputs().first(); + // Removes an output + QMetaObject::invokeMethod(kwinApp()->platform(), "removeOutput", Qt::DirectConnection, Q_ARG(AbstractOutput *, output)); + + // Let the new state propagate + QVERIFY(outputEnteredSpy.wait()); + + QCOMPARE(waylandServer()->display()->outputs().count(), 1); + QCOMPARE(waylandServer()->display()->outputDevices().count(), 1); + + QCOMPARE(Test::waylandOutputDevices().count(), 1); + QCOMPARE(outputDeviceEnabledChangedSpy.count(), 1); + QCOMPARE(device->enabled(), OutputDevice::Enablement::Disabled); + QCOMPARE(outputLeftSpy.count(), 1); + QCOMPARE(outputEnteredSpy.count(), 1); // surface moved to the other screen + QCOMPARE(surface->outputs().count(), 1); + QCOMPARE(screens()->count(), 1); + QCOMPARE(screenChangedSpy.count(), 3); + QCOMPARE(modesChangedSpy.count(), 0); + QCOMPARE(outputEnabledSpy.count(), 0); + QCOMPARE(outputDisabledSpy.count(), 1); + QCOMPARE(outputRemovedSpy.count(), 1); +} + WAYLANDTEST_MAIN(TestOutputManagement) #include "outputmanagement_test.moc" diff --git a/plugins/platforms/virtual/virtual_backend.cpp b/plugins/platforms/virtual/virtual_backend.cpp index 931d9661e7..1def00f39b 100644 --- a/plugins/platforms/virtual/virtual_backend.cpp +++ b/plugins/platforms/virtual/virtual_backend.cpp @@ -159,12 +159,10 @@ void VirtualBackend::enableOutput(VirtualOutput *output, bool enable) void VirtualBackend::removeOutput(AbstractOutput *output) { VirtualOutput *virtualOutput = static_cast(output); - if (m_outputsEnabled.removeOne(virtualOutput)) { - emit outputDisabled(virtualOutput); - } + virtualOutput->setEnabled(false); + m_outputs.removeOne(virtualOutput); emit outputRemoved(virtualOutput); - m_outputsEnabled.removeOne(virtualOutput); delete virtualOutput; diff --git a/plugins/platforms/virtual/virtual_backend.h b/plugins/platforms/virtual/virtual_backend.h index 151e3d1d82..49012e1f26 100644 --- a/plugins/platforms/virtual/virtual_backend.h +++ b/plugins/platforms/virtual/virtual_backend.h @@ -54,7 +54,7 @@ public: void enableOutput(VirtualOutput *output, bool enable); - void removeOutput(AbstractOutput *output); + Q_INVOKABLE void removeOutput(AbstractOutput *output); Q_SIGNALS: void virtualOutputsSet(bool countChanged);