@@ -1,5 +1,5 @@
2− * Copyright (C) 2016 Canonical, Ltd.
2+ * Copyright (C) 2016-2017 Canonical, Ltd.
4 * This program is free software: you can redistribute it and/or modify it under
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License version 3, as published by
5 * the terms of the GNU Lesser General Public License version 3, as published by
@@ -130,7 +130,7 @@ void TopLevelWindowModel::removeApplication(unityapi::ApplicationInfoInterface *
130 int i = 0;
130 int i = 0;
131 while (i < m_windowModel.count()) {
131 while (i < m_windowModel.count()) {
132 if (m_windowModel.at(i).application == application) {
132 if (m_windowModel.at(i).application == application) {
133− removeAt(i);
133+ deleteAt(i);
@@ -148,12 +148,13 @@ void TopLevelWindowModel::prependSurface(unityapi::MirSurfaceInterface *surface,
149 Q_ASSERT(surface != nullptr);
149 Q_ASSERT(surface != nullptr);
151+ connectSurface(surface);
151 bool filledPlaceholder = false;
153 bool filledPlaceholder = false;
152 for (int i = 0; i < m_windowModel.count() && !filledPlaceholder; ++i) {
154 for (int i = 0; i < m_windowModel.count() && !filledPlaceholder; ++i) {
153 ModelEntry &entry = m_windowModel[i];
155 ModelEntry &entry = m_windowModel[i];
154 if (entry.application == application && entry.window->surface() == nullptr) {
156 if (entry.application == application && entry.window->surface() == nullptr) {
155 entry.window->setSurface(surface);
157 entry.window->setSurface(surface);
156− connectSurface(surface);
157 INFO_MSG << " appId=" << application->appId() << " surface=" << surface
158 INFO_MSG << " appId=" << application->appId() << " surface=" << surface
158 << ", filling out placeholder. after: " << toString();
159 << ", filling out placeholder. after: " << toString();
159 filledPlaceholder = true;
160 filledPlaceholder = true;
@@ -167,6 +168,34 @@ void TopLevelWindowModel::prependSurface(unityapi::MirSurfaceInterface *surface,
169void TopLevelWindowModel::prependSurfaceHelper(unityapi::MirSurfaceInterface *surface, unityapi::ApplicationInfoInterface *application)
170void TopLevelWindowModel::prependSurfaceHelper(unityapi::MirSurfaceInterface *surface, unityapi::ApplicationInfoInterface *application)
173+ Window *window = createWindow(surface);
175+ connect(window, &Window::stateChanged, this, [=](Mir::State newState) {
176+ if (newState == Mir::HiddenState) {
177+ // Comply, removing it from our model. Just as if it didn't exist anymore.
178+ removeAt(indexForId(window->id()));
180+ if (indexForId(window->id()) == -1) {
181+ // was probably hidden before. put it back on the list
182+ auto *application = m_applicationManager->findApplicationWithSurface(window->surface());
183+ Q_ASSERT(application);
184+ prependWindow(window, application);
189+ prependWindow(window, application);
192+ activateEmptyWindow(window);
195+ INFO_MSG << " after " << toString();
198+void TopLevelWindowModel::prependWindow(Window *window, unityapi::ApplicationInfoInterface *application)
171 if (m_modelState == IdleState) {
200 if (m_modelState == IdleState) {
172 m_modelState = InsertingState;
201 m_modelState = InsertingState;
@@ -176,12 +205,7 @@ void TopLevelWindowModel::prependSurfaceHelper(unityapi::MirSurfaceInterface *su
176 // No point in signaling anything if we're resetting the whole model
205 // No point in signaling anything if we're resetting the whole model
179− Window *window = createWindow(surface);
181 m_windowModel.prepend(ModelEntry(window, application));
208 m_windowModel.prepend(ModelEntry(window, application));
183− connectSurface(surface);
186 if (m_modelState == InsertingState) {
210 if (m_modelState == InsertingState) {
187 endInsertRows();
211 endInsertRows();
@@ -189,12 +213,6 @@ void TopLevelWindowModel::prependSurfaceHelper(unityapi::MirSurfaceInterface *su
189 Q_EMIT listChanged();
213 Q_EMIT listChanged();
190 m_modelState = IdleState;
214 m_modelState = IdleState;
194− activateEmptyWindow(window);
197− INFO_MSG << " after " << toString();
200void TopLevelWindowModel::connectWindow(Window *window)
218void TopLevelWindowModel::connectWindow(Window *window)
@@ -243,6 +261,13 @@ void TopLevelWindowModel::connectWindow(Window *window)
243 connect(window, &Window::emptyWindowActivated, this, [this, window]() {
261 connect(window, &Window::emptyWindowActivated, this, [this, window]() {
244 activateEmptyWindow(window);
262 activateEmptyWindow(window);
265+ connect(window, &Window::liveChanged, this, [this, window](bool isAlive) {
266+ if (!isAlive && window->state() == Mir::HiddenState) {
267+ // Hidden windows are not in the model. So just delete it right away.
248void TopLevelWindowModel::activateEmptyWindow(Window *window)
273void TopLevelWindowModel::activateEmptyWindow(Window *window)
@@ -308,7 +333,7 @@ void TopLevelWindowModel::onSurfaceDestroyed(unityapi::MirSurfaceInterface *surf
310 if (m_windowModel[i].removeOnceSurfaceDestroyed) {
335 if (m_windowModel[i].removeOnceSurfaceDestroyed) {
311− removeAt(i);
336+ deleteAt(i);
313 auto window = m_windowModel[i].window;
338 auto window = m_windowModel[i].window;
314 window->setSurface(nullptr);
339 window->setSurface(nullptr);
@@ -346,7 +371,16 @@ void TopLevelWindowModel::onSurfaceCreated(unityapi::MirSurfaceInterface *surfac
347 auto *application = m_applicationManager->findApplicationWithSurface(surface);
372 auto *application = m_applicationManager->findApplicationWithSurface(surface);
348 if (application) {
373 if (application) {
374+ if (surface->state() == Mir::HiddenState) {
375+ // Ignore it until it's finally shown
376+ connect(surface, &unityapi::MirSurfaceInterface::stateChanged, this, [=](Mir::State newState) {
377+ Q_ASSERT(newState != Mir::HiddenState);
378+ disconnect(surface, &unityapi::MirSurfaceInterface::stateChanged, this, 0);
349− prependSurface(surface, application);
379+ prependSurface(surface, application);
382+ prependSurface(surface, application);
351 // Must be a prompt session. No need to do add it as a prompt surface is not top-level.
385 // Must be a prompt session. No need to do add it as a prompt surface is not top-level.
352 // It will show up in the ApplicationInfoInterface::promptSurfaceList of some application.
386 // It will show up in the ApplicationInfoInterface::promptSurfaceList of some application.
@@ -361,6 +395,17 @@ void TopLevelWindowModel::onSurfaceCreated(unityapi::MirSurfaceInterface *surfac
398+void TopLevelWindowModel::deleteAt(int index)
400+ auto window = m_windowModel[index].window;
404+ window->setSurface(nullptr);
364void TopLevelWindowModel::removeAt(int index)
409void TopLevelWindowModel::removeAt(int index)
366 if (m_modelState == IdleState) {
411 if (m_modelState == IdleState) {
@@ -373,8 +418,9 @@ void TopLevelWindowModel::removeAt(int index)
374 auto window = m_windowModel[index].window;
419 auto window = m_windowModel[index].window;
376− window->setSurface(nullptr);
421+ if (!window->surface()) {
377− window->setFocused(false);
422+ window->setFocused(false);
379 m_windowModel.removeAt(index);
425 m_windowModel.removeAt(index);
@@ -385,11 +431,9 @@ void TopLevelWindowModel::removeAt(int index)
385 m_modelState = IdleState;
431 m_modelState = IdleState;
388− disconnect(window, 0, this, 0);
389 if (m_focusedWindow == window) {
434 if (m_focusedWindow == window) {
390 setFocusedWindow(nullptr);
435 setFocusedWindow(nullptr);
394 INFO_MSG << " after " << toString();
438 INFO_MSG << " after " << toString();