on f85133b help sign in
unity8/tests/plugins/WindowManager/tst_TopLevelWindowModel.cpp
192 lines 7.2 kB history raw
1/*
2 * Copyright (C) 2017 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
17// There is a companion set of QMLTests for TLWM in tst_QMLTopLevelWindowModel.qml.
19#include <QtTest/QtTest>
20#include <QSignalSpy>
22// WindowManager plugin
23#include <TopLevelWindowModel.h>
24#include <Window.h>
26#include "UnityApplicationMocks.h"
28class tst_TopLevelWindowModel : public QObject
30 Q_OBJECT
32private Q_SLOTS:
33 void init(); // called right before each and every test function is executed
34 void cleanup(); // called right after each and every test function is executed
36 void singleSurfaceStartsHidden();
37 void secondSurfaceIsHidden();
38 void rootFocus();
39 void rootFocusInhibit();
41private:
42 ApplicationManager *applicationManager{nullptr};
43 SurfaceManager *surfaceManager{nullptr};
44 TopLevelWindowModel *topLevelWindowModel{nullptr};
45};
47void tst_TopLevelWindowModel::init()
49 applicationManager = new ApplicationManager;
50 surfaceManager = new SurfaceManager;
52 topLevelWindowModel = new TopLevelWindowModel;
53 topLevelWindowModel->setApplicationManager(applicationManager);
54 topLevelWindowModel->setSurfaceManager(surfaceManager);
57void tst_TopLevelWindowModel::cleanup()
59 delete topLevelWindowModel;
60 topLevelWindowModel = nullptr;
62 delete surfaceManager;
63 surfaceManager = nullptr;
65 delete applicationManager;
66 applicationManager = nullptr;
69void tst_TopLevelWindowModel::singleSurfaceStartsHidden()
71 QCOMPARE(topLevelWindowModel->rowCount(), 0);
73 auto application = static_cast<Application*>(applicationManager->startApplication(QString("hello-world"), QStringList()));
75 QCOMPARE(topLevelWindowModel->rowCount(), 1);
76 QCOMPARE((void*)topLevelWindowModel->windowAt(0)->surface(), (void*)nullptr);
78 auto surface = new MirSurface;
79 surface->m_state = Mir::HiddenState;
80 application->m_surfaceList.addSurface(surface);
81 Q_EMIT surfaceManager->surfaceCreated(surface);
83 QCOMPARE(topLevelWindowModel->rowCount(), 1);
84 // not showing the surface as it's still hidden
85 QCOMPARE((void*)topLevelWindowModel->windowAt(0)->surface(), (void*)nullptr);
87 surface->requestState(Mir::RestoredState);
89 QCOMPARE(topLevelWindowModel->rowCount(), 1);
90 // Now that the surface is no longer hidden, TopLevelWindowModel should expose it.
91 QCOMPARE((void*)topLevelWindowModel->windowAt(0)->surface(), (void*)surface);
94void tst_TopLevelWindowModel::secondSurfaceIsHidden()
96 QCOMPARE(topLevelWindowModel->rowCount(), 0);
98 auto application = static_cast<Application*>(applicationManager->startApplication(QString("hello-world"), QStringList()));
100 QCOMPARE(topLevelWindowModel->rowCount(), 1);
101 QCOMPARE((void*)topLevelWindowModel->windowAt(0)->surface(), (void*)nullptr);
103 auto firstSurface = new MirSurface;
104 application->m_surfaceList.addSurface(firstSurface);
105 Q_EMIT surfaceManager->surfaceCreated(firstSurface);
107 QCOMPARE(topLevelWindowModel->rowCount(), 1);
108 QCOMPARE((void*)topLevelWindowModel->windowAt(0)->surface(), (void*)firstSurface);
110 auto secondSurface = new MirSurface;
111 secondSurface->m_state = Mir::HiddenState;
112 application->m_surfaceList.addSurface(secondSurface);
113 Q_EMIT surfaceManager->surfaceCreated(secondSurface);
115 // still only the first surface is exposed by TopLevelWindowModel
116 QCOMPARE(topLevelWindowModel->rowCount(), 1);
117 QCOMPARE((void*)topLevelWindowModel->windowAt(0)->surface(), (void*)firstSurface);
119 secondSurface->requestState(Mir::RestoredState);
121 // now the second surface finally shows up
122 QCOMPARE(topLevelWindowModel->rowCount(), 2);
123 QCOMPARE((void*)topLevelWindowModel->windowAt(0)->surface(), (void*)secondSurface);
124 QCOMPARE((void*)topLevelWindowModel->windowAt(1)->surface(), (void*)firstSurface);
126 secondSurface->requestState(Mir::HiddenState);
128 // and it's gone again
129 QCOMPARE(topLevelWindowModel->rowCount(), 1);
130 QCOMPARE((void*)topLevelWindowModel->windowAt(0)->surface(), (void*)firstSurface);
133// Ensure that rootFocus unfocuses and refocuses windows
134void tst_TopLevelWindowModel::rootFocus()
136 applicationManager->startApplication(QString("hello-world"), QStringList());
138 // We need to keep the window's surface null, unlike the other tests,
139 // because then the TLWM assumes that the window is unknown to MirAL and
140 // handles focus changes itself. If MirAL and QtMir are behaving properly,
141 // they mirror this behavior for windows with surfaces.
142 QCOMPARE(topLevelWindowModel->rowCount(), 1);
143 QCOMPARE((void*)topLevelWindowModel->windowAt(0)->surface(), (void*)nullptr);
144 auto dummyWindow = topLevelWindowModel->windowAt(0);
146 auto rootFocusChangedSpy = new QSignalSpy(topLevelWindowModel, &TopLevelWindowModel::rootFocusChanged);
148 // Unsetting rootFocus will remove focus from the dummy window
149 topLevelWindowModel->setRootFocus(false);
150 QVERIFY(!topLevelWindowModel->rootFocus());
151 QVERIFY(!dummyWindow->focused());
152 QCOMPARE(rootFocusChangedSpy->count(), 1);
154 // Setting rootFocus will add focus back to the dummy window
155 topLevelWindowModel->setRootFocus(true);
156 QVERIFY(topLevelWindowModel->rootFocus());
157 QCOMPARE((void*)topLevelWindowModel->focusedWindow(), (void*)dummyWindow);
158 QCOMPARE(rootFocusChangedSpy->count(), 2);
161// Ensure that rootFocus does not refocus a window if we focus another
162void tst_TopLevelWindowModel::rootFocusInhibit()
164 applicationManager->startApplication(QString("1"), QStringList());
166 auto dummyWindow1 = topLevelWindowModel->windowAt(0);
168 // Unsetting rootFocus will remove focus from the dummy window
169 topLevelWindowModel->setRootFocus(false);
170 QVERIFY(!topLevelWindowModel->rootFocus());
171 QVERIFY(!dummyWindow1->focused());
173 // Starting an Application will cause a pendingActivation, setting
174 // rootFocus but preventing the original window from becoming refocused
175 auto dummyWindow1FocusSpy = new QSignalSpy(dummyWindow1, &Window::focusedChanged);
177 // Saying that dummyWindow1 is different than dummyWindow2 will have to do
178 // since Applications don't know their Windows and we don't mock the other
179 // way around.
180 applicationManager->startApplication(QString("2"), QStringList());
181 auto dummyWindow2 = topLevelWindowModel->windowAt(0);
182 QVERIFY((void*)dummyWindow1 != (void*)dummyWindow2);
184 QVERIFY(topLevelWindowModel->rootFocus());
185 QVERIFY(!dummyWindow1->focused());
186 QVERIFY(dummyWindow2->focused());
187 QVERIFY(dummyWindow1FocusSpy->empty());
190QTEST_MAIN(tst_TopLevelWindowModel)
192#include "tst_TopLevelWindowModel.moc"