on 16fa310 help sign in
unity8/tests/mocks/Unity/Application/SurfaceManager.cpp
272 lines 7.5 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 const QUrl& screenshot)
66 MirSurface* surface = new MirSurface(name, type, state, screenshot);
67 registerSurface(surface);
68 return surface;
71void SurfaceManager::registerSurface(MirSurface *surface)
73 m_surfaces.prepend(surface);
75 surface->setMinimumWidth(m_newSurfaceMinimumWidth);
76 surface->setMaximumWidth(m_newSurfaceMaximumWidth);
77 surface->setMinimumHeight(m_newSurfaceMinimumHeight);
78 surface->setMaximumHeight(m_newSurfaceMaximumHeight);
79 surface->setWidthIncrement(m_newSurfaceWidthIncrement);
80 surface->setHeightIncrement(m_newSurfaceHeightIncrement);
82 connect(surface, &MirSurface::stateRequested, this, [=](Mir::State state) {
83 this->onStateRequested(surface, state);
84 });
86 connect(surface, &QObject::destroyed, this, [=]() {
87 this->onSurfaceDestroyed(surface);
88 });
91void SurfaceManager::notifySurfaceCreated(unityapi::MirSurfaceInterface *surface)
93 Q_EMIT surfaceCreated(surface);
96void SurfaceManager::setNewSurfaceMinimumWidth(int value)
98 if (m_newSurfaceMinimumWidth != value) {
99 m_newSurfaceMinimumWidth = value;
100 Q_EMIT newSurfaceMinimumWidthChanged(m_newSurfaceMinimumWidth);
101 }
104void SurfaceManager::setNewSurfaceMaximumWidth(int value)
106 if (m_newSurfaceMaximumWidth != value) {
107 m_newSurfaceMaximumWidth = value;
108 Q_EMIT newSurfaceMaximumWidthChanged(m_newSurfaceMaximumWidth);
109 }
112void SurfaceManager::setNewSurfaceMinimumHeight(int value)
114 if (m_newSurfaceMinimumHeight != value) {
115 m_newSurfaceMinimumHeight = value;
116 Q_EMIT newSurfaceMinimumHeightChanged(m_newSurfaceMinimumHeight);
117 }
120void SurfaceManager::setNewSurfaceMaximumHeight(int value)
122 if (m_newSurfaceMaximumHeight != value) {
123 m_newSurfaceMaximumHeight = value;
124 Q_EMIT newSurfaceMaximumHeightChanged(m_newSurfaceMaximumHeight);
125 }
128void SurfaceManager::setNewSurfaceWidthIncrement(int value)
130 if (m_newSurfaceWidthIncrement != value) {
131 m_newSurfaceWidthIncrement = value;
132 Q_EMIT newSurfaceWidthIncrementChanged(m_newSurfaceWidthIncrement);
133 }
136void SurfaceManager::setNewSurfaceHeightIncrement(int value)
138 if (m_newSurfaceHeightIncrement != value) {
139 m_newSurfaceHeightIncrement = value;
140 Q_EMIT newSurfaceHeightIncrementChanged(m_newSurfaceHeightIncrement);
141 }
144void SurfaceManager::raise(unityapi::MirSurfaceInterface *surface)
146 if (m_underModification)
147 return;
149 DEBUG_MSG("("<<surface<<") started");
150 Q_EMIT modificationsStarted();
151 m_underModification = true;
153 doRaise(surface);
155 m_underModification = false;
156 Q_EMIT modificationsEnded();
157 DEBUG_MSG("("<<surface<<") ended");
160void SurfaceManager::doRaise(unityapi::MirSurfaceInterface *apiSurface)
162 auto surface = static_cast<MirSurface*>(apiSurface);
163 int index = m_surfaces.indexOf(surface);
164 Q_ASSERT(index != -1);
165 m_surfaces.move(index, 0);
167 Q_EMIT surfacesRaised({surface});
170void SurfaceManager::activate(unityapi::MirSurfaceInterface *apiSurface)
172 auto surface = static_cast<MirSurface*>(apiSurface);
174 if (surface == m_focusedSurface) {
175 return;
176 }
178 Q_ASSERT(!m_underModification);
180 DEBUG_MSG("("<<surface<<") started");
181 Q_EMIT modificationsStarted();
182 m_underModification = true;
183 if (m_focusedSurface) {
184 m_focusedSurface->setFocused(false);
185 }
186 if (surface) {
187 if (surface->state() == Mir::HiddenState || surface->state() == Mir::MinimizedState) {
188 if (surface->previousState() != Mir::UnknownState) {
189 surface->setState(surface->previousState());
190 } else {
191 surface->setState(Mir::RestoredState);
192 }
193 }
194 surface->setFocused(true);
195 doRaise(surface);
196 }
197 m_focusedSurface = surface;
198 m_underModification = false;
199 Q_EMIT modificationsEnded();
200 DEBUG_MSG("("<<surface<<") ended");
203void SurfaceManager::onStateRequested(MirSurface *surface, Mir::State state)
205 Q_ASSERT(!m_underModification);
207 DEBUG_MSG("("<<surface<<","<<state<<") started");
208 Q_EMIT modificationsStarted();
209 m_underModification = true;
211 surface->setPreviousState(surface->state());
212 surface->setState(state);
214 if ((state == Mir::MinimizedState || state == Mir::HiddenState) && surface->focused()) {
215 Q_ASSERT(m_focusedSurface == surface);
216 surface->setFocused(false);
217 m_focusedSurface = nullptr;
218 focusFirstAvailableSurface();
219 }
221 m_underModification = false;
222 Q_EMIT modificationsEnded();
223 DEBUG_MSG("("<<surface<<","<<state<<") ended");
226void SurfaceManager::onSurfaceDestroyed(MirSurface *surface)
228 m_surfaces.removeAll(surface);
229 if (m_focusedSurface == surface) {
230 m_focusedSurface = nullptr;
232 Q_EMIT modificationsStarted();
233 m_underModification = true;
235 focusFirstAvailableSurface();
237 m_underModification = false;
238 Q_EMIT modificationsEnded();
239 }
242void SurfaceManager::focusFirstAvailableSurface()
244 MirSurface *chosenSurface = nullptr;
245 for (int i = 0; i < m_surfaces.count() && !chosenSurface; ++i) {
246 auto *surface = m_surfaces[i];
247 if (surface->state() != Mir::HiddenState && surface->state() != Mir::MinimizedState) {
248 chosenSurface = surface;
249 }
250 }
252 if (!chosenSurface) {
253 return;
254 }
256 if (m_focusedSurface) {
257 m_focusedSurface->setFocused(false);
258 }
259 if (chosenSurface) {
260 chosenSurface->setFocused(true);
261 }
262 m_focusedSurface = chosenSurface;
265void SurfaceManager::createInputMethodSurface()
267 if (!m_virtualKeyboard) {
268 m_virtualKeyboard = new VirtualKeyboard;
269 registerSurface(m_virtualKeyboard);
270 Q_EMIT surfaceCreated(m_virtualKeyboard);
271 }