File indexing completed on 2024-05-12 05:38:23
0001 /* 0002 SPDX-FileCopyrightText: 2016 Marco Martin <mart@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include <QObject> 0008 0009 #include <QDir> 0010 #include <QScreen> 0011 #include <QSignalSpy> 0012 #include <QStandardPaths> 0013 #include <QTemporaryDir> 0014 #include <QTest> 0015 #include <plasmaactivities/controller.h> 0016 #include <qtestcase.h> 0017 0018 #include "../desktopview.h" 0019 #include "../panelview.h" 0020 #include "../screenpool.h" 0021 #include "../shellcorona.h" 0022 #include "mockcompositor.h" 0023 #include "xdgoutputv1.h" 0024 0025 using namespace MockCompositor; 0026 0027 class ShellTest : public QObject, DefaultCompositor 0028 { 0029 Q_OBJECT 0030 0031 QScreen *insertScreen(const QRect &geometry, const QString &name); 0032 void setScreenOrder(const QStringList &order, bool expectOrderChanged); 0033 0034 private Q_SLOTS: 0035 void initTestCase(); 0036 void cleanupTestCase(); 0037 void cleanup(); 0038 0039 void testScreenInsertion(); 0040 void testPanelInsertion(); 0041 void testSecondScreenInsertion(); 0042 void testRedundantScreenInsertion(); 0043 void testScreenRemovalRecyclingViews(); 0044 void testMoveOutOfRedundant(); 0045 void testScreenRemoval(); 0046 void testReorderScreens_data(); 0047 void testReorderScreens(); 0048 void testReorderContainments(); 0049 0050 private: 0051 ShellCorona *m_corona; 0052 }; 0053 0054 QScreen *ShellTest::insertScreen(const QRect &geometry, const QString &name) 0055 { 0056 QScreen *result = nullptr; 0057 0058 auto doTest = [=, this](QScreen *&res) { 0059 int oldAppNumScreens = qApp->screens().size(); 0060 int oldCoronaNumScreens = m_corona->numScreens(); 0061 0062 // Fake screen? 0063 if (qApp->screens().size() == 1 && qApp->screens()[0]->name().isEmpty()) { 0064 QCOMPARE(m_corona->numScreens(), 0); 0065 oldAppNumScreens = 0; 0066 } 0067 0068 // QSignalSpy coronaAddedSpy(m_corona, SIGNAL(screenAdded(int))); 0069 QSignalSpy appAddedSpy(qGuiApp, SIGNAL(screenAdded(QScreen *))); 0070 // QSignalSpy orderChangeSpy(m_corona->m_screenPool, &ScreenPool::screenOrderChanged); 0071 0072 // Add a new output 0073 exec([=, this] { 0074 OutputData data; 0075 data.mode.resolution = {geometry.width(), geometry.height()}; 0076 data.position = {geometry.x(), geometry.y()}; 0077 data.physicalSize = data.mode.physicalSizeForDpi(96); 0078 data.connector = name; 0079 // NOTE: assumes that when a screen is added it will already have the final geometry 0080 add<Output>(data); 0081 }); 0082 0083 // coronaAddedSpy.wait(); 0084 QTRY_COMPARE(appAddedSpy.size(), 1); 0085 // QTRY_COMPARE(orderChangeSpy.size(), 1); 0086 QCOMPARE(m_corona->numScreens(), oldCoronaNumScreens); // Corona has *not* been notified yer as setScreenOrder has not been called 0087 QCOMPARE(m_corona->m_desktopViewForScreen.count(), oldCoronaNumScreens); 0088 QCOMPARE(qApp->screens().size(), oldAppNumScreens + 1); 0089 // QCOMPARE(coronaAddedSpy.size(), 1); 0090 // result.first = coronaAddedSpy.takeFirst().at(0).value<int>(); 0091 res = appAddedSpy.takeFirst().at(0).value<QScreen *>(); 0092 QCOMPARE(res->name(), name); 0093 QCOMPARE(res->geometry(), geometry); 0094 /* auto *cont = m_corona->m_desktopViewForScreen[result.first]->containment(); 0095 QCOMPARE(cont->screen(), result.first); 0096 QCOMPARE(m_corona->containmentForScreen(result.first, m_corona->m_activityController->currentActivity(), QString()), cont);*/ 0097 }; 0098 doTest(result); 0099 return result; 0100 } 0101 0102 void ShellTest::setScreenOrder(const QStringList &order, bool expectOrderChanged) 0103 { 0104 QSignalSpy coronaScreenOrderSpy(m_corona, &ShellCorona::screenOrderChanged); 0105 0106 exec([=, this] { 0107 outputOrder()->setList(order); 0108 }); 0109 0110 if (expectOrderChanged) { 0111 coronaScreenOrderSpy.wait(); 0112 Q_ASSERT(coronaScreenOrderSpy.count() == 1); 0113 QCOMPARE(coronaScreenOrderSpy.count(), 1); 0114 auto order = coronaScreenOrderSpy.takeFirst().at(0).value<QList<QScreen *>>(); 0115 QCOMPARE(m_corona->m_desktopViewForScreen.size(), order.size()); 0116 } else { 0117 coronaScreenOrderSpy.wait(250); 0118 Q_ASSERT(coronaScreenOrderSpy.count() == 0); 0119 QCOMPARE(coronaScreenOrderSpy.count(), 0); 0120 } 0121 0122 QCOMPARE(m_corona->m_desktopViewForScreen.size(), m_corona->m_screenPool->screenOrder().size()); 0123 0124 for (int i = 0; i < m_corona->m_screenPool->screenOrder().size(); ++i) { 0125 QVERIFY(m_corona->m_desktopViewForScreen.contains(i)); 0126 QCOMPARE(m_corona->m_desktopViewForScreen[i]->containment()->screen(), i); 0127 QCOMPARE(m_corona->m_desktopViewForScreen[i]->screenToFollow(), m_corona->m_screenPool->screenOrder()[i]); 0128 } 0129 } 0130 0131 void ShellTest::initTestCase() 0132 { 0133 QStandardPaths::setTestModeEnabled(true); 0134 qRegisterMetaType<QScreen *>(); 0135 0136 KConfigGroup cg(KSharedConfig::openConfig(), QStringLiteral("ScreenConnectors")); 0137 cg.deleteGroup(); 0138 cg.sync(); 0139 0140 qApp->setProperty("org.kde.KActivities.core.disableAutostart", true); 0141 m_corona = new ShellCorona(); 0142 m_corona->setShell("org.kde.plasma.nano"); 0143 m_corona->init(); 0144 0145 QTRY_COMPARE(QGuiApplication::screens().size(), 1); 0146 QCOMPARE(m_corona->screenPool()->screenOrder().size(), 1); 0147 QCOMPARE(QGuiApplication::screens().first()->name(), QStringLiteral("WL-1")); 0148 QCOMPARE(QGuiApplication::primaryScreen(), QGuiApplication::screens().first()); 0149 QCOMPARE(QGuiApplication::primaryScreen(), m_corona->screenPool()->primaryScreen()); 0150 QCOMPARE(m_corona->screenPool()->idForScreen(m_corona->screenPool()->primaryScreen()), 0); 0151 QCOMPARE(m_corona->screenPool()->screenForId(0)->name(), QStringLiteral("WL-1")); 0152 } 0153 0154 void ShellTest::cleanupTestCase() 0155 { 0156 exec([this] { 0157 outputOrder()->setList({"WL-1"}); 0158 }); 0159 QCOMPOSITOR_COMPARE(getAll<Output>().size(), 1); // Only the default output should be left 0160 QTRY_COMPARE(QGuiApplication::screens().size(), 1); 0161 // m_corona->deleteLater(); 0162 m_corona->unload(); 0163 QCOMPARE(m_corona->m_desktopViewForScreen.count(), 0); 0164 0165 QTRY_VERIFY2(isClean(), qPrintable(dirtyMessage())); 0166 0167 KConfigGroup cg(KSharedConfig::openConfig(), QStringLiteral("ScreenConnectors")); 0168 cg.deleteGroup(); 0169 cg.sync(); 0170 delete m_corona; 0171 } 0172 0173 void ShellTest::cleanup() 0174 { 0175 const int oldNumScreens = qApp->screens().size(); 0176 const int oldCoronaNumScreens = m_corona->numScreens(); 0177 QVERIFY(oldCoronaNumScreens <= oldNumScreens); 0178 QSignalSpy coronaRemovedSpy(m_corona, SIGNAL(screenRemoved(int))); 0179 0180 exec([=, this] { 0181 for (int i = oldNumScreens - 1; i >= 0; --i) { 0182 remove(output(i)); 0183 } 0184 }); 0185 setScreenOrder({}, true); 0186 0187 QTRY_COMPARE(coronaRemovedSpy.size(), oldCoronaNumScreens); 0188 0189 // Cleanup all the containments that were created 0190 for (auto *c : m_corona->containments()) { 0191 if (c->containmentType() == Plasma::Containment::Panel || c->screen() != 0) { 0192 c->destroy(); 0193 } 0194 } 0195 m_corona->m_waitingPanels.clear(); 0196 0197 QCOMPARE(m_corona->m_panelViews.size(), 0); 0198 QCOMPARE(m_corona->numScreens(), 0); 0199 QCOMPARE(qApp->screens().size(), 1); 0200 QCOMPARE(qApp->screens()[0]->name(), QString()); 0201 insertScreen(QRect(0, 0, 1920, 1080), QStringLiteral("WL-1")); 0202 QCOMPARE(qApp->screens().size(), 1); 0203 QSignalSpy coronaScreenOrderSpy(m_corona, &ShellCorona::screenOrderChanged); 0204 setScreenOrder({"WL-1"}, true); 0205 } 0206 0207 void ShellTest::testScreenInsertion() 0208 { 0209 const auto geom = QRect(1920, 0, 1920, 1080); 0210 const auto name = QStringLiteral("DP-1"); 0211 auto result = insertScreen(geom, name); 0212 setScreenOrder({"WL-1", "DP-1"}, true); 0213 QCOMPARE(result->geometry(), geom); 0214 QCOMPARE(qApp->screens().size(), 2); 0215 QCOMPARE(qApp->screens()[0]->geometry(), m_corona->m_desktopViewForScreen[0]->geometry()); 0216 QCOMPARE(qApp->screens()[1]->geometry(), m_corona->m_desktopViewForScreen[1]->geometry()); 0217 QCOMPARE(qApp->screens()[1]->name(), name); 0218 } 0219 0220 void ShellTest::testPanelInsertion() 0221 { 0222 QCOMPARE(m_corona->m_panelViews.size(), 0); 0223 auto panelCont = m_corona->addPanel(QStringLiteral("org.kde.panel")); 0224 // If the panel fails to load (on ci plasma-desktop isn't here) we want the "failed" containment to be of panel type anyways 0225 QCOMPARE(m_corona->m_panelViews.size(), 1); 0226 QVERIFY(m_corona->m_panelViews.contains(panelCont)); 0227 QCOMPARE(panelCont->screen(), 0); 0228 QCOMPARE(m_corona->m_panelViews[panelCont]->screen(), qApp->primaryScreen()); 0229 } 0230 0231 void ShellTest::testSecondScreenInsertion() 0232 { 0233 auto geom1 = QRect(1920, 0, 1920, 1080); 0234 auto name1 = QStringLiteral("DP-1"); 0235 auto result1 = insertScreen(geom1, name1); 0236 0237 auto geom2 = QRect(3840, 0, 1920, 1080); 0238 auto name2 = QStringLiteral("DP-2"); 0239 auto result2 = insertScreen(geom2, name2); 0240 0241 setScreenOrder({"WL-1", "DP-1", "DP-2"}, true); 0242 0243 QCOMPARE(qApp->screens().size(), 3); 0244 QCOMPARE(result1->geometry(), geom1); 0245 QCOMPARE(result1->name(), name1); 0246 0247 QCOMPARE(result2->geometry(), geom2); 0248 QCOMPARE(result2->name(), name2); 0249 } 0250 0251 void ShellTest::testRedundantScreenInsertion() 0252 { 0253 QCOMPARE(m_corona->m_desktopViewForScreen.size(), 1); 0254 auto *view0 = m_corona->m_desktopViewForScreen[0]; 0255 QCOMPARE(view0->screen()->name(), QStringLiteral("WL-1")); 0256 0257 auto *cont0 = m_corona->m_desktopViewForScreen[0]->containment(); 0258 QCOMPARE(cont0->screen(), 0); 0259 auto *oldScreen0 = view0->screen(); 0260 0261 const auto geom = QRect(0, 0, 1920, 1080); 0262 const auto name = QStringLiteral("DP-1"); 0263 auto result = insertScreen(geom, name); 0264 // false as we do not expect to be notified for screenorderchanged 0265 setScreenOrder({"WL-1", "DP-1"}, false); 0266 QCOMPARE(result->geometry(), geom); 0267 QCOMPARE(qApp->screens().size(), 2); 0268 // m_desktopViewForScreen did *not* get a view for the new screen 0269 QCOMPARE(m_corona->m_desktopViewForScreen.size(), 1); 0270 // associations of old things didn't change 0271 QCOMPARE(view0->containment(), cont0); 0272 QCOMPARE(cont0->screen(), 0); 0273 QCOMPARE(view0->screen(), oldScreen0); 0274 } 0275 0276 void ShellTest::testMoveOutOfRedundant() 0277 { 0278 testRedundantScreenInsertion(); 0279 0280 QSignalSpy coronaAddedSpy(m_corona, SIGNAL(screenAdded(int))); 0281 0282 exec([this] { 0283 auto *out = output(1); 0284 auto *xdgOut = xdgOutput(out); 0285 out->m_data.mode.resolution = {1280, 2048}; 0286 xdgOut->sendLogicalSize(QSize(1280, 2048)); 0287 out->sendDone(); 0288 outputOrder()->setList({"WL-1", "DP-1"}); 0289 }); 0290 0291 coronaAddedSpy.wait(); 0292 QCOMPARE(coronaAddedSpy.size(), 1); 0293 const int screen = coronaAddedSpy.takeFirst().at(0).value<int>(); 0294 QCOMPARE(screen, 1); 0295 } 0296 0297 void ShellTest::testScreenRemoval() 0298 { 0299 // Create 2 new screens 0300 testSecondScreenInsertion(); 0301 0302 Plasma::Containment *cont0 = m_corona->containmentForScreen(0, m_corona->m_activityController->currentActivity(), QString()); 0303 QVERIFY(cont0); 0304 QCOMPARE(cont0->screen(), 0); 0305 Plasma::Containment *cont1 = m_corona->containmentForScreen(1, m_corona->m_activityController->currentActivity(), QString()); 0306 QVERIFY(cont1); 0307 QCOMPARE(cont1->screen(), 1); 0308 Plasma::Containment *cont2 = m_corona->containmentForScreen(2, m_corona->m_activityController->currentActivity(), QString()); 0309 QVERIFY(cont2); 0310 QCOMPARE(cont2->screen(), 2); 0311 0312 QCOMPARE(m_corona->m_panelViews.size(), 0); 0313 auto panelCont = m_corona->addPanel(QStringLiteral("org.kde.plasma.panel")); 0314 m_corona->m_panelViews[panelCont]->setScreenToFollow(m_corona->m_screenPool->screenForId(2)); 0315 QCOMPARE(panelCont->screen(), 2); 0316 QCOMPARE(m_corona->m_panelViews[panelCont]->screen(), m_corona->m_screenPool->screenForId(2)); 0317 QCOMPARE(m_corona->m_panelViews.size(), 1); 0318 0319 QSignalSpy removedSpy(m_corona, SIGNAL(screenRemoved(int))); 0320 0321 // Remove outputs 0322 exec([this] { 0323 remove(output(2)); 0324 remove(output(1)); 0325 }); 0326 0327 QTRY_COMPARE(removedSpy.size(), 2); 0328 0329 setScreenOrder({"WL-1"}, true); 0330 0331 QCOMPARE(m_corona->numScreens(), 1); 0332 QCOMPARE(qApp->screens().size(), 1); 0333 0334 // the removed screens are what corona calls 1 and 2, 0 remains 0335 QCOMPARE(removedSpy.takeFirst().at(0).value<int>(), 2); 0336 QCOMPARE(removedSpy.takeFirst().at(0).value<int>(), 1); 0337 QCOMPARE(m_corona->m_desktopViewForScreen.count(), 1); 0338 // The only view remained is the one which was primary already 0339 QCOMPARE(cont0, m_corona->m_desktopViewForScreen[0]->containment()); 0340 QCOMPARE(qApp->screens()[0]->geometry(), m_corona->m_desktopViewForScreen[0]->geometry()); 0341 0342 // Has the panelview been removed? 0343 QCOMPARE(m_corona->m_panelViews.size(), 0); 0344 0345 bool cont1Found = false; 0346 bool cont2Found = false; 0347 // Search for the other two containments, should have screen() -1 and lastScreen 1 and 2 0348 for (auto *cont : m_corona->containments()) { 0349 if (cont == cont1) { 0350 cont1Found = true; 0351 QCOMPARE(cont->screen(), -1); 0352 QCOMPARE(cont->lastScreen(), 1); 0353 } else if (cont == cont2) { 0354 cont2Found = true; 0355 QCOMPARE(cont->screen(), -1); 0356 QCOMPARE(cont->lastScreen(), 2); 0357 } 0358 } 0359 QVERIFY(cont1Found); 0360 QVERIFY(cont2Found); 0361 } 0362 0363 void ShellTest::testScreenRemovalRecyclingViews() 0364 { 0365 // Create 2 new screens 0366 testSecondScreenInsertion(); 0367 0368 Plasma::Containment *cont0 = m_corona->containmentForScreen(0, m_corona->m_activityController->currentActivity(), QString()); 0369 QVERIFY(cont0); 0370 QCOMPARE(cont0->screen(), 0); 0371 Plasma::Containment *cont1 = m_corona->containmentForScreen(1, m_corona->m_activityController->currentActivity(), QString()); 0372 QVERIFY(cont1); 0373 QCOMPARE(cont1->screen(), 1); 0374 Plasma::Containment *cont2 = m_corona->containmentForScreen(2, m_corona->m_activityController->currentActivity(), QString()); 0375 QVERIFY(cont2); 0376 QCOMPARE(cont2->screen(), 2); 0377 0378 auto *view0 = m_corona->m_desktopViewForScreen[0]; 0379 auto screen0 = view0->screenToFollow(); 0380 auto *view1 = m_corona->m_desktopViewForScreen[1]; 0381 auto screen1 = view1->screenToFollow(); 0382 auto *view2 = m_corona->m_desktopViewForScreen[2]; 0383 auto screen2 = view2->screenToFollow(); 0384 0385 QSignalSpy view2DeletedSpy(view2, &DesktopView::destroyed); 0386 QSignalSpy screen1DeletedSpy(screen1, &DesktopView::destroyed); 0387 0388 // Create a panel on screen 1 0389 QCOMPARE(m_corona->m_panelViews.size(), 0); 0390 auto panelCont = m_corona->addPanel(QStringLiteral("org.kde.plasma.panel")); 0391 QCOMPARE(m_corona->m_panelViews.size(), 1); 0392 auto panelView = m_corona->m_panelViews[panelCont]; 0393 panelView->setScreenToFollow(m_corona->m_screenPool->screenForId(1)); 0394 QCOMPARE(panelCont->screen(), 1); 0395 QCOMPARE(panelView->screen(), m_corona->m_screenPool->screenForId(1)); 0396 QCOMPARE(m_corona->m_panelViews.size(), 1); 0397 0398 QSignalSpy removedSpy(m_corona, SIGNAL(screenRemoved(int))); 0399 0400 // Remove output 0401 exec([this] { 0402 remove(output(1)); 0403 }); 0404 0405 QTRY_COMPARE(removedSpy.size(), 1); 0406 0407 setScreenOrder({"WL-1", "DP-2"}, true); 0408 0409 QTRY_COMPARE(view2DeletedSpy.count(), 1); 0410 QTRY_COMPARE(screen1DeletedSpy.count(), 1); 0411 0412 QCOMPARE(m_corona->numScreens(), 2); 0413 QCOMPARE(qApp->screens().size(), 2); 0414 // the removed screens are what corona calls 1 and 2, 0 remains 0415 QCOMPARE(removedSpy.takeFirst().at(0).value<int>(), 2); 0416 QCOMPARE(m_corona->m_desktopViewForScreen.count(), 2); 0417 0418 // Views for cont0 and cont1 remained, cont1 reassigned screen 0419 QCOMPARE(cont0, m_corona->m_desktopViewForScreen[0]->containment()); 0420 QCOMPARE(cont1, m_corona->m_desktopViewForScreen[1]->containment()); 0421 QCOMPARE(view0, m_corona->m_desktopViewForScreen[0]); 0422 QCOMPARE(view1, m_corona->m_desktopViewForScreen[1]); 0423 QCOMPARE(view0->screenToFollow(), screen0); 0424 QCOMPARE(view1->screenToFollow(), screen2); 0425 0426 // The panel remained, moved to screen2 0427 QCOMPARE(m_corona->m_panelViews.size(), 1); 0428 QCOMPARE(panelView->screenToFollow(), screen2); 0429 0430 // Add DP-1 again, test that a view with cont2 inside is created 0431 insertScreen(QRect(1920, 0, 1920, 1080), QStringLiteral("DP-1")); 0432 0433 setScreenOrder({"WL-1", "DP-2", "DP-1"}, true); 0434 0435 auto *newView2 = m_corona->m_desktopViewForScreen[2]; 0436 QCOMPARE(m_corona->m_desktopViewForScreen.size(), 3); 0437 QCOMPARE(newView2->containment(), cont2); 0438 } 0439 0440 void ShellTest::testReorderScreens_data() 0441 { 0442 QTest::addColumn<QList<QRect>>("geometries"); 0443 QTest::addColumn<QStringList>("orderBefore"); 0444 QTest::addColumn<QStringList>("orderAfter"); 0445 0446 QTest::newRow("twoScreens") << QList<QRect>({{0, 0, 1920, 1080}, {1920, 0, 1920, 1080}}) << QStringList({"WL-1", "DP-1"}) << QStringList({"DP-1", "WL-1"}); 0447 QTest::newRow("3screensReorder0_1") << QList<QRect>({{0, 0, 1920, 1080}, {1920, 0, 1920, 1080}, {3840, 0, 1920, 1080}}) 0448 << QStringList({"WL-1", "DP-1", "DP-2"}) << QStringList({"DP-1", "WL-1", "DP-2"}); 0449 QTest::newRow("3screensReorder2_3") << QList<QRect>({{0, 0, 1920, 1080}, {1920, 0, 1920, 1080}, {3840, 0, 1920, 1080}}) 0450 << QStringList({"WL-1", "DP-1", "DP-2"}) << QStringList({"DP-1", "WL-1", "DP-2"}); 0451 QTest::newRow("3screensShuffled") << QList<QRect>({{0, 0, 1920, 1080}, {1920, 0, 1920, 1080}, {3840, 0, 1920, 1080}}) 0452 << QStringList({"WL-1", "DP-1", "DP-2"}) << QStringList({"DP-2", "DP-1", "WL-1"}); 0453 } 0454 0455 void ShellTest::testReorderScreens() 0456 { 0457 QFETCH(QList<QRect>, geometries); 0458 QFETCH(QStringList, orderBefore); 0459 QFETCH(QStringList, orderAfter); 0460 0461 QVERIFY(orderBefore.size() > 0); 0462 QCOMPARE(orderBefore.size(), geometries.size()); 0463 QCOMPARE(orderBefore.size(), orderAfter.size()); 0464 // At the beginning of the test there is always a default one 0465 QCOMPARE(orderBefore.first(), QStringLiteral("WL-1")); 0466 0467 QHash<int, int> remapIndexes; 0468 0469 for (int i = 0; i < orderBefore.size(); ++i) { 0470 const QString conn = orderBefore[i]; 0471 remapIndexes[i] = orderAfter.indexOf(conn); 0472 // Verify that we have same connectors in orderBefore and orderAfter 0473 QVERIFY(remapIndexes[i] >= 0); 0474 if (conn != QStringLiteral("WL-1")) { 0475 insertScreen(geometries[i], conn); 0476 } 0477 } 0478 setScreenOrder(orderBefore, true); 0479 0480 QList<DesktopView *> desktopViews; 0481 QList<PanelView *> panelViews; 0482 QList<Plasma::Containment *> desktopContainments; 0483 QList<Plasma::Containment *> panelContainments; 0484 QList<QScreen *> screens; 0485 0486 for (int i = 0; i < orderBefore.size(); ++i) { 0487 auto *view = m_corona->m_desktopViewForScreen[i]; 0488 desktopViews.append(view); 0489 desktopContainments.append(view->containment()); 0490 screens.append(view->screenToFollow()); 0491 0492 QCOMPARE(view->screen()->name(), orderBefore[i]); 0493 QCOMPARE(view->containment()->screen(), i); 0494 } 0495 0496 // Add a panel for each screen 0497 for (int i = 0; i < screens.size(); ++i) { 0498 QScreen *s = screens[i]; 0499 auto panelCont = m_corona->addPanel(QStringLiteral("org.kde.plasma.panel")); 0500 // If the panel fails to load (on ci plasma-desktop isn't here) we want the "failed" containment to be of panel type anyways 0501 QVERIFY(m_corona->m_panelViews.contains(panelCont)); 0502 QCOMPARE(panelCont->screen(), 0); 0503 m_corona->m_panelViews[panelCont]->setScreenToFollow(s); 0504 QCOMPARE(panelCont->screen(), i); 0505 panelViews.append(m_corona->m_panelViews[panelCont]); 0506 panelContainments.append(panelCont); 0507 } 0508 0509 QSignalSpy coronaScreenOrderSpy(m_corona, &ShellCorona::screenOrderChanged); 0510 setScreenOrder(orderAfter, true); 0511 0512 QTRY_COMPARE(coronaScreenOrderSpy.count(), 1); 0513 QList<QScreen *> qScreenOrderFormSignal = coronaScreenOrderSpy.takeFirst().at(0).value<QList<QScreen *>>(); 0514 0515 QCOMPARE(qScreenOrderFormSignal.size(), orderAfter.size()); 0516 for (int i = 0; i < qScreenOrderFormSignal.size(); ++i) { 0517 QCOMPARE(qScreenOrderFormSignal[i]->name(), orderAfter[i]); 0518 } 0519 0520 for (int i = 0; i < orderAfter.size(); ++i) { 0521 auto *view = m_corona->m_desktopViewForScreen[i]; 0522 view->screenToFollow(); 0523 } 0524 0525 QList<DesktopView *> desktopViewsAfter; 0526 QList<PanelView *> panelViewsAfter; 0527 panelViewsAfter.resize(orderAfter.size()); 0528 QList<Plasma::Containment *> desktopContainmentsAfter; 0529 QList<Plasma::Containment *> panelContainmentsAfter; 0530 panelContainmentsAfter.resize(orderAfter.size()); 0531 QList<QScreen *> screensAfter; 0532 0533 for (int i = 0; i < orderAfter.size(); ++i) { 0534 auto *view = m_corona->m_desktopViewForScreen[i]; 0535 desktopViewsAfter.append(view); 0536 desktopContainmentsAfter.append(view->containment()); 0537 screensAfter.append(view->screenToFollow()); 0538 0539 QCOMPARE(view->screenToFollow(), qScreenOrderFormSignal[i]); 0540 QCOMPARE(view->screen()->name(), orderAfter[i]); 0541 QCOMPARE(view->containment()->screen(), i); 0542 } 0543 0544 { 0545 QSet<int> allScreenIds; 0546 for (int i = 0; i < orderAfter.size(); ++i) { 0547 allScreenIds.insert(i); 0548 } 0549 for (PanelView *v : m_corona->m_panelViews) { 0550 Plasma::Containment *cont = v->containment(); 0551 QVERIFY(cont->screen() >= 0); 0552 QVERIFY(allScreenIds.contains(cont->screen())); 0553 panelViewsAfter[cont->screen()] = v; 0554 panelContainmentsAfter[cont->screen()] = cont; 0555 allScreenIds.remove(cont->screen()); 0556 } 0557 } 0558 0559 for (int i = 0; i < orderAfter.size(); ++i) { 0560 QCOMPARE(desktopViews[i], desktopViewsAfter[i]); 0561 QCOMPARE(panelViews[i], panelViewsAfter[i]); 0562 QCOMPARE(desktopContainments[i], desktopContainmentsAfter[i]); 0563 QCOMPARE(panelContainments[i], panelContainmentsAfter[i]); 0564 QCOMPARE(screens[i], screensAfter[remapIndexes[i]]); 0565 0566 QCOMPARE(desktopViewsAfter[i]->screenToFollow(), screensAfter[i]); 0567 QCOMPARE(desktopViewsAfter[i]->screenToFollow(), screens[remapIndexes[i]]); 0568 QCOMPARE(panelViewsAfter[i]->screenToFollow(), screensAfter[i]); 0569 QCOMPARE(panelViewsAfter[i]->screenToFollow(), screens[remapIndexes[i]]); 0570 } 0571 } 0572 0573 void ShellTest::testReorderContainments() 0574 { 0575 // this tests assigning different screens to containments without the actual order changing 0576 testSecondScreenInsertion(); 0577 testPanelInsertion(); 0578 0579 QList<DesktopView *> desktopViews; 0580 QList<Plasma::Containment *> desktopContainments; 0581 QList<QScreen *> screens = m_corona->m_screenPool->screenOrder().toVector(); 0582 QCOMPARE(screens.size(), 3); 0583 0584 for (int i = 0; i < screens.size(); ++i) { 0585 auto *view = m_corona->m_desktopViewForScreen[i]; 0586 desktopViews.append(view); 0587 desktopContainments.append(view->containment()); 0588 0589 QCOMPARE(view->screen(), screens[i]); 0590 QCOMPARE(view->containment()->screen(), i); 0591 } 0592 QCOMPARE(desktopViews.size(), 3); 0593 /*Disable the test on panels for now, as the fake containment we create here would be og NoContainment type 0594 QCOMPARE(m_corona->m_panelViews.size(), 1); 0595 auto *panelView = m_corona->m_panelViews.values().first(); 0596 auto panelContainment = panelView->containment(); 0597 QCOMPARE(panelView->screen(), screens[0]); 0598 QCOMPARE(panelContainment->screen(), 0); 0599 0600 // Move panel to screen 1 0601 m_corona->setScreenForContainment(panelContainment, 1); 0602 QCOMPARE(panelView->screen(), screens[1]); 0603 QCOMPARE(panelContainment->screen(), 1); 0604 */ 0605 0606 // Move containment at screen 0 to 1 0607 QCOMPARE(desktopContainments[0]->screen(), 0); 0608 QCOMPARE(desktopContainments[1]->screen(), 1); 0609 m_corona->setScreenForContainment(desktopContainments[0], 1); 0610 0611 QCOMPARE(desktopContainments[0]->screen(), 1); 0612 QCOMPARE(desktopContainments[1]->screen(), 0); 0613 QCOMPARE(desktopViews[0]->screenToFollow(), screens[1]); 0614 QCOMPARE(desktopViews[1]->screenToFollow(), screens[0]); 0615 } 0616 0617 QCOMPOSITOR_TEST_MAIN(ShellTest) 0618 0619 #include "shelltest.moc"