~lukas-kde/unity8/betterSessionManagement

« back to all changes in this revision

Viewing changes to plugins/WindowManager/TopLevelWindowModel.cpp

  • Committer: Lukáš Tinkl
  • Date: 2017-03-24 11:57:27 UTC
  • mfrom: (2800.1.91 unity8)
  • Revision ID: lukas.tinkl@canonical.com-20170324115727-34c7tvv3qnxvxzdj
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2016 Canonical, Ltd.
 
2
 * Copyright (C) 2016-2017 Canonical, Ltd.
3
3
 *
4
4
 * This program is free software: you can redistribute it and/or modify it under
5
5
 * the terms of the GNU Lesser General Public License version 3, as published by
130
130
    int i = 0;
131
131
    while (i < m_windowModel.count()) {
132
132
        if (m_windowModel.at(i).application == application) {
133
 
            removeAt(i);
 
133
            deleteAt(i);
134
134
        } else {
135
135
            ++i;
136
136
        }
148
148
{
149
149
    Q_ASSERT(surface != nullptr);
150
150
 
 
151
    connectSurface(surface);
 
152
 
151
153
    bool filledPlaceholder = false;
152
154
    for (int i = 0; i < m_windowModel.count() && !filledPlaceholder; ++i) {
153
155
        ModelEntry &entry = m_windowModel[i];
154
156
        if (entry.application == application && entry.window->surface() == nullptr) {
155
157
            entry.window->setSurface(surface);
156
 
            connectSurface(surface);
157
158
            INFO_MSG << " appId=" << application->appId() << " surface=" << surface
158
159
                      << ", filling out placeholder. after: " << toString();
159
160
            filledPlaceholder = true;
168
169
 
169
170
void TopLevelWindowModel::prependSurfaceHelper(unityapi::MirSurfaceInterface *surface, unityapi::ApplicationInfoInterface *application)
170
171
{
 
172
 
 
173
    Window *window = createWindow(surface);
 
174
 
 
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()));
 
179
        } else {
 
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);
 
185
            }
 
186
        }
 
187
    });
 
188
 
 
189
    prependWindow(window, application);
 
190
 
 
191
    if (!surface) {
 
192
        activateEmptyWindow(window);
 
193
    }
 
194
 
 
195
    INFO_MSG << " after " << toString();
 
196
}
 
197
 
 
198
void TopLevelWindowModel::prependWindow(Window *window, unityapi::ApplicationInfoInterface *application)
 
199
{
171
200
    if (m_modelState == IdleState) {
172
201
        m_modelState = InsertingState;
173
202
        beginInsertRows(QModelIndex(), 0 /*first*/, 0 /*last*/);
176
205
        // No point in signaling anything if we're resetting the whole model
177
206
    }
178
207
 
179
 
    Window *window = createWindow(surface);
180
 
 
181
208
    m_windowModel.prepend(ModelEntry(window, application));
182
 
    if (surface) {
183
 
        connectSurface(surface);
184
 
    }
185
209
 
186
210
    if (m_modelState == InsertingState) {
187
211
        endInsertRows();
189
213
        Q_EMIT listChanged();
190
214
        m_modelState = IdleState;
191
215
    }
192
 
 
193
 
    if (!surface) {
194
 
        activateEmptyWindow(window);
195
 
    }
196
 
 
197
 
    INFO_MSG << " after " << toString();
198
216
}
199
217
 
200
218
void TopLevelWindowModel::connectWindow(Window *window)
243
261
    connect(window, &Window::emptyWindowActivated, this, [this, window]() {
244
262
        activateEmptyWindow(window);
245
263
    });
 
264
 
 
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.
 
268
            delete window;
 
269
        }
 
270
    });
246
271
}
247
272
 
248
273
void TopLevelWindowModel::activateEmptyWindow(Window *window)
308
333
    }
309
334
 
310
335
    if (m_windowModel[i].removeOnceSurfaceDestroyed) {
311
 
        removeAt(i);
 
336
        deleteAt(i);
312
337
    } else {
313
338
        auto window = m_windowModel[i].window;
314
339
        window->setSurface(nullptr);
341
366
        });
342
367
    } else {
343
368
        if (surface->type() == Mir::InputMethodType) {
 
369
            connectSurface(surface);
344
370
            setInputMethodWindow(createWindow(surface));
345
371
        } else {
346
372
            auto *application = m_applicationManager->findApplicationWithSurface(surface);
347
373
            if (application) {
348
 
                prependSurface(surface, 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);
 
379
                        prependSurface(surface, application);
 
380
                    });
 
381
                } else {
 
382
                    prependSurface(surface, application);
 
383
                }
349
384
            } else {
350
385
                // Must be a prompt session. No need to do add it as a prompt surface is not top-level.
351
386
                // It will show up in the ApplicationInfoInterface::promptSurfaceList of some application.
360
395
    }
361
396
}
362
397
 
 
398
void TopLevelWindowModel::deleteAt(int index)
 
399
{
 
400
    auto window = m_windowModel[index].window;
 
401
 
 
402
    removeAt(index);
 
403
 
 
404
    window->setSurface(nullptr);
 
405
 
 
406
    delete window;
 
407
}
 
408
 
363
409
void TopLevelWindowModel::removeAt(int index)
364
410
{
365
411
    if (m_modelState == IdleState) {
372
418
 
373
419
    auto window = m_windowModel[index].window;
374
420
 
375
 
    window->setSurface(nullptr);
376
 
    window->setFocused(false);
 
421
    if (!window->surface()) {
 
422
        window->setFocused(false);
 
423
    }
377
424
 
378
425
    m_windowModel.removeAt(index);
379
426
 
384
431
        m_modelState = IdleState;
385
432
    }
386
433
 
387
 
    disconnect(window, 0, this, 0);
388
434
    if (m_focusedWindow == window) {
389
435
        setFocusedWindow(nullptr);
390
436
    }
391
 
    delete window;
392
437
 
393
438
    INFO_MSG << " after " << toString();
394
439
}