on 3987688 help sign in
unity8/tests/mocks/Unity/Application/SurfaceManager.cpp
284 lines 8.1 kB history raw
1/*
2 * Copyright (C) 2014-2016 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#include "SurfaceManager.h"
19#include "ApplicationInfo.h"
20#include "VirtualKeyboard.h"
22#include <paths.h>
24#define SURFACEMANAGER_DEBUG 0
26#if SURFACEMANAGER_DEBUG
27#define DEBUG_MSG(params) qDebug().nospace() << "SurfaceManager[" << (void*)this << "]::" << __func__ << params
28#else
29#define DEBUG_MSG(params) ((void)0)
30#endif
32namespace unityapi = unity::shell::application;
34SurfaceManager *SurfaceManager::m_instance = nullptr;
36SurfaceManager *SurfaceManager::instance()
38 if (m_instance == nullptr) {
39 auto inst = new SurfaceManager();
40 }
41 return m_instance;
44SurfaceManager::SurfaceManager(QObject *)
46 DEBUG_MSG("");
48 Q_ASSERT(m_instance == nullptr);
49 m_instance = this;
52SurfaceManager::~SurfaceManager()
54 DEBUG_MSG("");
56 if (m_virtualKeyboard) {
57 m_virtualKeyboard->setLive(false);
58 }
60 Q_ASSERT(m_instance == this);
61 m_instance = nullptr;
64MirSurface *SurfaceManager::createSurface(const QString& name,
65 Mir::Type type,
66 Mir::State state,
67 MirSurface *parentSurface,
68 const QUrl &screenshot,
69 const QUrl &qmlFilePath)
71 MirSurface* surface = new MirSurface(name, type, state, parentSurface, screenshot, qmlFilePath);
72 registerSurface(surface);
73 if (parentSurface) {
74 static_cast<MirSurfaceListModel*>(parentSurface->childSurfaceList())->addSurface(surface);
75 }
76 return surface;
79void SurfaceManager::registerSurface(MirSurface *surface)
81 m_surfaces.prepend(surface);
83 if (!surface->parentSurface()) {
84 surface->setMinimumWidth(m_newSurfaceMinimumWidth);
85 surface->setMaximumWidth(m_newSurfaceMaximumWidth);
86 surface->setMinimumHeight(m_newSurfaceMinimumHeight);
87 surface->setMaximumHeight(m_newSurfaceMaximumHeight);
88 surface->setWidthIncrement(m_newSurfaceWidthIncrement);
89 surface->setHeightIncrement(m_newSurfaceHeightIncrement);
90 }
92 connect(surface, &MirSurface::stateRequested, this, [=](Mir::State state) {
93 this->onStateRequested(surface, state);
94 });
96 const QString persistentId = surface->persistentId();
97 connect(surface, &QObject::destroyed, this, [=]() {
98 this->onSurfaceDestroyed(surface, persistentId);
99 });
103void SurfaceManager::notifySurfaceCreated(unityapi::MirSurfaceInterface *surface)
105 Q_EMIT surfaceCreated(surface);
108void SurfaceManager::setNewSurfaceMinimumWidth(int value)
110 if (m_newSurfaceMinimumWidth != value) {
111 m_newSurfaceMinimumWidth = value;
112 Q_EMIT newSurfaceMinimumWidthChanged(m_newSurfaceMinimumWidth);
113 }
116void SurfaceManager::setNewSurfaceMaximumWidth(int value)
118 if (m_newSurfaceMaximumWidth != value) {
119 m_newSurfaceMaximumWidth = value;
120 Q_EMIT newSurfaceMaximumWidthChanged(m_newSurfaceMaximumWidth);
121 }
124void SurfaceManager::setNewSurfaceMinimumHeight(int value)
126 if (m_newSurfaceMinimumHeight != value) {
127 m_newSurfaceMinimumHeight = value;
128 Q_EMIT newSurfaceMinimumHeightChanged(m_newSurfaceMinimumHeight);
129 }
132void SurfaceManager::setNewSurfaceMaximumHeight(int value)
134 if (m_newSurfaceMaximumHeight != value) {
135 m_newSurfaceMaximumHeight = value;
136 Q_EMIT newSurfaceMaximumHeightChanged(m_newSurfaceMaximumHeight);
137 }
140void SurfaceManager::setNewSurfaceWidthIncrement(int value)
142 if (m_newSurfaceWidthIncrement != value) {
143 m_newSurfaceWidthIncrement = value;
144 Q_EMIT newSurfaceWidthIncrementChanged(m_newSurfaceWidthIncrement);
145 }
148void SurfaceManager::setNewSurfaceHeightIncrement(int value)
150 if (m_newSurfaceHeightIncrement != value) {
151 m_newSurfaceHeightIncrement = value;
152 Q_EMIT newSurfaceHeightIncrementChanged(m_newSurfaceHeightIncrement);
153 }
156void SurfaceManager::raise(unityapi::MirSurfaceInterface *surface)
158 if (m_underModification)
159 return;
161 DEBUG_MSG("("<<surface<<") started");
162 Q_EMIT modificationsStarted();
163 m_underModification = true;
165 doRaise(surface);
167 m_underModification = false;
168 Q_EMIT modificationsEnded();
169 DEBUG_MSG("("<<surface<<") ended");
172void SurfaceManager::doRaise(unityapi::MirSurfaceInterface *apiSurface)
174 auto surface = static_cast<MirSurface*>(apiSurface);
175 int index = m_surfaces.indexOf(surface);
176 Q_ASSERT(index != -1);
177 m_surfaces.move(index, 0);
179 Q_EMIT surfacesRaised({surface});
182void SurfaceManager::activate(unityapi::MirSurfaceInterface *apiSurface)
184 auto surface = static_cast<MirSurface*>(apiSurface);
186 if (surface == m_focusedSurface) {
187 return;
188 }
190 Q_ASSERT(!m_underModification);
192 DEBUG_MSG("("<<surface<<") started");
193 Q_EMIT modificationsStarted();
194 m_underModification = true;
195 if (m_focusedSurface) {
196 m_focusedSurface->setFocused(false);
197 }
198 if (surface) {
199 if (surface->state() == Mir::HiddenState || surface->state() == Mir::MinimizedState) {
200 if (surface->previousState() != Mir::UnknownState) {
201 surface->setState(surface->previousState());
202 } else {
203 surface->setState(Mir::RestoredState);
204 }
205 }
206 surface->setFocused(true);
207 doRaise(surface);
208 }
209 m_focusedSurface = surface;
210 m_underModification = false;
211 Q_EMIT modificationsEnded();
212 DEBUG_MSG("("<<surface<<") ended");
215void SurfaceManager::onStateRequested(MirSurface *surface, Mir::State state)
217 DEBUG_MSG("("<<surface<<","<<state<<") started");
218 Q_EMIT modificationsStarted();
219 m_underModification = true;
221 surface->setPreviousState(surface->state());
222 surface->setState(state);
224 if ((state == Mir::MinimizedState || state == Mir::HiddenState) && surface->focused()) {
225 Q_ASSERT(m_focusedSurface == surface);
226 surface->setFocused(false);
227 m_focusedSurface = nullptr;
228 focusFirstAvailableSurface();
229 }
231 m_underModification = false;
232 Q_EMIT modificationsEnded();
233 DEBUG_MSG("("<<surface<<","<<state<<") ended");
236void SurfaceManager::onSurfaceDestroyed(MirSurface *surface, const QString& persistentId)
238 m_surfaces.removeAll(surface);
239 if (m_focusedSurface == surface) {
240 m_focusedSurface = nullptr;
242 Q_EMIT modificationsStarted();
243 m_underModification = true;
245 focusFirstAvailableSurface();
247 m_underModification = false;
248 Q_EMIT modificationsEnded();
249 }
250 Q_EMIT surfaceDestroyed(persistentId);
253void SurfaceManager::focusFirstAvailableSurface()
255 MirSurface *chosenSurface = nullptr;
256 for (int i = 0; i < m_surfaces.count() && !chosenSurface; ++i) {
257 auto *surface = m_surfaces[i];
258 if (surface->state() != Mir::HiddenState && surface->state() != Mir::MinimizedState) {
259 chosenSurface = surface;
260 }
261 }
263 if (!chosenSurface) {
264 return;
265 }
267 if (m_focusedSurface) {
268 m_focusedSurface->setFocused(false);
269 }
271 chosenSurface->setFocused(true);
272 doRaise(chosenSurface);
274 m_focusedSurface = chosenSurface;
277void SurfaceManager::createInputMethodSurface()
279 if (!m_virtualKeyboard) {
280 m_virtualKeyboard = new VirtualKeyboard;
281 registerSurface(m_virtualKeyboard);
282 Q_EMIT surfaceCreated(m_virtualKeyboard);
283 }