Merge lp:~dandrader/qtmir/miral-surfacemanager into lp:~unity-team/qtmir/miral-qt-integration

Proposed by Daniel d'Andrada
Status: Merged
Approved by: Gerry Boland
Approved revision: 579
Merged at revision: 581
Proposed branch: lp:~dandrader/qtmir/miral-surfacemanager
Merge into: lp:~unity-team/qtmir/miral-qt-integration
Diff against target: 1582 lines (+261/-1156)
13 files modified
src/modules/Unity/Application/CMakeLists.txt (+2/-4)
src/modules/Unity/Application/application.h (+1/-2)
src/modules/Unity/Application/application_manager.cpp (+11/-0)
src/modules/Unity/Application/application_manager.h (+6/-5)
src/modules/Unity/Application/applicationmanagerinterface.h (+0/-35)
src/modules/Unity/Application/mirsurfaceinterface.h (+0/-1)
src/modules/Unity/Application/plugin.cpp (+3/-4)
src/modules/Unity/Application/surfacemanager.cpp (+166/-0)
src/modules/Unity/Application/surfacemanager.h (+72/-0)
src/modules/Unity/Application/toplevelwindowmodel.cpp (+0/-691)
src/modules/Unity/Application/toplevelwindowmodel.h (+0/-161)
src/modules/Unity/Application/window.cpp (+0/-186)
src/modules/Unity/Application/window.h (+0/-67)
To merge this branch: bzr merge lp:~dandrader/qtmir/miral-surfacemanager
Reviewer Review Type Date Requested Status
Gerry Boland (community) Approve
Review via email: mp+310909@code.launchpad.net

Commit message

Move TopLevelWindowModel out of qtmir. Export a SurfaceManager instead

Description of the change

Dramatically improves the interface between qtmir and unity8

Needs:
https://code.launchpad.net/~dandrader/unity-api/miral-surfacemanager/+merge/310910

To post a comment you must log in.
Revision history for this message
Gerry Boland (gerboland) wrote :

Smaller API is cleaner.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/modules/Unity/Application/CMakeLists.txt'
2--- src/modules/Unity/Application/CMakeLists.txt 2016-11-03 20:17:46 +0000
3+++ src/modules/Unity/Application/CMakeLists.txt 2016-11-15 17:55:38 +0000
4@@ -45,14 +45,13 @@
5 session.cpp
6 sessionmanager.cpp
7 sharedwakelock.cpp
8+ surfacemanager.cpp
9 upstart/applicationinfo.cpp
10 upstart/taskcontroller.cpp
11 timer.cpp
12 timesource.cpp
13- toplevelwindowmodel.cpp
14 tracepoints.c
15 settings.cpp
16- window.cpp
17 windowmodel.cpp
18 # We need to run moc on these headers
19 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
20@@ -61,8 +60,7 @@
21 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceInterface.h
22 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceItemInterface.h
23 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceListInterface.h
24- ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/TopLevelWindowModelInterface.h
25- ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/WindowInterface.h
26+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/SurfaceManagerInterface.h
27 # Feed the automoc monster
28 session_interface.h
29 applicationinfo.h
30
31=== modified file 'src/modules/Unity/Application/application.h'
32--- src/modules/Unity/Application/application.h 2016-11-03 20:17:46 +0000
33+++ src/modules/Unity/Application/application.h 2016-11-15 17:55:38 +0000
34@@ -103,6 +103,7 @@
35 unity::shell::application::MirSurfaceListInterface* surfaceList() const override;
36 unity::shell::application::MirSurfaceListInterface* promptSurfaceList() const override;
37 int surfaceCount() const override { return surfaceList()->count(); }
38+ void close() override;
39
40 ProcessState processState() const { return m_processState; }
41 void setProcessState(ProcessState value);
42@@ -119,8 +120,6 @@
43
44 pid_t pid() const;
45
46- void close();
47-
48 // internal as in "not exposed in unity-api", so qtmir-internal.
49 InternalState internalState() const { return m_state; }
50
51
52=== modified file 'src/modules/Unity/Application/application_manager.cpp'
53--- src/modules/Unity/Application/application_manager.cpp 2016-11-03 20:17:46 +0000
54+++ src/modules/Unity/Application/application_manager.cpp 2016-11-15 17:55:38 +0000
55@@ -577,6 +577,17 @@
56 authorized = true;
57 }
58
59+
60+unityapi::ApplicationInfoInterface *ApplicationManager::findApplicationWithSurface(unityapi::MirSurfaceInterface* surface)
61+{
62+ if (!surface)
63+ return nullptr;
64+
65+ auto qtmirSurface = static_cast<qtmir::MirSurfaceInterface*>(surface);
66+
67+ return findApplicationWithPid(miral::pid_of(qtmirSurface->session()->session()));
68+}
69+
70 Application* ApplicationManager::findApplicationWithSession(const std::shared_ptr<ms::Session> &session)
71 {
72 if (!session)
73
74=== modified file 'src/modules/Unity/Application/application_manager.h'
75--- src/modules/Unity/Application/application_manager.h 2016-11-03 20:17:46 +0000
76+++ src/modules/Unity/Application/application_manager.h 2016-11-15 17:55:38 +0000
77@@ -26,9 +26,11 @@
78
79 // local
80 #include "application.h"
81-#include "applicationmanagerinterface.h"
82 #include "taskcontroller.h"
83
84+// Unity API
85+#include <unity/shell/application/ApplicationManagerInterface.h>
86+
87 namespace mir {
88 namespace scene {
89 class Session;
90@@ -53,7 +55,7 @@
91 class SharedWakelock;
92 class SettingsInterface;
93
94-class ApplicationManager : public ApplicationManagerInterface
95+class ApplicationManager : public unity::shell::application::ApplicationManagerInterface
96 {
97 Q_OBJECT
98
99@@ -81,13 +83,11 @@
100 QString focusedApplicationId() const override;
101 Q_INVOKABLE qtmir::Application* get(int index) const override;
102 Q_INVOKABLE qtmir::Application* findApplication(const QString &appId) const override;
103+ unity::shell::application::ApplicationInfoInterface *findApplicationWithSurface(unity::shell::application::MirSurfaceInterface* surface) override;
104 Q_INVOKABLE bool requestFocusApplication(const QString &appId) override;
105 Q_INVOKABLE qtmir::Application* startApplication(const QString &appId, const QStringList &arguments = QStringList()) override;
106 Q_INVOKABLE bool stopApplication(const QString &appId) override;
107
108- // qtmir::ApplicationManagerInterface
109- Application* findApplicationWithSession(const std::shared_ptr<mir::scene::Session> &session) override;
110-
111 // QAbstractListModel
112 int rowCount(const QModelIndex & parent = QModelIndex()) const override;
113 QVariant data(const QModelIndex & index, int role) const override;
114@@ -119,6 +119,7 @@
115 void onApplicationClosing(Application *application);
116
117 private:
118+ Application* findApplicationWithSession(const std::shared_ptr<mir::scene::Session> &session);
119 void setFocused(Application *application);
120 void add(Application *application);
121 void remove(Application* application);
122
123=== removed file 'src/modules/Unity/Application/applicationmanagerinterface.h'
124--- src/modules/Unity/Application/applicationmanagerinterface.h 2016-11-03 20:17:46 +0000
125+++ src/modules/Unity/Application/applicationmanagerinterface.h 1970-01-01 00:00:00 +0000
126@@ -1,35 +0,0 @@
127-/*
128- * Copyright (C) 2016 Canonical, Ltd.
129- *
130- * This program is free software: you can redistribute it and/or modify it under
131- * the terms of the GNU Lesser General Public License version 3, as published by
132- * the Free Software Foundation.
133- *
134- * This program is distributed in the hope that it will be useful, but WITHOUT
135- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
136- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
137- * Lesser General Public License for more details.
138- *
139- * You should have received a copy of the GNU Lesser General Public License
140- * along with this program. If not, see <http://www.gnu.org/licenses/>.
141- */
142-
143-#ifndef QTMIR_APPLICATION_MANAGER_INTERFACE_H
144-#define QTMIR_APPLICATION_MANAGER_INTERFACE_H
145-
146-// Unity API
147-#include <unity/shell/application/ApplicationManagerInterface.h>
148-
149-namespace qtmir {
150-
151-class ApplicationManagerInterface : public unity::shell::application::ApplicationManagerInterface
152-{
153-public:
154- ApplicationManagerInterface(QObject *parent) : unity::shell::application::ApplicationManagerInterface(parent) {}
155-
156- virtual Application* findApplicationWithSession(const std::shared_ptr<mir::scene::Session> &session) = 0;
157-};
158-
159-} // namespace qtmir
160-
161-#endif // QTMIR_APPLICATION_MANAGER_INTERFACE_H
162
163=== modified file 'src/modules/Unity/Application/mirsurfaceinterface.h'
164--- src/modules/Unity/Application/mirsurfaceinterface.h 2016-11-03 20:17:46 +0000
165+++ src/modules/Unity/Application/mirsurfaceinterface.h 2016-11-15 17:55:38 +0000
166@@ -116,7 +116,6 @@
167 void ready();
168 void cursorChanged(const QCursor &cursor);
169 void raiseRequested();
170- void closeRequested();
171 void framesPosted();
172 void isBeingDisplayedChanged();
173 void frameDropped();
174
175=== modified file 'src/modules/Unity/Application/plugin.cpp'
176--- src/modules/Unity/Application/plugin.cpp 2016-11-03 20:17:46 +0000
177+++ src/modules/Unity/Application/plugin.cpp 2016-11-15 17:55:38 +0000
178@@ -23,9 +23,8 @@
179 #include "mirsurfaceinterface.h"
180 #include "mirsurfaceitem.h"
181 #include "mirsurfacelistmodel.h"
182-#include "toplevelwindowmodel.h"
183-#include "window.h"
184 #include "windowmodel.h"
185+#include "surfacemanager.h"
186
187 // platforms/mirserver
188 #include <mirsingleton.h>
189@@ -65,8 +64,8 @@
190 qRegisterMetaType<qtmir::Application*>("Application*");
191 qRegisterMetaType<unity::shell::application::MirSurfaceInterface*>("MirSurfaceInterface*");
192 qRegisterMetaType<unity::shell::application::MirSurfaceListInterface*>("unity::shell::application::MirSurfaceListInterface*");
193+ qRegisterMetaType<unity::shell::application::SurfaceManagerInterface*>("unity::shell::application::SurfaceManagerInterface*");
194 qRegisterMetaType<MirSurfaceAttrib>("MirSurfaceAttrib");
195- qRegisterMetaType<unity::shell::application::WindowInterface*>("unity::shell::application::WindowInterface*");
196
197 qmlRegisterUncreatableType<unity::shell::application::ApplicationManagerInterface>(
198 uri, 0, 1, "ApplicationManagerInterface", "Abstract interface. Cannot be created in QML");
199@@ -80,9 +79,9 @@
200 uri, 0, 1, "MirSurface", "MirSurface can't be instantiated from QML");
201 qmlRegisterType<qtmir::MirSurfaceItem>(uri, 0, 1, "MirSurfaceItem");
202 qmlRegisterSingletonType<qtmir::Mir>(uri, 0, 1, "Mir", mirSingleton);
203+ qmlRegisterType<qtmir::SurfaceManager>(uri, 0, 1, "SurfaceManager");
204
205 qmlRegisterType<qtmir::WindowModel>(uri, 0, 1, "WindowModel");
206- qmlRegisterType<qtmir::TopLevelWindowModel>(uri, 0, 1, "TopLevelWindowModel");
207 }
208
209 virtual void initializeEngine(QQmlEngine *engine, const char *uri)
210
211=== added file 'src/modules/Unity/Application/surfacemanager.cpp'
212--- src/modules/Unity/Application/surfacemanager.cpp 1970-01-01 00:00:00 +0000
213+++ src/modules/Unity/Application/surfacemanager.cpp 2016-11-15 17:55:38 +0000
214@@ -0,0 +1,166 @@
215+/*
216+ * Copyright (C) 2016 Canonical, Ltd.
217+ *
218+ * This program is free software: you can redistribute it and/or modify it under
219+ * the terms of the GNU Lesser General Public License version 3, as published by
220+ * the Free Software Foundation.
221+ *
222+ * This program is distributed in the hope that it will be useful, but WITHOUT
223+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
224+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
225+ * Lesser General Public License for more details.
226+ *
227+ * You should have received a copy of the GNU Lesser General Public License
228+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
229+ */
230+
231+#include "surfacemanager.h"
232+
233+#include "mirsurface.h"
234+#include "sessionmanager.h"
235+
236+// mirserver
237+#include "nativeinterface.h"
238+
239+// Qt
240+#include <QGuiApplication>
241+
242+Q_LOGGING_CATEGORY(QTMIR_SURFACEMANAGER, "qtmir.surfacemanager", QtDebugMsg)
243+
244+#define DEBUG_MSG qCDebug(QTMIR_SURFACEMANAGER).nospace().noquote() << __func__
245+
246+using namespace qtmir;
247+namespace unityapi = unity::shell::application;
248+
249+SurfaceManager::SurfaceManager(QObject *)
250+{
251+ DEBUG_MSG << "()";
252+
253+ auto nativeInterface = dynamic_cast<NativeInterface*>(QGuiApplication::platformNativeInterface());
254+
255+ if (!nativeInterface) {
256+ qFatal("ERROR: Unity.Application QML plugin requires use of the 'mirserver' QPA plugin");
257+ }
258+
259+ m_windowController = static_cast<WindowControllerInterface*>(nativeInterface->nativeResourceForIntegration("WindowController"));
260+
261+ auto windowModel = static_cast<WindowModelNotifier*>(nativeInterface->nativeResourceForIntegration("WindowModelNotifier"));
262+ connectToWindowModelNotifier(windowModel);
263+
264+ m_sessionManager = SessionManager::singleton();
265+}
266+
267+void SurfaceManager::connectToWindowModelNotifier(WindowModelNotifier *notifier)
268+{
269+ connect(notifier, &WindowModelNotifier::windowAdded, this, &SurfaceManager::onWindowAdded, Qt::QueuedConnection);
270+ connect(notifier, &WindowModelNotifier::windowRemoved, this, &SurfaceManager::onWindowRemoved, Qt::QueuedConnection);
271+ connect(notifier, &WindowModelNotifier::windowReady, this, &SurfaceManager::onWindowReady, Qt::QueuedConnection);
272+ connect(notifier, &WindowModelNotifier::windowMoved, this, &SurfaceManager::onWindowMoved, Qt::QueuedConnection);
273+ connect(notifier, &WindowModelNotifier::windowStateChanged, this, &SurfaceManager::onWindowStateChanged, Qt::QueuedConnection);
274+ connect(notifier, &WindowModelNotifier::windowFocusChanged, this, &SurfaceManager::onWindowFocusChanged, Qt::QueuedConnection);
275+ connect(notifier, &WindowModelNotifier::windowsRaised, this, &SurfaceManager::onWindowsRaised, Qt::QueuedConnection);
276+ connect(notifier, &WindowModelNotifier::modificationsStarted, this, &SurfaceManager::modificationsStarted, Qt::QueuedConnection);
277+ connect(notifier, &WindowModelNotifier::modificationsEnded, this, &SurfaceManager::modificationsEnded, Qt::QueuedConnection);
278+}
279+
280+void SurfaceManager::rememberMirSurface(MirSurface *surface)
281+{
282+ m_allSurfaces.append(surface);
283+}
284+
285+void SurfaceManager::forgetMirSurface(const miral::Window &window)
286+{
287+ for (int i = 0; i < m_allSurfaces.count(); ++i) {
288+ if (m_allSurfaces[i]->window() == window) {
289+ m_allSurfaces.removeAt(i);
290+ return;
291+ }
292+ }
293+}
294+void SurfaceManager::onWindowAdded(const NewWindow &window)
295+{
296+ auto mirSession = window.windowInfo.window().application();
297+ SessionInterface* session = m_sessionManager->findSession(mirSession.get());
298+
299+ auto surface = new MirSurface(window, m_windowController, session);
300+ rememberMirSurface(surface);
301+
302+ if (session)
303+ session->registerSurface(surface);
304+
305+ Q_EMIT surfaceCreated(surface);
306+}
307+
308+void SurfaceManager::onWindowRemoved(const miral::WindowInfo &windowInfo)
309+{
310+ MirSurface *surface = find(windowInfo);
311+ forgetMirSurface(windowInfo.window());
312+ surface->setLive(false);
313+}
314+
315+MirSurface *SurfaceManager::find(const miral::WindowInfo &needle) const
316+{
317+ return find(needle.window());
318+}
319+
320+MirSurface *SurfaceManager::find(const miral::Window &window) const
321+{
322+ Q_FOREACH(const auto surface, m_allSurfaces) {
323+ if (surface->window() == window) {
324+ return surface;
325+ }
326+ }
327+ return nullptr;
328+}
329+
330+void SurfaceManager::onWindowReady(const miral::WindowInfo &windowInfo)
331+{
332+ if (auto mirSurface = find(windowInfo)) {
333+ mirSurface->setReady();
334+ }
335+}
336+
337+void SurfaceManager::onWindowMoved(const miral::WindowInfo &windowInfo, const QPoint topLeft)
338+{
339+ if (auto mirSurface = find(windowInfo)) {
340+ mirSurface->setPosition(topLeft);
341+ }
342+}
343+
344+void SurfaceManager::onWindowFocusChanged(const miral::WindowInfo &windowInfo, bool focused)
345+{
346+ if (auto mirSurface = find(windowInfo)) {
347+ mirSurface->setFocused(focused);
348+ }
349+}
350+
351+void SurfaceManager::onWindowStateChanged(const miral::WindowInfo &windowInfo, Mir::State state)
352+{
353+ if (auto mirSurface = find(windowInfo)) {
354+ mirSurface->updateState(state);
355+ }
356+}
357+
358+void SurfaceManager::onWindowsRaised(const std::vector<miral::Window> &windows)
359+{
360+ // sad inefficiency when crossing API boundaries (from miral to qt)
361+ const int raiseCount = windows.size();
362+ QVector<unityapi::MirSurfaceInterface*> surfaces(raiseCount);
363+ for (int i = 0; i < raiseCount; i++) {
364+ auto mirSurface = find(windows[i]);
365+ surfaces.append(mirSurface);
366+ }
367+ Q_EMIT surfacesRaised(surfaces);
368+}
369+
370+void SurfaceManager::raise(unityapi::MirSurfaceInterface *surface)
371+{
372+ auto qtmirSurface = static_cast<qtmir::MirSurface*>(surface);
373+ m_windowController->raise(qtmirSurface->window());
374+}
375+
376+void SurfaceManager::activate(unityapi::MirSurfaceInterface *surface)
377+{
378+ auto qtmirSurface = static_cast<qtmir::MirSurface*>(surface);
379+ m_windowController->activate(qtmirSurface ? qtmirSurface->window() : miral::Window());
380+}
381
382=== added file 'src/modules/Unity/Application/surfacemanager.h'
383--- src/modules/Unity/Application/surfacemanager.h 1970-01-01 00:00:00 +0000
384+++ src/modules/Unity/Application/surfacemanager.h 2016-11-15 17:55:38 +0000
385@@ -0,0 +1,72 @@
386+/*
387+ * Copyright (C) 2016 Canonical, Ltd.
388+ *
389+ * This program is free software: you can redistribute it and/or modify it under
390+ * the terms of the GNU Lesser General Public License version 3, as published by
391+ * the Free Software Foundation.
392+ *
393+ * This program is distributed in the hope that it will be useful, but WITHOUT
394+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
395+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
396+ * Lesser General Public License for more details.
397+ *
398+ * You should have received a copy of the GNU Lesser General Public License
399+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
400+ */
401+
402+#ifndef QTMIR_SURFACEMANAGER_H
403+#define QTMIR_SURFACEMANAGER_H
404+
405+// common
406+#include "windowmodelnotifier.h"
407+
408+// Unity API
409+#include <unity/shell/application/SurfaceManagerInterface.h>
410+
411+#include <QVector>
412+#include <QLoggingCategory>
413+
414+Q_DECLARE_LOGGING_CATEGORY(QTMIR_SURFACEMANAGER)
415+
416+namespace qtmir {
417+
418+class MirSurface;
419+class SessionManager;
420+class WindowControllerInterface;
421+
422+class SurfaceManager : public unity::shell::application::SurfaceManagerInterface
423+{
424+ Q_OBJECT
425+
426+public:
427+ explicit SurfaceManager(QObject *parent = 0);
428+ virtual ~SurfaceManager() {}
429+
430+ void raise(unity::shell::application::MirSurfaceInterface *surface) override;
431+ void activate(unity::shell::application::MirSurfaceInterface *surface) override;
432+
433+private Q_SLOTS:
434+ void onWindowAdded(const qtmir::NewWindow &windowInfo);
435+ void onWindowRemoved(const miral::WindowInfo &windowInfo);
436+ void onWindowReady(const miral::WindowInfo &windowInfo);
437+ void onWindowMoved(const miral::WindowInfo &windowInfo, const QPoint topLeft);
438+ void onWindowStateChanged(const miral::WindowInfo &windowInfo, Mir::State state);
439+ void onWindowFocusChanged(const miral::WindowInfo &windowInfo, bool focused);
440+ void onWindowsRaised(const std::vector<miral::Window> &windows);
441+
442+private:
443+ void connectToWindowModelNotifier(WindowModelNotifier *notifier);
444+ void rememberMirSurface(MirSurface *surface);
445+ void forgetMirSurface(const miral::Window &window);
446+ MirSurface* find(const miral::WindowInfo &needle) const;
447+ MirSurface* find(const miral::Window &needle) const;
448+
449+ QVector<MirSurface*> m_allSurfaces;
450+
451+ WindowControllerInterface *m_windowController;
452+ SessionManager* m_sessionManager;
453+};
454+
455+} // namespace qtmir
456+
457+#endif // QTMIR_SURFACEMANAGER_H
458
459=== removed file 'src/modules/Unity/Application/toplevelwindowmodel.cpp'
460--- src/modules/Unity/Application/toplevelwindowmodel.cpp 2016-11-09 14:18:17 +0000
461+++ src/modules/Unity/Application/toplevelwindowmodel.cpp 1970-01-01 00:00:00 +0000
462@@ -1,691 +0,0 @@
463-/*
464- * Copyright (C) 2016 Canonical, Ltd.
465- *
466- * This program is free software: you can redistribute it and/or modify it under
467- * the terms of the GNU Lesser General Public License version 3, as published by
468- * the Free Software Foundation.
469- *
470- * This program is distributed in the hope that it will be useful, but WITHOUT
471- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
472- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
473- * Lesser General Public License for more details.
474- *
475- * You should have received a copy of the GNU Lesser General Public License
476- * along with this program. If not, see <http://www.gnu.org/licenses/>.
477- */
478-
479-#include "toplevelwindowmodel.h"
480-
481-#include "application.h"
482-#include "application_manager.h"
483-#include "mirsurface.h"
484-#include "sessionmanager.h"
485-
486-// mirserver
487-#include "nativeinterface.h"
488-
489-// Qt
490-#include <QGuiApplication>
491-#include <QDebug>
492-
493-Q_LOGGING_CATEGORY(QTMIR_TOPLEVELWINDOWMODEL, "qtmir.toplevelwindowmodel", QtDebugMsg)
494-
495-#define DEBUG_MSG qCDebug(QTMIR_TOPLEVELWINDOWMODEL).nospace().noquote() << __func__
496-
497-using namespace qtmir;
498-namespace unityapi = unity::shell::application;
499-
500-TopLevelWindowModel::TopLevelWindowModel()
501-{
502- auto nativeInterface = dynamic_cast<NativeInterface*>(QGuiApplication::platformNativeInterface());
503-
504- if (!nativeInterface) {
505- qFatal("ERROR: Unity.Application QML plugin requires use of the 'mirserver' QPA plugin");
506- }
507-
508- m_windowController = static_cast<WindowControllerInterface*>(nativeInterface->nativeResourceForIntegration("WindowController"));
509-
510- auto windowModel = static_cast<WindowModelNotifier*>(nativeInterface->nativeResourceForIntegration("WindowModelNotifier"));
511- connectToWindowModelNotifier(windowModel);
512-
513- setApplicationManager(ApplicationManager::singleton());
514-
515- m_sessionManager = SessionManager::singleton();
516-}
517-
518-TopLevelWindowModel::TopLevelWindowModel(WindowModelNotifier *notifier,
519- WindowControllerInterface *controller)
520- : m_windowController(controller)
521-{
522- connectToWindowModelNotifier(notifier);
523-}
524-
525-void TopLevelWindowModel::setApplicationManager(ApplicationManagerInterface* value)
526-{
527- if (m_applicationManager == value) {
528- return;
529- }
530-
531- Q_ASSERT(m_modelState == IdleState);
532- m_modelState = ResettingState;
533-
534- beginResetModel();
535-
536- if (m_applicationManager) {
537- m_windowModel.clear();
538- disconnect(m_applicationManager, 0, this, 0);
539- }
540-
541- m_applicationManager = value;
542-
543- if (m_applicationManager) {
544- connect(m_applicationManager, &QAbstractItemModel::rowsInserted,
545- this, [this](const QModelIndex &/*parent*/, int first, int last) {
546- for (int i = first; i <= last; ++i) {
547- auto application = m_applicationManager->get(i);
548- addApplication(static_cast<Application*>(application));
549- }
550- });
551-
552- connect(m_applicationManager, &QAbstractItemModel::rowsAboutToBeRemoved,
553- this, [this](const QModelIndex &/*parent*/, int first, int last) {
554- for (int i = first; i <= last; ++i) {
555- auto application = m_applicationManager->get(i);
556- removeApplication(static_cast<Application*>(application));
557- }
558- });
559-
560- for (int i = 0; i < m_applicationManager->rowCount(); ++i) {
561- auto application = m_applicationManager->get(i);
562- addApplication(static_cast<Application*>(application));
563- }
564- }
565-
566- endResetModel();
567- m_modelState = IdleState;
568-}
569-
570-void TopLevelWindowModel::addApplication(Application *application)
571-{
572- DEBUG_MSG << "(" << application->appId() << ")";
573-
574- if (application->state() != unityapi::ApplicationInfoInterface::Stopped && application->surfaceList()->count() == 0) {
575- prependPlaceholder(application);
576- }
577-}
578-
579-void TopLevelWindowModel::removeApplication(Application *application)
580-{
581- DEBUG_MSG << "(" << application->appId() << ")";
582-
583- Q_ASSERT(m_modelState == IdleState);
584-
585- int i = 0;
586- while (i < m_windowModel.count()) {
587- if (m_windowModel.at(i).application == application) {
588- removeAt(i);
589- } else {
590- ++i;
591- }
592- }
593-}
594-
595-void TopLevelWindowModel::prependPlaceholder(Application *application)
596-{
597- DEBUG_MSG << "(" << application->appId() << ")";
598-
599- prependSurfaceHelper(nullptr, application);
600-}
601-
602-void TopLevelWindowModel::prependSurface(MirSurface *surface, Application *application)
603-{
604- Q_ASSERT(surface != nullptr);
605-
606- bool filledPlaceholder = false;
607- for (int i = 0; i < m_windowModel.count() && !filledPlaceholder; ++i) {
608- ModelEntry &entry = m_windowModel[i];
609- if (entry.application == application && entry.window->surface() == nullptr) {
610- entry.window->setSurface(surface);
611- connectSurface(surface);
612- DEBUG_MSG << " appId=" << application->appId() << " surface=" << surface
613- << ", filling out placeholder. after: " << toString();
614- filledPlaceholder = true;
615- }
616- }
617-
618- if (!filledPlaceholder) {
619- DEBUG_MSG << " appId=" << application->appId() << " surface=" << surface << ", adding new row";
620- prependSurfaceHelper(surface, application);
621- }
622-}
623-
624-void TopLevelWindowModel::prependSurfaceHelper(MirSurface *surface, Application *application)
625-{
626- if (m_modelState == IdleState) {
627- m_modelState = InsertingState;
628- beginInsertRows(QModelIndex(), 0 /*first*/, 0 /*last*/);
629- } else {
630- Q_ASSERT(m_modelState == ResettingState);
631- // No point in signaling anything if we're resetting the whole model
632- }
633-
634- int id = generateId();
635- Window *window = new Window(id);
636- if (surface) {
637- window->setSurface(surface);
638- }
639- m_windowModel.prepend(ModelEntry(window, application));
640- if (surface) {
641- connectSurface(surface);
642- }
643-
644- connectWindow(window);
645-
646- if (m_modelState == InsertingState) {
647- endInsertRows();
648- Q_EMIT countChanged();
649- Q_EMIT listChanged();
650- m_modelState = IdleState;
651- }
652-
653- if (!surface) {
654- // focus the newly added window. miral can't help with that as it doesn't know about it.
655- window->setFocused(true);
656- if (m_focusedWindow && m_focusedWindow->surface()) {
657- m_windowController->activate(miral::Window());
658- }
659- }
660-
661- DEBUG_MSG << " after " << toString();
662-}
663-
664-void TopLevelWindowModel::connectWindow(Window *window)
665-{
666- connect(window, &unityapi::WindowInterface::focusRequested, this, [this, window]() {
667- if (!window->surface()) {
668- // miral doesn't know about this window, so we have to do it ourselves
669- window->setFocused(true);
670- raiseId(window->id());
671- Window *previousWindow = m_focusedWindow;
672- setFocusedWindow(window);
673- if (previousWindow && previousWindow->surface() && previousWindow->surface()->focused()) {
674- m_windowController->activate(miral::Window());
675- }
676- }
677- });
678-
679- connect(window, &unityapi::WindowInterface::focusedChanged, this, [this, window](bool focused) {
680- if (window->surface()) {
681- // Condense changes to the focused window
682- // eg: Do focusedWindow=A to focusedWindow=B instead of
683- // focusedWindow=A to focusedWindow=null to focusedWindow=B
684- m_focusedWindowChanged = true;
685- if (focused) {
686- Q_ASSERT(m_newlyFocusedWindow == nullptr);
687- m_newlyFocusedWindow = window;
688- }
689- }
690- });
691-
692- connect(window, &Window::closeRequested, this, [this, window]() {
693- if (!window->surface()) {
694- int index = indexForId(window->id());
695- Q_ASSERT(index >= 0);
696- m_windowModel[index].application->close();
697- }
698- });
699-}
700-
701-void TopLevelWindowModel::connectSurface(MirSurfaceInterface *surface)
702-{
703- connect(surface, &MirSurfaceInterface::liveChanged, this, [this, surface](bool live){
704- if (!live) {
705- onSurfaceDied(surface);
706- }
707- });
708- connect(surface, &QObject::destroyed, this, [this, surface](){ this->onSurfaceDestroyed(surface); });
709-}
710-
711-void TopLevelWindowModel::onSurfaceDied(MirSurfaceInterface *surface)
712-{
713- int i = indexOf(surface);
714- if (i == -1) {
715- return;
716- }
717-
718- auto application = m_windowModel[i].application;
719-
720- // can't be starting if it already has a surface
721- Q_ASSERT(application->state() != unityapi::ApplicationInfoInterface::Starting);
722-
723- if (application->state() == unityapi::ApplicationInfoInterface::Running) {
724- m_windowModel[i].removeOnceSurfaceDestroyed = true;
725- } else {
726- // assume it got killed by the out-of-memory daemon.
727- //
728- // So leave entry in the model and only remove its surface, so shell can display a screenshot
729- // in its place.
730- m_windowModel[i].removeOnceSurfaceDestroyed = false;
731- }
732-}
733-
734-void TopLevelWindowModel::onSurfaceDestroyed(MirSurfaceInterface *surface)
735-{
736- int i = indexOf(surface);
737- if (i == -1) {
738- return;
739- }
740-
741- if (m_windowModel[i].removeOnceSurfaceDestroyed) {
742- removeAt(i);
743- } else {
744- auto window = m_windowModel[i].window;
745- window->setSurface(nullptr);
746- window->setFocused(false);
747- DEBUG_MSG << " Removed surface from entry. After: " << toString();
748- }
749-}
750-
751-void TopLevelWindowModel::connectToWindowModelNotifier(WindowModelNotifier *notifier)
752-{
753- connect(notifier, &WindowModelNotifier::windowAdded, this, &TopLevelWindowModel::onWindowAdded, Qt::QueuedConnection);
754- connect(notifier, &WindowModelNotifier::windowRemoved, this, &TopLevelWindowModel::onWindowRemoved, Qt::QueuedConnection);
755- connect(notifier, &WindowModelNotifier::windowReady, this, &TopLevelWindowModel::onWindowReady, Qt::QueuedConnection);
756- connect(notifier, &WindowModelNotifier::windowMoved, this, &TopLevelWindowModel::onWindowMoved, Qt::QueuedConnection);
757- connect(notifier, &WindowModelNotifier::windowStateChanged, this, &TopLevelWindowModel::onWindowStateChanged, Qt::QueuedConnection);
758- connect(notifier, &WindowModelNotifier::windowFocusChanged, this, &TopLevelWindowModel::onWindowFocusChanged, Qt::QueuedConnection);
759- connect(notifier, &WindowModelNotifier::windowsRaised, this, &TopLevelWindowModel::onWindowsRaised, Qt::QueuedConnection);
760- connect(notifier, &WindowModelNotifier::modificationsStarted, this, &TopLevelWindowModel::onModificationsStarted, Qt::QueuedConnection);
761- connect(notifier, &WindowModelNotifier::modificationsEnded, this, &TopLevelWindowModel::onModificationsEnded, Qt::QueuedConnection);
762-}
763-
764-void TopLevelWindowModel::onWindowAdded(const NewWindow &window)
765-{
766- auto mirSession = window.windowInfo.window().application();
767- SessionInterface* session = m_sessionManager->findSession(mirSession.get());
768-
769- auto surface = new MirSurface(window, m_windowController, session);
770- rememberMirSurface(surface);
771-
772- if (session)
773- session->registerSurface(surface);
774-
775- if (window.windowInfo.type() == mir_surface_type_inputmethod) {
776- int id = generateId();
777- Window *qmlWindow = new Window(id);
778- connectWindow(qmlWindow);
779- qmlWindow->setSurface(surface);
780- setInputMethodWindow(qmlWindow);
781- } else {
782- Application *application = m_applicationManager->findApplicationWithSession(mirSession);
783- if (application) {
784- prependSurface(surface, application);
785- } else {
786- // Must be a prompt session. No need to do anything about it here as a prompt surface is not top-level.
787- // It will show up in the qtmir::Application::promptSurfaceList of some application.
788- }
789- }
790- // TODO: handle surfaces that are neither top-level windows nor input method. eg: child dialogs, popups, menus
791-}
792-
793-void TopLevelWindowModel::onWindowRemoved(const miral::WindowInfo &windowInfo)
794-{
795- forgetMirSurface(windowInfo.window());
796-
797- if (windowInfo.type() == mir_surface_type_inputmethod) {
798- removeInputMethodWindow();
799- return;
800- }
801-
802- const int index = findIndexOf(windowInfo.window());
803- if (index >= 0) {
804- auto surface = static_cast<MirSurface*>(m_windowModel[index].window->surface());
805- surface->setLive(false);
806- }
807-}
808-
809-void TopLevelWindowModel::rememberMirSurface(MirSurface *surface)
810-{
811- m_allSurfaces.append(surface);
812-}
813-
814-void TopLevelWindowModel::forgetMirSurface(const miral::Window &window)
815-{
816- for (int i = 0; i < m_allSurfaces.count(); ++i) {
817- if (m_allSurfaces[i]->window() == window) {
818- m_allSurfaces.removeAt(i);
819- return;
820- }
821- }
822-}
823-
824-void TopLevelWindowModel::removeAt(int index)
825-{
826- if (m_modelState == IdleState) {
827- beginRemoveRows(QModelIndex(), index, index);
828- m_modelState = RemovingState;
829- } else {
830- Q_ASSERT(m_modelState == ResettingState);
831- // No point in signaling anything if we're resetting the whole model
832- }
833-
834- auto window = m_windowModel[index].window;
835-
836- window->setSurface(nullptr);
837- window->setFocused(false);
838-
839- m_windowModel.removeAt(index);
840-
841- if (m_modelState == RemovingState) {
842- endRemoveRows();
843- Q_EMIT countChanged();
844- Q_EMIT listChanged();
845- m_modelState = IdleState;
846- }
847-
848- disconnect(window, 0, this, 0);
849- if (m_focusedWindow == window) {
850- setFocusedWindow(nullptr);
851- }
852- delete window;
853-
854- DEBUG_MSG << " after " << toString();
855-}
856-
857-void TopLevelWindowModel::onWindowReady(const miral::WindowInfo &windowInfo)
858-{
859- if (auto mirSurface = find(windowInfo)) {
860- mirSurface->setReady();
861- }
862-}
863-
864-void TopLevelWindowModel::onWindowMoved(const miral::WindowInfo &windowInfo, const QPoint topLeft)
865-{
866- if (auto mirSurface = find(windowInfo)) {
867- mirSurface->setPosition(topLeft);
868- }
869-}
870-
871-void TopLevelWindowModel::onWindowFocusChanged(const miral::WindowInfo &windowInfo, bool focused)
872-{
873- if (auto mirSurface = find(windowInfo)) {
874- mirSurface->setFocused(focused);
875- }
876-}
877-
878-void TopLevelWindowModel::onWindowStateChanged(const miral::WindowInfo &windowInfo, Mir::State state)
879-{
880- if (auto mirSurface = find(windowInfo)) {
881- mirSurface->updateState(state);
882- }
883-}
884-
885-void TopLevelWindowModel::setInputMethodWindow(Window *window)
886-{
887- if (m_inputMethodWindow) {
888- qWarning("Multiple Input Method Surfaces created, removing the old one!");
889- delete m_inputMethodWindow;
890- }
891- m_inputMethodWindow = window;
892- Q_EMIT inputMethodSurfaceChanged(m_inputMethodWindow->surface());
893-}
894-
895-void TopLevelWindowModel::removeInputMethodWindow()
896-{
897- if (m_inputMethodWindow) {
898- delete m_inputMethodWindow;
899- m_inputMethodWindow = nullptr;
900- Q_EMIT inputMethodSurfaceChanged(nullptr);
901- }
902-}
903-
904-void TopLevelWindowModel::onWindowsRaised(const std::vector<miral::Window> &windows)
905-{
906- const int raiseCount = windows.size();
907- for (int i = 0; i < raiseCount; i++) {
908- int fromIndex = findIndexOf(windows[i]);
909- if (fromIndex != -1) {
910- move(fromIndex, 0);
911- }
912- }
913-}
914-
915-int TopLevelWindowModel::rowCount(const QModelIndex &/*parent*/) const
916-{
917- return m_windowModel.count();
918-}
919-
920-QVariant TopLevelWindowModel::data(const QModelIndex& index, int role) const
921-{
922- if (index.row() < 0 || index.row() >= m_windowModel.size())
923- return QVariant();
924-
925- if (role == WindowRole) {
926- unityapi::WindowInterface *window = m_windowModel.at(index.row()).window;
927- return QVariant::fromValue(window);
928- } else if (role == ApplicationRole) {
929- return QVariant::fromValue(m_windowModel.at(index.row()).application);
930- } else {
931- return QVariant();
932- }
933-}
934-
935-MirSurface *TopLevelWindowModel::find(const miral::WindowInfo &needle) const
936-{
937- auto window = needle.window();
938- Q_FOREACH(const auto surface, m_allSurfaces) {
939- if (surface->window() == window) {
940- return surface;
941- }
942- }
943- return nullptr;
944-}
945-
946-int TopLevelWindowModel::findIndexOf(const miral::Window &needle) const
947-{
948- for (int i=0; i<m_windowModel.count(); i++) {
949- auto surface = static_cast<MirSurface*>(m_windowModel[i].window->surface());
950- if (surface && surface->window() == needle) {
951- return i;
952- }
953- }
954- return -1;
955-}
956-
957-int TopLevelWindowModel::generateId()
958-{
959- int id = m_nextId;
960- m_nextId = nextFreeId(m_nextId + 1);
961- return id;
962-}
963-
964-int TopLevelWindowModel::nextFreeId(int candidateId)
965-{
966- if (candidateId > m_maxId) {
967- return nextFreeId(1);
968- } else {
969- if (indexForId(candidateId) == -1) {
970- // it's indeed free
971- return candidateId;
972- } else {
973- return nextFreeId(candidateId + 1);
974- }
975- }
976-}
977-
978-QString TopLevelWindowModel::toString()
979-{
980- QString str;
981- for (int i = 0; i < m_windowModel.count(); ++i) {
982- auto item = m_windowModel.at(i);
983-
984- QString itemStr = QString("(index=%1,appId=%2,surface=0x%3,id=%4)")
985- .arg(i)
986- .arg(item.application->appId())
987- .arg((qintptr)item.window->surface(), 0, 16)
988- .arg(item.window->id());
989-
990- if (i > 0) {
991- str.append(",");
992- }
993- str.append(itemStr);
994- }
995- return str;
996-}
997-
998-int TopLevelWindowModel::indexOf(MirSurfaceInterface *surface)
999-{
1000- for (int i = 0; i < m_windowModel.count(); ++i) {
1001- if (m_windowModel.at(i).window->surface() == surface) {
1002- return i;
1003- }
1004- }
1005- return -1;
1006-}
1007-
1008-int TopLevelWindowModel::indexForId(int id) const
1009-{
1010- for (int i = 0; i < m_windowModel.count(); ++i) {
1011- if (m_windowModel[i].window->id() == id) {
1012- return i;
1013- }
1014- }
1015- return -1;
1016-}
1017-
1018-unityapi::WindowInterface *TopLevelWindowModel::windowAt(int index) const
1019-{
1020- if (index >=0 && index < m_windowModel.count()) {
1021- return m_windowModel[index].window;
1022- } else {
1023- return nullptr;
1024- }
1025-}
1026-
1027-unityapi::MirSurfaceInterface *TopLevelWindowModel::surfaceAt(int index) const
1028-{
1029- if (index >=0 && index < m_windowModel.count()) {
1030- return m_windowModel[index].window->surface();
1031- } else {
1032- return nullptr;
1033- }
1034-}
1035-
1036-unityapi::ApplicationInfoInterface *TopLevelWindowModel::applicationAt(int index) const
1037-{
1038- if (index >=0 && index < m_windowModel.count()) {
1039- return m_windowModel[index].application;
1040- } else {
1041- return nullptr;
1042- }
1043-}
1044-
1045-int TopLevelWindowModel::idAt(int index) const
1046-{
1047- if (index >=0 && index < m_windowModel.count()) {
1048- return m_windowModel[index].window->id();
1049- } else {
1050- return 0;
1051- }
1052-}
1053-
1054-void TopLevelWindowModel::raiseId(int id)
1055-{
1056- if (m_modelState == IdleState) {
1057- DEBUG_MSG << "(id=" << id << ") - do it now.";
1058- doRaiseId(id);
1059- } else {
1060- DEBUG_MSG << "(id=" << id << ") - Model busy (modelState=" << m_modelState << "). Try again in the next event loop.";
1061- // The model has just signalled some change. If we have a Repeater responding to this update, it will get nuts
1062- // if we perform yet another model change straight away.
1063- //
1064- // A bad sympton of this problem is a Repeater.itemAt(index) call returning null event though Repeater.count says
1065- // the index is definitely within bounds.
1066- QMetaObject::invokeMethod(this, "raiseId", Qt::QueuedConnection, Q_ARG(int, id));
1067- }
1068-}
1069-
1070-void TopLevelWindowModel::doRaiseId(int id)
1071-{
1072- int fromIndex = indexForId(id);
1073- if (fromIndex != -1) {
1074- auto surface = static_cast<MirSurface*>(m_windowModel[fromIndex].window->surface());
1075- if (surface) {
1076- m_windowController->raise(surface->window());
1077- } else {
1078- // move it ourselves. Since there's no mir::scene::Surface/miral::Window, there's nothing
1079- // miral can do about it.
1080- move(fromIndex, 0);
1081- }
1082- }
1083-}
1084-
1085-void TopLevelWindowModel::setFocusedWindow(Window *window)
1086-{
1087- if (window != m_focusedWindow) {
1088- DEBUG_MSG << "(" << window << ")";
1089-
1090- Window* previousWindow = m_focusedWindow;
1091-
1092- m_focusedWindow = window;
1093- Q_EMIT focusedWindowChanged(m_focusedWindow);
1094-
1095- if (previousWindow && previousWindow->focused() && !previousWindow->surface()) {
1096- // do it ourselves. miral doesn't know about this window
1097- previousWindow->setFocused(false);
1098- }
1099- }
1100-}
1101-
1102-unityapi::MirSurfaceInterface* TopLevelWindowModel::inputMethodSurface() const
1103-{
1104- return m_inputMethodWindow ? m_inputMethodWindow->surface() : nullptr;
1105-}
1106-
1107-unityapi::WindowInterface* TopLevelWindowModel::focusedWindow() const
1108-{
1109- return m_focusedWindow;
1110-}
1111-
1112-void TopLevelWindowModel::move(int from, int to)
1113-{
1114- if (from == to) return;
1115- DEBUG_MSG << " from=" << from << " to=" << to;
1116-
1117- if (from >= 0 && from < m_windowModel.size() && to >= 0 && to < m_windowModel.size()) {
1118- QModelIndex parent;
1119- /* When moving an item down, the destination index needs to be incremented
1120- by one, as explained in the documentation:
1121- http://qt-project.org/doc/qt-5.0/qtcore/qabstractitemmodel.html#beginMoveRows */
1122-
1123- Q_ASSERT(m_modelState == IdleState);
1124- m_modelState = MovingState;
1125-
1126- beginMoveRows(parent, from, from, parent, to + (to > from ? 1 : 0));
1127-#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
1128- const auto &window = m_windowModel.takeAt(from);
1129- m_windowModel.insert(to, window);
1130-#else
1131- m_windowModel.move(from, to);
1132-#endif
1133- endMoveRows();
1134-
1135- Q_EMIT listChanged();
1136- m_modelState = IdleState;
1137-
1138- DEBUG_MSG << " after " << toString();
1139- }
1140-}
1141-void TopLevelWindowModel::onModificationsStarted()
1142-{
1143-}
1144-
1145-void TopLevelWindowModel::onModificationsEnded()
1146-{
1147- if (m_focusedWindowChanged) {
1148- setFocusedWindow(m_newlyFocusedWindow);
1149- }
1150- // reset
1151- m_focusedWindowChanged = false;
1152- m_newlyFocusedWindow = nullptr;
1153-}
1154
1155=== removed file 'src/modules/Unity/Application/toplevelwindowmodel.h'
1156--- src/modules/Unity/Application/toplevelwindowmodel.h 2016-11-04 11:06:15 +0000
1157+++ src/modules/Unity/Application/toplevelwindowmodel.h 1970-01-01 00:00:00 +0000
1158@@ -1,161 +0,0 @@
1159-/*
1160- * Copyright (C) 2016 Canonical, Ltd.
1161- *
1162- * This program is free software: you can redistribute it and/or modify it under
1163- * the terms of the GNU Lesser General Public License version 3, as published by
1164- * the Free Software Foundation.
1165- *
1166- * This program is distributed in the hope that it will be useful, but WITHOUT
1167- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1168- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1169- * Lesser General Public License for more details.
1170- *
1171- * You should have received a copy of the GNU Lesser General Public License
1172- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1173- */
1174-
1175-#ifndef TOPLEVELWINDOWMODEL_H
1176-#define TOPLEVELWINDOWMODEL_H
1177-
1178-#include <QLoggingCategory>
1179-
1180-#include "mirsurface.h"
1181-#include "window.h"
1182-#include "windowmodelnotifier.h"
1183-
1184-// Unity API
1185-#include <unity/shell/application/TopLevelWindowModelInterface.h>
1186-
1187-Q_DECLARE_LOGGING_CATEGORY(QTMIR_TOPLEVELWINDOWMODEL)
1188-
1189-namespace unity {
1190- namespace shell {
1191- namespace application {
1192- class ApplicationInfoInterface;
1193- class ApplicationManagerInterface;
1194- class MirSurfaceInterface;
1195- }
1196- }
1197-}
1198-
1199-namespace qtmir {
1200-
1201-class Application;
1202-class ApplicationManagerInterface;
1203-class SessionManager;
1204-class WindowControllerInterface;
1205-
1206-class TopLevelWindowModel : public unity::shell::application::TopLevelWindowModelInterface
1207-{
1208- Q_OBJECT
1209-
1210-public:
1211- TopLevelWindowModel();
1212- explicit TopLevelWindowModel(WindowModelNotifier *notifier,
1213- WindowControllerInterface *controller); // For testing
1214-
1215- // From unity::shell::application::TopLevelWindowModelInterface
1216- unity::shell::application::MirSurfaceInterface* inputMethodSurface() const override;
1217- unity::shell::application::WindowInterface* focusedWindow() const override;
1218-
1219- // From QAbstractItemModel
1220- int rowCount(const QModelIndex &parent = QModelIndex()) const override;
1221- QVariant data(const QModelIndex& index, int role) const override;
1222-
1223- // Own API
1224- void setApplicationManager(ApplicationManagerInterface*);
1225-
1226-public Q_SLOTS:
1227- // From unity::shell::application::TopLevelWindowModelInterface
1228- unity::shell::application::MirSurfaceInterface *surfaceAt(int index) const override;
1229- unity::shell::application::WindowInterface *windowAt(int index) const override;
1230- unity::shell::application::ApplicationInfoInterface *applicationAt(int index) const override;
1231- int idAt(int index) const override;
1232- int indexForId(int id) const override;
1233- void raiseId(int id) override;
1234-
1235-private Q_SLOTS:
1236- void onWindowAdded(const qtmir::NewWindow &windowInfo);
1237- void onWindowRemoved(const miral::WindowInfo &windowInfo);
1238- void onWindowReady(const miral::WindowInfo &windowInfo);
1239- void onWindowMoved(const miral::WindowInfo &windowInfo, const QPoint topLeft);
1240- void onWindowStateChanged(const miral::WindowInfo &windowInfo, Mir::State state);
1241- void onWindowFocusChanged(const miral::WindowInfo &windowInfo, bool focused);
1242- void onWindowsRaised(const std::vector<miral::Window> &windows);
1243- void onModificationsStarted();
1244- void onModificationsEnded();
1245-
1246-private:
1247- void doRaiseId(int id);
1248- int generateId();
1249- int nextFreeId(int candidateId);
1250- void connectToWindowModelNotifier(WindowModelNotifier *notifier);
1251- QString toString();
1252- int indexOf(MirSurfaceInterface *surface);
1253-
1254- void setInputMethodWindow(Window *window);
1255- void setFocusedWindow(Window *window);
1256- void removeInputMethodWindow();
1257- MirSurface* find(const miral::WindowInfo &needle) const;
1258- int findIndexOf(const miral::Window &needle) const;
1259- void removeAt(int index);
1260-
1261- void addApplication(Application *application);
1262- void removeApplication(Application *application);
1263-
1264- void prependPlaceholder(Application *application);
1265- void prependSurface(MirSurface *surface, Application *application);
1266- void prependSurfaceHelper(MirSurface *surface, Application *application);
1267-
1268- void connectWindow(Window *window);
1269- void connectSurface(MirSurfaceInterface *surface);
1270-
1271- void onSurfaceDied(MirSurfaceInterface *surface);
1272- void onSurfaceDestroyed(MirSurfaceInterface *surface);
1273-
1274- void move(int from, int to);
1275-
1276- void rememberMirSurface(MirSurface *surface);
1277- void forgetMirSurface(const miral::Window &window);
1278-
1279- struct ModelEntry {
1280- ModelEntry() {}
1281- ModelEntry(Window *window,
1282- Application *application)
1283- : window(window), application(application) {}
1284- Window *window{nullptr};
1285- Application *application{nullptr};
1286- bool removeOnceSurfaceDestroyed{false};
1287- };
1288-
1289- QVector<ModelEntry> m_windowModel;
1290- WindowControllerInterface *m_windowController;
1291- SessionManager* m_sessionManager;
1292- Window* m_inputMethodWindow{nullptr};
1293- Window* m_focusedWindow{nullptr};
1294- QVector<MirSurface*> m_allSurfaces;
1295-
1296- int m_nextId{1};
1297- // Just something big enough that we don't risk running out of unused id numbers.
1298- // Not sure if QML int type supports something close to std::numeric_limits<int>::max() and
1299- // there's no reason to try out its limits.
1300- static const int m_maxId{1000000};
1301-
1302- ApplicationManagerInterface* m_applicationManager{nullptr};
1303-
1304- enum ModelState {
1305- IdleState,
1306- InsertingState,
1307- RemovingState,
1308- MovingState,
1309- ResettingState
1310- };
1311- ModelState m_modelState{IdleState};
1312-
1313- // Valid between modificationsStarted and modificationsEnded
1314- bool m_focusedWindowChanged{false};
1315- Window *m_newlyFocusedWindow{nullptr};
1316-};
1317-
1318-} // namespace qtmir
1319-#endif // TOPLEVELWINDOWMODEL_H
1320
1321=== removed file 'src/modules/Unity/Application/window.cpp'
1322--- src/modules/Unity/Application/window.cpp 2016-11-07 11:44:55 +0000
1323+++ src/modules/Unity/Application/window.cpp 1970-01-01 00:00:00 +0000
1324@@ -1,186 +0,0 @@
1325-/*
1326- * Copyright (C) 2016 Canonical, Ltd.
1327- *
1328- * This program is free software; you can redistribute it and/or modify
1329- * it under the terms of the GNU General Public License as published by
1330- * the Free Software Foundation; version 3.
1331- *
1332- * This program is distributed in the hope that it will be useful,
1333- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1334- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1335- * GNU General Public License for more details.
1336- *
1337- * You should have received a copy of the GNU General Public License
1338- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1339- */
1340-
1341-#include "window.h"
1342-#include "mirsurface.h"
1343-
1344-#include <QQmlEngine>
1345-
1346-namespace unityapi = unity::shell::application;
1347-using namespace qtmir;
1348-
1349-Window::Window(int id)
1350- : WindowInterface(nullptr)
1351- , m_id(id)
1352-{
1353- QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
1354-}
1355-
1356-QPoint Window::position() const
1357-{
1358- return m_position;
1359-}
1360-
1361-QPoint Window::requestedPosition() const
1362-{
1363- return m_requestedPosition;
1364-}
1365-
1366-void Window::setRequestedPosition(const QPoint &value)
1367-{
1368- if (value != m_requestedPosition) {
1369- m_requestedPosition = value;
1370- Q_EMIT requestedPositionChanged(m_requestedPosition);
1371- if (m_surface) {
1372- m_surface->setRequestedPosition(value);
1373- } else {
1374- // fake-miral: always comply
1375- m_position = m_requestedPosition;
1376- Q_EMIT positionChanged(m_position);
1377- }
1378- }
1379-}
1380-
1381-Mir::State Window::state() const
1382-{
1383- return m_state;
1384-}
1385-
1386-bool Window::focused() const
1387-{
1388- return m_focused;
1389-}
1390-
1391-bool Window::confinesMousePointer() const
1392-{
1393- if (m_surface) {
1394- return m_surface->confinesMousePointer();
1395- } else {
1396- return false;
1397- }
1398-}
1399-
1400-int Window::id() const
1401-{
1402- return m_id;
1403-}
1404-
1405-unityapi::MirSurfaceInterface* Window::surface() const
1406-{
1407- return m_surface;
1408-}
1409-
1410-void Window::requestState(Mir::State state)
1411-{
1412- if (m_surface) {
1413- m_surface->requestState(state);
1414- } else if (m_state != state) {
1415- m_state = state;
1416- Q_EMIT stateChanged(m_state);
1417- }
1418-}
1419-
1420-void Window::requestFocus()
1421-{
1422- if (m_surface) {
1423- m_surface->requestFocus();
1424- } else {
1425- Q_EMIT focusRequested();
1426- }
1427-}
1428-
1429-void Window::close()
1430-{
1431- if (m_surface) {
1432- m_surface->close();
1433- } else {
1434- Q_EMIT closeRequested();
1435- }
1436-}
1437-
1438-void Window::setSurface(MirSurface *surface)
1439-{
1440- if (m_surface) {
1441- disconnect(m_surface, 0, this, 0);
1442- }
1443-
1444- m_surface = surface;
1445-
1446- if (m_surface) {
1447- connect(surface, &MirSurfaceInterface::focusRequested, this, [this]() {
1448- Q_EMIT focusRequested();
1449- });
1450-
1451- connect(surface, &MirSurfaceInterface::closeRequested, this, &Window::closeRequested);
1452-
1453- connect(surface, &MirSurfaceInterface::positionChanged, this, [this]() {
1454- updatePosition();
1455- });
1456-
1457- connect(surface, &MirSurfaceInterface::stateChanged, this, [this]() {
1458- updateState();
1459- });
1460-
1461- connect(surface, &MirSurfaceInterface::focusedChanged, this, [this]() {
1462- updateFocused();
1463- });
1464-
1465- // bring it up to speed
1466- m_surface->setRequestedPosition(m_requestedPosition);
1467- m_surface->requestState(m_state);
1468-
1469- // and sync with surface
1470- updatePosition();
1471- updateState();
1472- updateFocused();
1473- }
1474-
1475- Q_EMIT surfaceChanged(surface);
1476-}
1477-
1478-void Window::updatePosition()
1479-{
1480- if (m_surface->position() != m_position) {
1481- m_position = m_surface->position();
1482- Q_EMIT positionChanged(m_position);
1483- }
1484-}
1485-
1486-void Window::updateState()
1487-{
1488- if (m_surface->state() != m_state) {
1489- m_state = m_surface->state();
1490- Q_EMIT stateChanged(m_state);
1491- }
1492-}
1493-
1494-void Window::updateFocused()
1495-{
1496- if (m_surface->focused() != m_focused) {
1497- m_focused = m_surface->focused();
1498- Q_EMIT focusedChanged(m_focused);
1499- }
1500-}
1501-
1502-void Window::setFocused(bool value)
1503-{
1504- if (value != m_focused) {
1505- m_focused = value;
1506- Q_EMIT focusedChanged(m_focused);
1507- // when we have a surface we get focus changes from updateFocused() instead
1508- Q_ASSERT(!m_surface);
1509- }
1510-}
1511
1512=== removed file 'src/modules/Unity/Application/window.h'
1513--- src/modules/Unity/Application/window.h 2016-11-03 20:17:46 +0000
1514+++ src/modules/Unity/Application/window.h 1970-01-01 00:00:00 +0000
1515@@ -1,67 +0,0 @@
1516-/*
1517- * Copyright (C) 2016 Canonical, Ltd.
1518- *
1519- * This program is free software; you can redistribute it and/or modify
1520- * it under the terms of the GNU General Public License as published by
1521- * the Free Software Foundation; version 3.
1522- *
1523- * This program is distributed in the hope that it will be useful,
1524- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1525- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1526- * GNU General Public License for more details.
1527- *
1528- * You should have received a copy of the GNU General Public License
1529- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1530- */
1531-
1532-#ifndef QTMIR_WINDOW_H
1533-#define QTMIR_WINDOW_H
1534-
1535-// unity-api
1536-#include <unity/shell/application/WindowInterface.h>
1537-
1538-namespace qtmir {
1539-
1540-class MirSurface;
1541-
1542-class Window : public unity::shell::application::WindowInterface
1543-{
1544- Q_OBJECT
1545-
1546-public:
1547- Window(int id);
1548- QPoint position() const override;
1549- QPoint requestedPosition() const override;
1550- void setRequestedPosition(const QPoint &) override;
1551- Mir::State state() const override;
1552- bool focused() const override;
1553- bool confinesMousePointer() const override;
1554- int id() const override;
1555- unity::shell::application::MirSurfaceInterface* surface() const override;
1556-
1557- void setSurface(MirSurface *surface);
1558- void setFocused(bool value);
1559-
1560-public Q_SLOTS:
1561- void requestState(Mir::State state) override;
1562- void requestFocus() override;
1563- void close() override;
1564-
1565-Q_SIGNALS:
1566- void closeRequested();
1567-
1568-private:
1569- void updatePosition();
1570- void updateState();
1571- void updateFocused();
1572-
1573- QPoint m_position;
1574- QPoint m_requestedPosition;
1575- bool m_focused{false};
1576- int m_id;
1577- Mir::State m_state{Mir::RestoredState};
1578- MirSurface *m_surface{nullptr};
1579-};
1580-
1581-} // namespace qtmir {
1582-#endif // QTMIR_WINDOW_H

Subscribers

People subscribed via source and target branches

to all changes: