on bionic help sign in
unity8/tests/mocks/Unity/Application/SurfaceManager.cpp
281 lines 8.0 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 return m_instance;
41SurfaceManager::SurfaceManager(QObject *)
43 DEBUG_MSG("");
45 Q_ASSERT(m_instance == nullptr);
46 m_instance = this;
49SurfaceManager::~SurfaceManager()
51 DEBUG_MSG("");
53 if (m_virtualKeyboard) {
54 m_virtualKeyboard->setLive(false);
55 }
57 Q_ASSERT(m_instance == this);
58 m_instance = nullptr;
61MirSurface *SurfaceManager::createSurface(const QString& name,
62 Mir::Type type,
63 Mir::State state,
64 MirSurface *parentSurface,
65 const QUrl &screenshot,
66 const QUrl &qmlFilePath)
68 MirSurface* surface = new MirSurface(name, type, state, parentSurface, screenshot, qmlFilePath);
69 registerSurface(surface);
70 if (parentSurface) {
71 static_cast<MirSurfaceListModel*>(parentSurface->childSurfaceList())->addSurface(surface);
72 }
73 return surface;
76void SurfaceManager::registerSurface(MirSurface *surface)
78 m_surfaces.prepend(surface);
80 if (!surface->parentSurface()) {
81 surface->setMinimumWidth(m_newSurfaceMinimumWidth);
82 surface->setMaximumWidth(m_newSurfaceMaximumWidth);
83 surface->setMinimumHeight(m_newSurfaceMinimumHeight);
84 surface->setMaximumHeight(m_newSurfaceMaximumHeight);
85 surface->setWidthIncrement(m_newSurfaceWidthIncrement);
86 surface->setHeightIncrement(m_newSurfaceHeightIncrement);
87 }
89 connect(surface, &MirSurface::stateRequested, this, [=](Mir::State state) {
90 this->onStateRequested(surface, state);
91 });
93 const QString persistentId = surface->persistentId();
94 connect(surface, &QObject::destroyed, this, [=]() {
95 this->onSurfaceDestroyed(surface, persistentId);
96 });
100void SurfaceManager::notifySurfaceCreated(unityapi::MirSurfaceInterface *surface)
102 Q_EMIT surfaceCreated(surface);
105void SurfaceManager::setNewSurfaceMinimumWidth(int value)
107 if (m_newSurfaceMinimumWidth != value) {
108 m_newSurfaceMinimumWidth = value;
109 Q_EMIT newSurfaceMinimumWidthChanged(m_newSurfaceMinimumWidth);
110 }
113void SurfaceManager::setNewSurfaceMaximumWidth(int value)
115 if (m_newSurfaceMaximumWidth != value) {
116 m_newSurfaceMaximumWidth = value;
117 Q_EMIT newSurfaceMaximumWidthChanged(m_newSurfaceMaximumWidth);
118 }
121void SurfaceManager::setNewSurfaceMinimumHeight(int value)
123 if (m_newSurfaceMinimumHeight != value) {
124 m_newSurfaceMinimumHeight = value;
125 Q_EMIT newSurfaceMinimumHeightChanged(m_newSurfaceMinimumHeight);
126 }
129void SurfaceManager::setNewSurfaceMaximumHeight(int value)
131 if (m_newSurfaceMaximumHeight != value) {
132 m_newSurfaceMaximumHeight = value;
133 Q_EMIT newSurfaceMaximumHeightChanged(m_newSurfaceMaximumHeight);
134 }
137void SurfaceManager::setNewSurfaceWidthIncrement(int value)
139 if (m_newSurfaceWidthIncrement != value) {
140 m_newSurfaceWidthIncrement = value;
141 Q_EMIT newSurfaceWidthIncrementChanged(m_newSurfaceWidthIncrement);
142 }
145void SurfaceManager::setNewSurfaceHeightIncrement(int value)
147 if (m_newSurfaceHeightIncrement != value) {
148 m_newSurfaceHeightIncrement = value;
149 Q_EMIT newSurfaceHeightIncrementChanged(m_newSurfaceHeightIncrement);
150 }
153void SurfaceManager::raise(unityapi::MirSurfaceInterface *surface)
155 if (m_underModification)
156 return;
158 DEBUG_MSG("("<<surface<<") started");
159 Q_EMIT modificationsStarted();
160 m_underModification = true;
162 doRaise(surface);
164 m_underModification = false;
165 Q_EMIT modificationsEnded();
166 DEBUG_MSG("("<<surface<<") ended");
169void SurfaceManager::doRaise(unityapi::MirSurfaceInterface *apiSurface)
171 auto surface = static_cast<MirSurface*>(apiSurface);
172 int index = m_surfaces.indexOf(surface);
173 Q_ASSERT(index != -1);
174 m_surfaces.move(index, 0);
176 Q_EMIT surfacesRaised({surface});
179void SurfaceManager::activate(unityapi::MirSurfaceInterface *apiSurface)
181 auto surface = static_cast<MirSurface*>(apiSurface);
183 if (surface == m_focusedSurface) {
184 return;
185 }
187 Q_ASSERT(!m_underModification);
189 DEBUG_MSG("("<<surface<<") started");
190 Q_EMIT modificationsStarted();
191 m_underModification = true;
192 if (m_focusedSurface) {
193 m_focusedSurface->setFocused(false);
194 }
195 if (surface) {
196 if (surface->state() == Mir::HiddenState || surface->state() == Mir::MinimizedState) {
197 if (surface->previousState() != Mir::UnknownState) {
198 surface->setState(surface->previousState());
199 } else {
200 surface->setState(Mir::RestoredState);
201 }
202 }
203 surface->setFocused(true);
204 doRaise(surface);
205 }
206 m_focusedSurface = surface;
207 m_underModification = false;
208 Q_EMIT modificationsEnded();
209 DEBUG_MSG("("<<surface<<") ended");
212void SurfaceManager::onStateRequested(MirSurface *surface, Mir::State state)
214 DEBUG_MSG("("<<surface<<","<<state<<") started");
215 Q_EMIT modificationsStarted();
216 m_underModification = true;
218 surface->setPreviousState(surface->state());
219 surface->setState(state);
221 if ((state == Mir::MinimizedState || state == Mir::HiddenState) && surface->focused()) {
222 Q_ASSERT(m_focusedSurface == surface);
223 surface->setFocused(false);
224 m_focusedSurface = nullptr;
225 focusFirstAvailableSurface();
226 }
228 m_underModification = false;
229 Q_EMIT modificationsEnded();
230 DEBUG_MSG("("<<surface<<","<<state<<") ended");
233void SurfaceManager::onSurfaceDestroyed(MirSurface *surface, const QString& persistentId)
235 m_surfaces.removeAll(surface);
236 if (m_focusedSurface == surface) {
237 m_focusedSurface = nullptr;
239 Q_EMIT modificationsStarted();
240 m_underModification = true;
242 focusFirstAvailableSurface();
244 m_underModification = false;
245 Q_EMIT modificationsEnded();
246 }
247 Q_EMIT surfaceDestroyed(persistentId);
250void SurfaceManager::focusFirstAvailableSurface()
252 MirSurface *chosenSurface = nullptr;
253 for (int i = 0; i < m_surfaces.count() && !chosenSurface; ++i) {
254 auto *surface = m_surfaces[i];
255 if (surface->state() != Mir::HiddenState && surface->state() != Mir::MinimizedState) {
256 chosenSurface = surface;
257 }
258 }
260 if (!chosenSurface) {
261 return;
262 }
264 if (m_focusedSurface) {
265 m_focusedSurface->setFocused(false);
266 }
268 chosenSurface->setFocused(true);
269 doRaise(chosenSurface);
271 m_focusedSurface = chosenSurface;
274void SurfaceManager::createInputMethodSurface()
276 if (!m_virtualKeyboard) {
277 m_virtualKeyboard = new VirtualKeyboard;
278 registerSurface(m_virtualKeyboard);
279 Q_EMIT surfaceCreated(m_virtualKeyboard);
280 }