Merge lp:~dandrader/miral/moveStuffToUnityApi into lp:miral

Proposed by Daniel d'Andrada
Status: Merged
Approved by: Gerry Boland
Approved revision: 427
Merged at revision: 431
Proposed branch: lp:~dandrader/miral/moveStuffToUnityApi
Merge into: lp:miral
Diff against target: 1294 lines (+522/-261)
14 files modified
miral-qt/CMakeLists.txt (+1/-1)
miral-qt/debian/control (+2/-2)
miral-qt/debian/gles-patches/convert-to-gles.patch (+1/-1)
miral-qt/src/common/debughelpers.cpp (+2/-0)
miral-qt/src/common/windowmodelnotifier.h (+2/-0)
miral-qt/src/modules/Unity/Application/CMakeLists.txt (+3/-0)
miral-qt/src/modules/Unity/Application/mirsurface.h (+5/-1)
miral-qt/src/modules/Unity/Application/mirsurfaceinterface.h (+0/-21)
miral-qt/src/modules/Unity/Application/plugin.cpp (+2/-0)
miral-qt/src/modules/Unity/Application/toplevelwindowmodel.cpp (+194/-133)
miral-qt/src/modules/Unity/Application/toplevelwindowmodel.h (+43/-94)
miral-qt/src/modules/Unity/Application/window.cpp (+190/-0)
miral-qt/src/modules/Unity/Application/window.h (+67/-0)
miral-qt/src/platforms/mirserver/windowmanagementpolicy.cpp (+10/-8)
To merge this branch: bzr merge lp:~dandrader/miral/moveStuffToUnityApi
Reviewer Review Type Date Requested Status
Gerry Boland (community) Approve
Review via email: mp+309785@code.launchpad.net

Commit message

[miral-qt] Move stuff to unity-api

+ bunch of other improvements and fixes

Description of the change

To post a comment you must log in.
426. By Daniel d'Andrada

[miral-qt] Move stuff to unity-api

+ bunch of other improvements and fixes

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

+// Code below crashes with things like move(from=-1, to=0) when there's only one item in the list
+#if 0
...
+#endif

Why are we keeping it?

Revision history for this message
Gerry Boland (gerboland) wrote :

+// Code below crashes with things like move(from=-1, to=0) when there's only one item in the list
+#if 0

if the simpler code works, why keep this?

Revision history for this message
Gerry Boland (gerboland) wrote :

Rest looks reasonable

review: Approve
427. By Daniel d'Andrada

Remove commented-out code

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

Removed the commented-out code.

Revision history for this message
Gerry Boland (gerboland) wrote :

Ok

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'miral-qt/CMakeLists.txt'
2--- miral-qt/CMakeLists.txt 2016-10-26 14:03:04 +0000
3+++ miral-qt/CMakeLists.txt 2016-11-03 12:11:13 +0000
4@@ -93,7 +93,7 @@
5 pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
6 pkg_check_modules(QTDBUSTEST libqtdbustest-1 REQUIRED)
7 pkg_check_modules(QTDBUSMOCK libqtdbusmock-1 REQUIRED)
8-pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=22)
9+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=23)
10 pkg_check_modules(CGMANAGER libcgmanager REQUIRED)
11 pkg_check_modules(CONTENT_HUB libcontent-hub>=0.2 REQUIRED)
12
13
14=== modified file 'miral-qt/debian/control'
15--- miral-qt/debian/control 2016-09-23 15:56:53 +0000
16+++ miral-qt/debian/control 2016-11-03 12:11:13 +0000
17@@ -24,7 +24,7 @@
18 libubuntu-app-launch2-dev (>= 0.9),
19 libubuntu-application-api-dev (>= 2.1.0),
20 libudev-dev,
21- libunity-api-dev (>= 7.119),
22+ libunity-api-dev (>= 7.120),
23 liburl-dispatcher1-dev,
24 libxkbcommon-dev,
25 libxrender-dev,
26@@ -98,7 +98,7 @@
27 Conflicts: libqtmir,
28 libunity-mir1,
29 Provides: unity-application-impl,
30- unity-application-impl-22,
31+ unity-application-impl-23,
32 Description: Qt plugin for Unity specific Mir APIs
33 QtMir provides Qt/QML bindings for Mir features that are exposed through the
34 qtmir-desktop or qtmir-android QPA plugin such as Application management
35
36=== modified file 'miral-qt/debian/gles-patches/convert-to-gles.patch'
37--- miral-qt/debian/gles-patches/convert-to-gles.patch 2016-09-23 15:56:53 +0000
38+++ miral-qt/debian/gles-patches/convert-to-gles.patch 2016-11-03 12:11:13 +0000
39@@ -84,7 +84,7 @@
40 -Conflicts: libqtmir,
41 - libunity-mir1,
42 -Provides: unity-application-impl,
43-- unity-application-impl-22,
44+- unity-application-impl-23,
45 -Description: Qt plugin for Unity specific Mir APIs
46 - QtMir provides Qt/QML bindings for Mir features that are exposed through the
47 - qtmir-desktop or qtmir-android QPA plugin such as Application management
48
49=== modified file 'miral-qt/src/common/debughelpers.cpp'
50--- miral-qt/src/common/debughelpers.cpp 2016-10-06 11:04:44 +0000
51+++ miral-qt/src/common/debughelpers.cpp 2016-11-03 12:11:13 +0000
52@@ -149,6 +149,8 @@
53 return "vertmaximized";
54 case mir_surface_state_fullscreen:
55 return "fullscreen";
56+ case mir_surface_state_hidden:
57+ return "hidden";
58 default:
59 return "???";
60 }
61
62=== modified file 'miral-qt/src/common/windowmodelnotifier.h'
63--- miral-qt/src/common/windowmodelnotifier.h 2016-10-06 20:56:04 +0000
64+++ miral-qt/src/common/windowmodelnotifier.h 2016-11-03 12:11:13 +0000
65@@ -77,6 +77,8 @@
66 void windowStateChanged(const miral::WindowInfo &window, Mir::State state);
67 void windowFocusChanged(const miral::WindowInfo &window, bool focused);
68 void windowsRaised(const std::vector<miral::Window> &windows); // results in deep copy when passed over Queued connection:(
69+ void modificationsStarted();
70+ void modificationsEnded();
71
72 private:
73 Q_DISABLE_COPY(WindowModelNotifier)
74
75=== modified file 'miral-qt/src/modules/Unity/Application/CMakeLists.txt'
76--- miral-qt/src/modules/Unity/Application/CMakeLists.txt 2016-11-02 15:19:09 +0000
77+++ miral-qt/src/modules/Unity/Application/CMakeLists.txt 2016-11-03 12:11:13 +0000
78@@ -57,6 +57,7 @@
79 toplevelwindowmodel.cpp
80 tracepoints.c
81 settings.cpp
82+ window.cpp
83 windowmodel.cpp
84 # We need to run moc on these headers
85 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
86@@ -65,6 +66,8 @@
87 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceInterface.h
88 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceItemInterface.h
89 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceListInterface.h
90+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/TopLevelWindowModelInterface.h
91+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/WindowInterface.h
92 # Feed the automoc monster
93 session_interface.h
94 applicationinfo.h
95
96=== modified file 'miral-qt/src/modules/Unity/Application/mirsurface.h'
97--- miral-qt/src/modules/Unity/Application/mirsurface.h 2016-11-02 15:36:49 +0000
98+++ miral-qt/src/modules/Unity/Application/mirsurface.h 2016-11-03 12:11:13 +0000
99@@ -168,9 +168,13 @@
100 std::shared_ptr<SurfaceObserver> surfaceObserver() const;
101
102 public Q_SLOTS:
103+ ////
104+ // unity::shell::application::MirSurfaceInterface
105 void requestState(Mir::State qmlState) override;
106+
107+ ////
108+ // qtmir::MirSurfaceInterface
109 void onCompositorSwappedBuffers() override;
110-
111 void setShellChrome(Mir::ShellChrome shellChrome) override;
112
113 private Q_SLOTS:
114
115=== modified file 'miral-qt/src/modules/Unity/Application/mirsurfaceinterface.h'
116--- miral-qt/src/modules/Unity/Application/mirsurfaceinterface.h 2016-10-06 15:36:43 +0000
117+++ miral-qt/src/modules/Unity/Application/mirsurfaceinterface.h 2016-11-03 12:11:13 +0000
118@@ -39,21 +39,10 @@
119 {
120 Q_OBJECT
121
122- /**
123- * @brief Position of the current surface buffer, in pixels.
124- */
125- // TODO: Move to unity::shell::application::MirSurfaceInterface
126- Q_PROPERTY(QPoint position READ position NOTIFY positionChanged)
127-
128- // TODO: Move to unity::shell::application::MirSurfaceInterface
129- Q_PROPERTY(QPoint requestedPosition READ requestedPosition WRITE setRequestedPosition NOTIFY requestedPositionChanged)
130-
131 public:
132 MirSurfaceInterface(QObject *parent = nullptr) : unity::shell::application::MirSurfaceInterface(parent) {}
133 virtual ~MirSurfaceInterface() {}
134
135- virtual QPoint position() const = 0;
136-
137 virtual void setLive(bool value) = 0;
138
139 virtual bool isReady() const = 0;
140@@ -118,13 +107,7 @@
141
142 virtual bool inputAreaContains(const QPoint &) const = 0;
143
144- // TODO: Move to unity::shell::application::MirSurfaceInterface
145- virtual QPoint requestedPosition() const = 0;
146- virtual void setRequestedPosition(const QPoint &) = 0;
147-
148 public Q_SLOTS:
149- virtual void requestState(Mir::State qmlState) = 0; // TODO: move to unity-api
150-
151 virtual void onCompositorSwappedBuffers() = 0;
152
153 virtual void setShellChrome(Mir::ShellChrome shellChrome) = 0;
154@@ -137,10 +120,6 @@
155 void framesPosted();
156 void isBeingDisplayedChanged();
157 void frameDropped();
158- void positionChanged(QPoint position);
159-
160- // TODO: Move to unity::shell::application::MirSurfaceInterface
161- void requestedPositionChanged(QPoint position);
162 };
163
164 } // namespace qtmir
165
166=== modified file 'miral-qt/src/modules/Unity/Application/plugin.cpp'
167--- miral-qt/src/modules/Unity/Application/plugin.cpp 2016-09-29 14:33:52 +0000
168+++ miral-qt/src/modules/Unity/Application/plugin.cpp 2016-11-03 12:11:13 +0000
169@@ -24,6 +24,7 @@
170 #include "mirsurfaceitem.h"
171 #include "mirsurfacelistmodel.h"
172 #include "toplevelwindowmodel.h"
173+#include "window.h"
174 #include "windowmodel.h"
175
176 // platforms/mirserver
177@@ -65,6 +66,7 @@
178 qRegisterMetaType<unity::shell::application::MirSurfaceInterface*>("MirSurfaceInterface*");
179 qRegisterMetaType<unity::shell::application::MirSurfaceListInterface*>("unity::shell::application::MirSurfaceListInterface*");
180 qRegisterMetaType<MirSurfaceAttrib>("MirSurfaceAttrib");
181+ qRegisterMetaType<unity::shell::application::WindowInterface*>("unity::shell::application::WindowInterface*");
182
183 qmlRegisterUncreatableType<unity::shell::application::ApplicationManagerInterface>(
184 uri, 0, 1, "ApplicationManagerInterface", "Abstract interface. Cannot be created in QML");
185
186=== modified file 'miral-qt/src/modules/Unity/Application/toplevelwindowmodel.cpp'
187--- miral-qt/src/modules/Unity/Application/toplevelwindowmodel.cpp 2016-10-28 11:57:11 +0000
188+++ miral-qt/src/modules/Unity/Application/toplevelwindowmodel.cpp 2016-11-03 12:11:13 +0000
189@@ -16,6 +16,7 @@
190
191 #include "toplevelwindowmodel.h"
192
193+#include "application.h"
194 #include "application_manager.h"
195 #include "mirsurface.h"
196 #include "sessionmanager.h"
197@@ -27,9 +28,9 @@
198 #include <QGuiApplication>
199 #include <QDebug>
200
201-Q_LOGGING_CATEGORY(QTMIR_WINDOWMODEL, "qtmir.windowmodel", QtDebugMsg)
202+Q_LOGGING_CATEGORY(QTMIR_TOPLEVELWINDOWMODEL, "qtmir.toplevelwindowmodel", QtDebugMsg)
203
204-#define DEBUG_MSG qCDebug(QTMIR_WINDOWMODEL).nospace().noquote() << __func__
205+#define DEBUG_MSG qCDebug(QTMIR_TOPLEVELWINDOWMODEL).nospace().noquote() << __func__
206
207 using namespace qtmir;
208 namespace unityapi = unity::shell::application;
209@@ -82,7 +83,7 @@
210 this, [this](const QModelIndex &/*parent*/, int first, int last) {
211 for (int i = first; i <= last; ++i) {
212 auto application = m_applicationManager->get(i);
213- addApplication(application);
214+ addApplication(static_cast<Application*>(application));
215 }
216 });
217
218@@ -90,13 +91,13 @@
219 this, [this](const QModelIndex &/*parent*/, int first, int last) {
220 for (int i = first; i <= last; ++i) {
221 auto application = m_applicationManager->get(i);
222- removeApplication(application);
223+ removeApplication(static_cast<Application*>(application));
224 }
225 });
226
227 for (int i = 0; i < m_applicationManager->rowCount(); ++i) {
228 auto application = m_applicationManager->get(i);
229- addApplication(application);
230+ addApplication(static_cast<Application*>(application));
231 }
232 }
233
234@@ -104,16 +105,16 @@
235 m_modelState = IdleState;
236 }
237
238-void TopLevelWindowModel::addApplication(unityapi::ApplicationInfoInterface *application)
239+void TopLevelWindowModel::addApplication(Application *application)
240 {
241 DEBUG_MSG << "(" << application->appId() << ")";
242
243 if (application->state() != unityapi::ApplicationInfoInterface::Stopped && application->surfaceList()->count() == 0) {
244- appendPlaceholder(application);
245+ prependPlaceholder(application);
246 }
247 }
248
249-void TopLevelWindowModel::removeApplication(unityapi::ApplicationInfoInterface *application)
250+void TopLevelWindowModel::removeApplication(Application *application)
251 {
252 DEBUG_MSG << "(" << application->appId() << ")";
253
254@@ -138,52 +139,57 @@
255 DEBUG_MSG << " after " << toString();
256 }
257
258-void TopLevelWindowModel::appendPlaceholder(unityapi::ApplicationInfoInterface *application)
259+void TopLevelWindowModel::prependPlaceholder(Application *application)
260 {
261 DEBUG_MSG << "(" << application->appId() << ")";
262
263- appendSurfaceHelper(nullptr, application);
264+ prependSurfaceHelper(nullptr, application);
265 }
266
267-void TopLevelWindowModel::appendSurface(MirSurface *surface, unityapi::ApplicationInfoInterface *application)
268+void TopLevelWindowModel::prependSurface(MirSurface *surface, Application *application)
269 {
270 Q_ASSERT(surface != nullptr);
271
272 bool filledPlaceholder = false;
273 for (int i = 0; i < m_windowModel.count() && !filledPlaceholder; ++i) {
274 ModelEntry &entry = m_windowModel[i];
275- if (entry.application == application && entry.surface == nullptr) {
276- entry.surface = surface;
277+ if (entry.application == application && entry.window->surface() == nullptr) {
278+ entry.window->setSurface(surface);
279 connectSurface(surface);
280 DEBUG_MSG << " appId=" << application->appId() << " surface=" << surface
281 << ", filling out placeholder. after: " << toString();
282- Q_EMIT dataChanged(index(i) /* topLeft */, index(i) /* bottomRight */, QVector<int>() << SurfaceRole);
283 filledPlaceholder = true;
284 }
285 }
286
287 if (!filledPlaceholder) {
288 DEBUG_MSG << " appId=" << application->appId() << " surface=" << surface << ", adding new row";
289- appendSurfaceHelper(surface, application);
290+ prependSurfaceHelper(surface, application);
291 }
292 }
293
294-void TopLevelWindowModel::appendSurfaceHelper(MirSurface *surface, unityapi::ApplicationInfoInterface *application)
295+void TopLevelWindowModel::prependSurfaceHelper(MirSurface *surface, Application *application)
296 {
297 if (m_modelState == IdleState) {
298 m_modelState = InsertingState;
299- beginInsertRows(QModelIndex(), m_windowModel.size() /*first*/, m_windowModel.size() /*last*/);
300+ beginInsertRows(QModelIndex(), 0 /*first*/, 0 /*last*/);
301 } else {
302 Q_ASSERT(m_modelState == ResettingState);
303 // No point in signaling anything if we're resetting the whole model
304 }
305
306 int id = generateId();
307- m_windowModel.append(ModelEntry(surface, application, id));
308+ Window *window = new Window(id);
309+ if (surface) {
310+ window->setSurface(surface);
311+ }
312+ m_windowModel.prepend(ModelEntry(window, application));
313 if (surface) {
314 connectSurface(surface);
315 }
316
317+ connectWindow(window);
318+
319 if (m_modelState == InsertingState) {
320 endInsertRows();
321 Q_EMIT countChanged();
322@@ -191,9 +197,54 @@
323 m_modelState = IdleState;
324 }
325
326+ if (!surface) {
327+ // focus the newly added window. miral can't help with that as it doesn't know about it.
328+ window->setFocused(true);
329+ if (m_focusedWindow && m_focusedWindow->surface()) {
330+ m_windowController->activate(miral::Window());
331+ }
332+ }
333+
334 DEBUG_MSG << " after " << toString();
335 }
336
337+void TopLevelWindowModel::connectWindow(Window *window)
338+{
339+ connect(window, &unityapi::WindowInterface::focusRequested, this, [this, window]() {
340+ if (!window->surface()) {
341+ // miral doesn't know about this window, so we have to do it ourselves
342+ window->setFocused(true);
343+ raiseId(window->id());
344+ Window *previousWindow = m_focusedWindow;
345+ setFocusedWindow(window);
346+ if (previousWindow && previousWindow->surface() && previousWindow->surface()->focused()) {
347+ m_windowController->activate(miral::Window());
348+ }
349+ }
350+ });
351+
352+ connect(window, &unityapi::WindowInterface::focusedChanged, this, [this, window](bool focused) {
353+ if (window->surface()) {
354+ // Condense changes to the focused window
355+ // eg: Do focusedWindow=A to focusedWindow=B instead of
356+ // focusedWindow=A to focusedWindow=null to focusedWindow=B
357+ m_focusedWindowChanged = true;
358+ if (focused) {
359+ Q_ASSERT(m_newlyFocusedWindow == nullptr);
360+ m_newlyFocusedWindow = window;
361+ }
362+ }
363+ });
364+
365+ connect(window, &Window::closeRequested, this, [this, window]() {
366+ if (!window->surface()) {
367+ int index = indexForId(window->id());
368+ Q_ASSERT(index >= 0);
369+ m_windowModel[index].application->close();
370+ }
371+ });
372+}
373+
374 void TopLevelWindowModel::connectSurface(MirSurfaceInterface *surface)
375 {
376 connect(surface, &MirSurfaceInterface::liveChanged, this, [this, surface](bool live){
377@@ -237,11 +288,9 @@
378 if (m_windowModel[i].removeOnceSurfaceDestroyed) {
379 removeAt(i);
380 } else {
381- if (m_windowModel[i].surface == m_focusedSurface) {
382- setFocusedSurface(nullptr);
383- }
384- m_windowModel[i].surface = nullptr;
385- Q_EMIT dataChanged(index(i) /* topLeft */, index(i) /* bottomRight */, QVector<int>() << SurfaceRole);
386+ auto window = m_windowModel[i].window;
387+ window->setSurface(nullptr);
388+ window->setFocused(false);
389 DEBUG_MSG << " Removed surface from entry. After: " << toString();
390 }
391 }
392@@ -255,14 +304,8 @@
393 connect(notifier, &WindowModelNotifier::windowStateChanged, this, &TopLevelWindowModel::onWindowStateChanged, Qt::QueuedConnection);
394 connect(notifier, &WindowModelNotifier::windowFocusChanged, this, &TopLevelWindowModel::onWindowFocusChanged, Qt::QueuedConnection);
395 connect(notifier, &WindowModelNotifier::windowsRaised, this, &TopLevelWindowModel::onWindowsRaised, Qt::QueuedConnection);
396-}
397-
398-QHash<int, QByteArray> TopLevelWindowModel::roleNames() const
399-{
400- QHash<int, QByteArray> roleNames { {SurfaceRole, "surface"},
401- {ApplicationRole, "application"},
402- {IdRole, "id"} };
403- return roleNames;
404+ connect(notifier, &WindowModelNotifier::modificationsStarted, this, &TopLevelWindowModel::onModificationsStarted, Qt::QueuedConnection);
405+ connect(notifier, &WindowModelNotifier::modificationsEnded, this, &TopLevelWindowModel::onModificationsEnded, Qt::QueuedConnection);
406 }
407
408 void TopLevelWindowModel::onWindowAdded(const NewWindow &window)
409@@ -276,11 +319,16 @@
410 session->registerSurface(surface);
411
412 if (window.windowInfo.type() == mir_surface_type_inputmethod) {
413- setInputMethodWindow(surface);
414+ int id = generateId();
415+ Window *qmlWindow = new Window(id);
416+ connectWindow(qmlWindow);
417+ qmlWindow->setSurface(surface);
418+ setInputMethodWindow(qmlWindow);
419 } else {
420- unityapi::ApplicationInfoInterface *application = m_applicationManager->findApplicationWithSession(mirSession);
421- appendSurface(surface, application);
422+ Application *application = m_applicationManager->findApplicationWithSession(mirSession);
423+ prependSurface(surface, application);
424 }
425+ // TODO: handle surfaces that are neither top-level windows nor input method. eg: child dialogs, popups, menus
426 }
427
428 void TopLevelWindowModel::onWindowRemoved(const miral::WindowInfo &windowInfo)
429@@ -292,7 +340,8 @@
430
431 const int index = findIndexOf(windowInfo.window());
432 if (index >= 0) {
433- m_windowModel[index].surface->setLive(false);
434+ auto surface = static_cast<MirSurface*>(m_windowModel[index].window->surface());
435+ surface->setLive(false);
436 }
437 }
438
439@@ -306,12 +355,15 @@
440 // No point in signaling anything if we're resetting the whole model
441 }
442
443- if (m_windowModel[index].surface != nullptr && m_windowModel[index].surface == m_focusedSurface) {
444- setFocusedSurface(nullptr);
445- }
446+ auto window = m_windowModel[index].window;
447+
448+ window->setSurface(nullptr);
449+ window->setFocused(false);
450
451 m_windowModel.removeAt(index);
452
453+ delete window;
454+
455 if (m_modelState == RemovingState) {
456 endRemoveRows();
457 Q_EMIT countChanged();
458@@ -340,12 +392,6 @@
459 {
460 if (auto mirSurface = find(windowInfo)) {
461 mirSurface->setFocused(focused);
462-
463- if (focused) {
464- setFocusedSurface(mirSurface);
465- } else if (mirSurface == m_focusedSurface) {
466- setFocusedSurface(nullptr);
467- }
468 }
469 }
470
471@@ -353,78 +399,41 @@
472 {
473 if (auto mirSurface = find(windowInfo)) {
474 mirSurface->updateState(state);
475+ } else if (m_inputMethodWindow) {
476+ auto surface = static_cast<MirSurface*>(m_inputMethodWindow->surface());
477+ if (surface->window() == windowInfo.window()) {
478+ surface->updateState(state);
479+ }
480 }
481 }
482
483-void TopLevelWindowModel::setInputMethodWindow(MirSurface *surface)
484+void TopLevelWindowModel::setInputMethodWindow(Window *window)
485 {
486- if (m_inputMethodSurface) {
487- qDebug("Multiple Input Method Surfaces created, removing the old one!");
488- delete m_inputMethodSurface;
489+ if (m_inputMethodWindow) {
490+ qWarning("Multiple Input Method Surfaces created, removing the old one!");
491+ delete m_inputMethodWindow;
492 }
493- m_inputMethodSurface = surface;
494- Q_EMIT inputMethodSurfaceChanged(m_inputMethodSurface);
495+ m_inputMethodWindow = window;
496+ Q_EMIT inputMethodSurfaceChanged(m_inputMethodWindow->surface());
497 }
498
499 void TopLevelWindowModel::removeInputMethodWindow()
500 {
501- if (m_inputMethodSurface) {
502- delete m_inputMethodSurface;
503- m_inputMethodSurface = nullptr;
504- Q_EMIT inputMethodSurfaceChanged(m_inputMethodSurface);
505+ if (m_inputMethodWindow) {
506+ delete m_inputMethodWindow;
507+ m_inputMethodWindow = nullptr;
508+ Q_EMIT inputMethodSurfaceChanged(nullptr);
509 }
510 }
511
512 void TopLevelWindowModel::onWindowsRaised(const std::vector<miral::Window> &windows)
513 {
514- // Reminder: last item in the "windows" list should end up at the top of the model
515- const int modelCount = m_windowModel.count();
516 const int raiseCount = windows.size();
517-
518- // Assumption: no NO-OPs are in this list - Qt will crash on endMoveRows() if you try NO-OPs!!!
519- // A NO-OP is if
520- // 1. "indices" is an empty list
521- // 2. "indices" of the form (..., modelCount - 2, modelCount - 1) which results in an unchanged list
522-
523- // Precompute the list of indices of Windows/Surfaces to raise, including the offsets due to
524- // indices which have already been moved.
525- QVector<QPair<int /*from*/, int /*to*/>> moveList;
526-
527- for (int i=raiseCount-1; i>=0; i--) {
528- int from = findIndexOf(windows[i]);
529- const int to = modelCount - raiseCount + i;
530-
531- int moveCount = 0;
532- // how many list items under "index" have been moved so far, correct "from" to suit
533- for (int j=raiseCount-1; j>i; j--) {
534- if (findIndexOf(windows[j]) < from) {
535- moveCount++;
536- }
537- }
538- from -= moveCount;
539-
540- if (from == to) {
541- // is NO-OP, would result in moving element to itself
542- } else {
543- moveList.prepend({from, to});
544- }
545- }
546-
547- // Perform the moving, trusting the moveList is correct for each iteration.
548- QModelIndex parent;
549- for (int i=moveList.count()-1; i>=0; i--) {
550- const int from = moveList[i].first;
551- const int to = moveList[i].second;
552-
553- beginMoveRows(parent, from, from, parent, to+1);
554-#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
555- const auto &window = m_windowModel.takeAt(from);
556- m_windowModel.insert(to, window);
557-#else
558- m_windowModel.move(from, to);
559-#endif
560-
561- endMoveRows();
562+ for (int i = 0; i < raiseCount; i++) {
563+ int fromIndex = findIndexOf(windows[i]);
564+ if (fromIndex != -1) {
565+ move(fromIndex, 0);
566+ }
567 }
568 }
569
570@@ -438,13 +447,11 @@
571 if (index.row() < 0 || index.row() >= m_windowModel.size())
572 return QVariant();
573
574- if (role == SurfaceRole) {
575- unityapi::MirSurfaceInterface *surface = m_windowModel.at(index.row()).surface;
576- return QVariant::fromValue(surface);
577+ if (role == WindowRole) {
578+ unityapi::WindowInterface *window = m_windowModel.at(index.row()).window;
579+ return QVariant::fromValue(window);
580 } else if (role == ApplicationRole) {
581 return QVariant::fromValue(m_windowModel.at(index.row()).application);
582- } else if (role == IdRole) {
583- return QVariant::fromValue(m_windowModel.at(index.row()).id);
584 } else {
585 return QVariant();
586 }
587@@ -454,8 +461,9 @@
588 {
589 auto window = needle.window();
590 Q_FOREACH(const auto entry, m_windowModel) {
591- if (entry.surface && entry.surface->window() == window) {
592- return entry.surface;
593+ auto surface = static_cast<MirSurface*>(entry.window->surface());
594+ if (surface && surface->window() == window) {
595+ return surface;
596 }
597 }
598 return nullptr;
599@@ -464,7 +472,8 @@
600 int TopLevelWindowModel::findIndexOf(const miral::Window &needle) const
601 {
602 for (int i=0; i<m_windowModel.count(); i++) {
603- if (m_windowModel[i].surface && m_windowModel[i].surface->window() == needle) {
604+ auto surface = static_cast<MirSurface*>(m_windowModel[i].window->surface());
605+ if (surface && surface->window() == needle) {
606 return i;
607 }
608 }
609@@ -501,8 +510,8 @@
610 QString itemStr = QString("(index=%1,appId=%2,surface=0x%3,id=%4)")
611 .arg(i)
612 .arg(item.application->appId())
613- .arg((qintptr)item.surface, 0, 16)
614- .arg(item.id);
615+ .arg((qintptr)item.window->surface(), 0, 16)
616+ .arg(item.window->id());
617
618 if (i > 0) {
619 str.append(",");
620@@ -515,7 +524,7 @@
621 int TopLevelWindowModel::indexOf(MirSurfaceInterface *surface)
622 {
623 for (int i = 0; i < m_windowModel.count(); ++i) {
624- if (m_windowModel.at(i).surface == surface) {
625+ if (m_windowModel.at(i).window->surface() == surface) {
626 return i;
627 }
628 }
629@@ -525,17 +534,26 @@
630 int TopLevelWindowModel::indexForId(int id) const
631 {
632 for (int i = 0; i < m_windowModel.count(); ++i) {
633- if (m_windowModel[i].id == id) {
634+ if (m_windowModel[i].window->id() == id) {
635 return i;
636 }
637 }
638 return -1;
639 }
640
641+unityapi::WindowInterface *TopLevelWindowModel::windowAt(int index) const
642+{
643+ if (index >=0 && index < m_windowModel.count()) {
644+ return m_windowModel[index].window;
645+ } else {
646+ return nullptr;
647+ }
648+}
649+
650 unityapi::MirSurfaceInterface *TopLevelWindowModel::surfaceAt(int index) const
651 {
652 if (index >=0 && index < m_windowModel.count()) {
653- return m_windowModel[index].surface;
654+ return m_windowModel[index].window->surface();
655 } else {
656 return nullptr;
657 }
658@@ -553,7 +571,7 @@
659 int TopLevelWindowModel::idAt(int index) const
660 {
661 if (index >=0 && index < m_windowModel.count()) {
662- return m_windowModel[index].id;
663+ return m_windowModel[index].window->id();
664 } else {
665 return 0;
666 }
667@@ -579,29 +597,53 @@
668 {
669 int fromIndex = indexForId(id);
670 if (fromIndex != -1) {
671- auto surface = m_windowModel[fromIndex].surface;
672+ auto surface = static_cast<MirSurface*>(m_windowModel[fromIndex].window->surface());
673 if (surface) {
674 m_windowController->raise(surface->window());
675 } else {
676 // move it ourselves. Since there's no mir::scene::Surface/miral::Window, there's nothing
677 // miral can do about it.
678- move(fromIndex, m_windowModel.count() - 1);
679- }
680- }
681-}
682-
683-void TopLevelWindowModel::setFocusedSurface(MirSurface *surface)
684-{
685- if (surface != m_focusedSurface) {
686- DEBUG_MSG << "(" << surface << ")";
687- m_focusedSurface = surface;
688- Q_EMIT focusedSurfaceChanged(m_focusedSurface);
689- }
690-}
691-
692-unityapi::MirSurfaceInterface* TopLevelWindowModel::focusedSurface() const
693-{
694- return m_focusedSurface;
695+ move(fromIndex, 0);
696+ }
697+ }
698+}
699+
700+Window *TopLevelWindowModel::findWindowWithSurface(MirSurface *surface)
701+{
702+ for (int i = 0; i < m_windowModel.count(); ++i) {
703+ Window *window = m_windowModel[i].window;
704+ if (window->surface() == surface) {
705+ return window;
706+ }
707+ }
708+ return nullptr;
709+}
710+
711+void TopLevelWindowModel::setFocusedWindow(Window *window)
712+{
713+ if (window != m_focusedWindow) {
714+ DEBUG_MSG << "(" << window << ")";
715+
716+ Window* previousWindow = m_focusedWindow;
717+
718+ m_focusedWindow = window;
719+ Q_EMIT focusedWindowChanged(m_focusedWindow);
720+
721+ if (previousWindow && previousWindow->focused() && !previousWindow->surface()) {
722+ // do it ourselves. miral doesn't know about this window
723+ previousWindow->setFocused(false);
724+ }
725+ }
726+}
727+
728+unityapi::MirSurfaceInterface* TopLevelWindowModel::inputMethodSurface() const
729+{
730+ return m_inputMethodWindow ? m_inputMethodWindow->surface() : nullptr;
731+}
732+
733+unityapi::WindowInterface* TopLevelWindowModel::focusedWindow() const
734+{
735+ return m_focusedWindow;
736 }
737
738 void TopLevelWindowModel::move(int from, int to)
739@@ -619,11 +661,30 @@
740 m_modelState = MovingState;
741
742 beginMoveRows(parent, from, from, parent, to + (to > from ? 1 : 0));
743+#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
744+ const auto &window = m_windowModel.takeAt(from);
745+ m_windowModel.insert(to, window);
746+#else
747 m_windowModel.move(from, to);
748+#endif
749 endMoveRows();
750
751+ Q_EMIT listChanged();
752 m_modelState = IdleState;
753
754 DEBUG_MSG << " after " << toString();
755 }
756 }
757+void TopLevelWindowModel::onModificationsStarted()
758+{
759+}
760+
761+void TopLevelWindowModel::onModificationsEnded()
762+{
763+ if (m_focusedWindowChanged) {
764+ setFocusedWindow(m_newlyFocusedWindow);
765+ }
766+ // reset
767+ m_focusedWindowChanged = false;
768+ m_newlyFocusedWindow = nullptr;
769+}
770
771=== modified file 'miral-qt/src/modules/Unity/Application/toplevelwindowmodel.h'
772--- miral-qt/src/modules/Unity/Application/toplevelwindowmodel.h 2016-10-06 21:13:42 +0000
773+++ miral-qt/src/modules/Unity/Application/toplevelwindowmodel.h 2016-11-03 12:11:13 +0000
774@@ -17,12 +17,15 @@
775 #ifndef TOPLEVELWINDOWMODEL_H
776 #define TOPLEVELWINDOWMODEL_H
777
778-#include <QAbstractListModel>
779 #include <QLoggingCategory>
780
781 #include "mirsurface.h"
782+#include "window.h"
783 #include "windowmodelnotifier.h"
784
785+// Unity API
786+#include <unity/shell/application/TopLevelWindowModelInterface.h>
787+
788 Q_DECLARE_LOGGING_CATEGORY(QTMIR_TOPLEVELWINDOWMODEL)
789
790 namespace unity {
791@@ -37,97 +40,39 @@
792
793 namespace qtmir {
794
795+class Application;
796 class ApplicationManagerInterface;
797 class SessionManager;
798 class WindowControllerInterface;
799
800-// TODO: Define an interface in unityapi
801-class TopLevelWindowModel : public QAbstractListModel
802+class TopLevelWindowModel : public unity::shell::application::TopLevelWindowModelInterface
803 {
804 Q_OBJECT
805
806- Q_PROPERTY(int count READ count NOTIFY countChanged)
807-
808- Q_PROPERTY(unity::shell::application::MirSurfaceInterface* inputMethodSurface READ inputMethodSurface NOTIFY inputMethodSurfaceChanged)
809-
810- Q_PROPERTY(unity::shell::application::MirSurfaceInterface* focusedSurface READ focusedSurface
811- NOTIFY focusedSurfaceChanged)
812-
813 public:
814- /**
815- * @brief The Roles supported by the model
816- *
817- * SurfaceRole - A MirSurfaceInterface. It will be null if the application is still starting up
818- * ApplicationRole - An ApplicationInfoInterface
819- * IdRole - A unique identifier for this entry. Useful to unambiguosly track elements as they move around in the list
820- */
821- enum Roles {
822- SurfaceRole = Qt::UserRole,
823- ApplicationRole = Qt::UserRole + 1,
824- IdRole = Qt::UserRole + 2,
825- };
826-
827 TopLevelWindowModel();
828 explicit TopLevelWindowModel(WindowModelNotifier *notifier,
829 WindowControllerInterface *controller); // For testing
830
831- // QAbstractItemModel methods
832+ // From unity::shell::application::TopLevelWindowModelInterface
833+ unity::shell::application::MirSurfaceInterface* inputMethodSurface() const override;
834+ unity::shell::application::WindowInterface* focusedWindow() const override;
835+
836+ // From QAbstractItemModel
837 int rowCount(const QModelIndex &parent = QModelIndex()) const override;
838 QVariant data(const QModelIndex& index, int role) const override;
839
840- QHash<int, QByteArray> roleNames() const override;
841-
842- int count() const { return rowCount(); }
843-
844- unity::shell::application::MirSurfaceInterface* inputMethodSurface() const { return m_inputMethodSurface; }
845-
846- unity::shell::application::MirSurfaceInterface* focusedSurface() const;
847-
848+ // Own API
849 void setApplicationManager(ApplicationManagerInterface*);
850
851 public Q_SLOTS:
852- /**
853- * @brief Returns the surface at the given index
854- *
855- * It will be a nullptr if the application is still starting up and thus hasn't yet created
856- * and drawn into a surface.
857- */
858- unity::shell::application::MirSurfaceInterface *surfaceAt(int index) const;
859-
860- /**
861- * @brief Returns the application at the given index
862- */
863- unity::shell::application::ApplicationInfoInterface *applicationAt(int index) const;
864-
865- /**
866- * @brief Returns the unique id of the element at the given index
867- */
868- int idAt(int index) const;
869-
870- /**
871- * @brief Returns the index where the row with the given id is located
872- *
873- * Returns -1 if there's no row with the given id.
874- */
875- int indexForId(int id) const;
876-
877- /**
878- * @brief Raises the row with the given id to the top of the window stack (index == count-1)
879- */
880- void raiseId(int id);
881-
882-Q_SIGNALS:
883- void countChanged();
884- void inputMethodSurfaceChanged(unity::shell::application::MirSurfaceInterface* inputMethodSurface);
885-
886- /**
887- * @brief Emitted when the list changes
888- *
889- * Emitted when model gains an element, loses an element or when elements exchange positions.
890- */
891- void listChanged();
892-
893- void focusedSurfaceChanged(unity::shell::application::MirSurfaceInterface *focusedSurface);
894+ // From unity::shell::application::TopLevelWindowModelInterface
895+ unity::shell::application::MirSurfaceInterface *surfaceAt(int index) const override;
896+ unity::shell::application::WindowInterface *windowAt(int index) const override;
897+ unity::shell::application::ApplicationInfoInterface *applicationAt(int index) const override;
898+ int idAt(int index) const override;
899+ int indexForId(int id) const override;
900+ void raiseId(int id) override;
901
902 private Q_SLOTS:
903 void onWindowAdded(const qtmir::NewWindow &windowInfo);
904@@ -137,6 +82,8 @@
905 void onWindowStateChanged(const miral::WindowInfo &windowInfo, Mir::State state);
906 void onWindowFocusChanged(const miral::WindowInfo &windowInfo, bool focused);
907 void onWindowsRaised(const std::vector<miral::Window> &windows);
908+ void onModificationsStarted();
909+ void onModificationsEnded();
910
911 private:
912 void doRaiseId(int id);
913@@ -146,22 +93,22 @@
914 QString toString();
915 int indexOf(MirSurfaceInterface *surface);
916
917- void setInputMethodWindow(MirSurface *surface);
918- void setFocusedSurface(MirSurface *surface);
919+ void setInputMethodWindow(Window *window);
920+ Window *findWindowWithSurface(MirSurface *surface);
921+ void setFocusedWindow(Window *window);
922 void removeInputMethodWindow();
923 MirSurface* find(const miral::WindowInfo &needle) const;
924 int findIndexOf(const miral::Window &needle) const;
925 void removeAt(int index);
926
927- void addApplication(unity::shell::application::ApplicationInfoInterface *application);
928- void removeApplication(unity::shell::application::ApplicationInfoInterface *application);
929-
930- void appendPlaceholder(unity::shell::application::ApplicationInfoInterface *application);
931- void appendSurface(MirSurface *surface,
932- unity::shell::application::ApplicationInfoInterface *application);
933- void appendSurfaceHelper(MirSurface *surface,
934- unity::shell::application::ApplicationInfoInterface *application);
935-
936+ void addApplication(Application *application);
937+ void removeApplication(Application *application);
938+
939+ void prependPlaceholder(Application *application);
940+ void prependSurface(MirSurface *surface, Application *application);
941+ void prependSurfaceHelper(MirSurface *surface, Application *application);
942+
943+ void connectWindow(Window *window);
944 void connectSurface(MirSurfaceInterface *surface);
945
946 void onSurfaceDied(MirSurfaceInterface *surface);
947@@ -171,21 +118,19 @@
948
949 struct ModelEntry {
950 ModelEntry() {}
951- ModelEntry(MirSurface *surface,
952- unity::shell::application::ApplicationInfoInterface *application,
953- int id)
954- : surface(surface), application(application), id(id) {}
955- MirSurface *surface{nullptr};
956- unity::shell::application::ApplicationInfoInterface *application{nullptr};
957- int id{-1};
958+ ModelEntry(Window *window,
959+ Application *application)
960+ : window(window), application(application) {}
961+ Window *window{nullptr};
962+ Application *application{nullptr};
963 bool removeOnceSurfaceDestroyed{false};
964 };
965
966 QVector<ModelEntry> m_windowModel;
967 WindowControllerInterface *m_windowController;
968 SessionManager* m_sessionManager;
969- MirSurface* m_inputMethodSurface{nullptr};
970- MirSurface* m_focusedSurface{nullptr};
971+ Window* m_inputMethodWindow{nullptr};
972+ Window* m_focusedWindow{nullptr};
973 int m_nextId{1};
974 // Just something big enough that we don't risk running out of unused id numbers.
975 // Not sure if QML int type supports something close to std::numeric_limits<int>::max() and
976@@ -202,6 +147,10 @@
977 ResettingState
978 };
979 ModelState m_modelState{IdleState};
980+
981+ // Valid between modificationsStarted and modificationsEnded
982+ bool m_focusedWindowChanged{false};
983+ Window *m_newlyFocusedWindow{nullptr};
984 };
985
986 } // namespace qtmir
987
988=== added file 'miral-qt/src/modules/Unity/Application/window.cpp'
989--- miral-qt/src/modules/Unity/Application/window.cpp 1970-01-01 00:00:00 +0000
990+++ miral-qt/src/modules/Unity/Application/window.cpp 2016-11-03 12:11:13 +0000
991@@ -0,0 +1,190 @@
992+/*
993+ * Copyright (C) 2016 Canonical, Ltd.
994+ *
995+ * This program is free software; you can redistribute it and/or modify
996+ * it under the terms of the GNU General Public License as published by
997+ * the Free Software Foundation; version 3.
998+ *
999+ * This program is distributed in the hope that it will be useful,
1000+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1001+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1002+ * GNU General Public License for more details.
1003+ *
1004+ * You should have received a copy of the GNU General Public License
1005+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1006+ */
1007+
1008+#include "window.h"
1009+#include "mirsurface.h"
1010+
1011+#include <QQmlEngine>
1012+
1013+namespace unityapi = unity::shell::application;
1014+using namespace qtmir;
1015+
1016+Window::Window(int id)
1017+ : WindowInterface(nullptr)
1018+ , m_id(id)
1019+{
1020+ QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
1021+}
1022+
1023+QPoint Window::position() const
1024+{
1025+ return m_position;
1026+}
1027+
1028+QPoint Window::requestedPosition() const
1029+{
1030+ return m_requestedPosition;
1031+}
1032+
1033+void Window::setRequestedPosition(const QPoint &value)
1034+{
1035+ if (value != m_requestedPosition) {
1036+ m_requestedPosition = value;
1037+ Q_EMIT requestedPositionChanged(m_requestedPosition);
1038+ if (m_surface) {
1039+ m_surface->setRequestedPosition(value);
1040+ } else {
1041+ // fake-miral: always comply
1042+ m_position = m_requestedPosition;
1043+ Q_EMIT positionChanged(m_position);
1044+ }
1045+ }
1046+}
1047+
1048+Mir::State Window::state() const
1049+{
1050+ return m_state;
1051+}
1052+
1053+bool Window::focused() const
1054+{
1055+ return m_focused;
1056+}
1057+
1058+bool Window::confinesMousePointer() const
1059+{
1060+ if (m_surface) {
1061+ return m_surface->confinesMousePointer();
1062+ } else {
1063+ return false;
1064+ }
1065+}
1066+
1067+int Window::id() const
1068+{
1069+ return m_id;
1070+}
1071+
1072+unityapi::MirSurfaceInterface* Window::surface() const
1073+{
1074+ return m_surface;
1075+}
1076+
1077+void Window::requestState(Mir::State state)
1078+{
1079+ if (m_surface) {
1080+ m_surface->requestState(state);
1081+ } else if (m_state != state) {
1082+ m_state = state;
1083+ Q_EMIT stateChanged(m_state);
1084+ }
1085+}
1086+
1087+void Window::requestFocus()
1088+{
1089+ if (m_surface) {
1090+ m_surface->requestFocus();
1091+ } else {
1092+ Q_EMIT focusRequested();
1093+ }
1094+}
1095+
1096+void Window::close()
1097+{
1098+ if (m_surface) {
1099+ m_surface->close();
1100+ } else {
1101+ Q_EMIT closeRequested();
1102+ }
1103+}
1104+
1105+void Window::setSurface(MirSurface *surface)
1106+{
1107+ if (m_surface) {
1108+ disconnect(m_surface, 0, this, 0);
1109+ }
1110+
1111+ m_surface = surface;
1112+
1113+ if (m_surface) {
1114+ connect(surface, &MirSurfaceInterface::focusRequested, this, [this]() {
1115+ Q_EMIT focusRequested();
1116+ });
1117+
1118+ connect(surface, &MirSurfaceInterface::closeRequested, this, &Window::closeRequested);
1119+
1120+ connect(surface, &MirSurfaceInterface::positionChanged, this, [this]() {
1121+ updatePosition();
1122+ });
1123+
1124+ connect(surface, &MirSurfaceInterface::stateChanged, this, [this]() {
1125+ updateState();
1126+ });
1127+
1128+ connect(surface, &MirSurfaceInterface::focusedChanged, this, [this]() {
1129+ updateFocused();
1130+ });
1131+
1132+ // QPointer is based on QWeakPointer which will be cleared only on QObject destructor (according to docs).
1133+ // We don't want that. MirSurface emits detroyed() early on
1134+ connect(surface, &QObject::destroyed, this, [this, surface](){ setSurface(nullptr); });
1135+
1136+ // bring it up to speed
1137+ m_surface->setRequestedPosition(m_requestedPosition);
1138+ m_surface->requestState(m_state);
1139+
1140+ // and sync with surface
1141+ updatePosition();
1142+ updateState();
1143+ updateFocused();
1144+ }
1145+
1146+ Q_EMIT surfaceChanged(surface);
1147+}
1148+
1149+void Window::updatePosition()
1150+{
1151+ if (m_surface->position() != m_position) {
1152+ m_position = m_surface->position();
1153+ Q_EMIT positionChanged(m_position);
1154+ }
1155+}
1156+
1157+void Window::updateState()
1158+{
1159+ if (m_surface->state() != m_state) {
1160+ m_state = m_surface->state();
1161+ Q_EMIT stateChanged(m_state);
1162+ }
1163+}
1164+
1165+void Window::updateFocused()
1166+{
1167+ if (m_surface->focused() != m_focused) {
1168+ m_focused = m_surface->focused();
1169+ Q_EMIT focusedChanged(m_focused);
1170+ }
1171+}
1172+
1173+void Window::setFocused(bool value)
1174+{
1175+ if (value != m_focused) {
1176+ m_focused = value;
1177+ Q_EMIT focusedChanged(m_focused);
1178+ // when we have a surface we get focus changes from updateFocused() instead
1179+ Q_ASSERT(!m_surface);
1180+ }
1181+}
1182
1183=== added file 'miral-qt/src/modules/Unity/Application/window.h'
1184--- miral-qt/src/modules/Unity/Application/window.h 1970-01-01 00:00:00 +0000
1185+++ miral-qt/src/modules/Unity/Application/window.h 2016-11-03 12:11:13 +0000
1186@@ -0,0 +1,67 @@
1187+/*
1188+ * Copyright (C) 2016 Canonical, Ltd.
1189+ *
1190+ * This program is free software; you can redistribute it and/or modify
1191+ * it under the terms of the GNU General Public License as published by
1192+ * the Free Software Foundation; version 3.
1193+ *
1194+ * This program is distributed in the hope that it will be useful,
1195+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1196+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1197+ * GNU General Public License for more details.
1198+ *
1199+ * You should have received a copy of the GNU General Public License
1200+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1201+ */
1202+
1203+#ifndef QTMIR_WINDOW_H
1204+#define QTMIR_WINDOW_H
1205+
1206+// unity-api
1207+#include <unity/shell/application/WindowInterface.h>
1208+
1209+namespace qtmir {
1210+
1211+class MirSurface;
1212+
1213+class Window : public unity::shell::application::WindowInterface
1214+{
1215+ Q_OBJECT
1216+
1217+public:
1218+ Window(int id);
1219+ QPoint position() const override;
1220+ QPoint requestedPosition() const override;
1221+ void setRequestedPosition(const QPoint &) override;
1222+ Mir::State state() const override;
1223+ bool focused() const override;
1224+ bool confinesMousePointer() const override;
1225+ int id() const override;
1226+ unity::shell::application::MirSurfaceInterface* surface() const override;
1227+
1228+ void setSurface(MirSurface *surface);
1229+ void setFocused(bool value);
1230+
1231+public Q_SLOTS:
1232+ void requestState(Mir::State state) override;
1233+ void requestFocus() override;
1234+ void close() override;
1235+
1236+Q_SIGNALS:
1237+ void closeRequested();
1238+
1239+private:
1240+ void updatePosition();
1241+ void updateState();
1242+ void updateFocused();
1243+
1244+ QPoint m_position;
1245+ QPoint m_requestedPosition;
1246+ bool m_focused{false};
1247+ int m_id;
1248+ Mir::State m_state{Mir::RestoredState};
1249+ MirSurface *m_surface{nullptr};
1250+};
1251+
1252+} // namespace qtmir {
1253+#endif // QTMIR_WINDOW_H
1254
1255=== modified file 'miral-qt/src/platforms/mirserver/windowmanagementpolicy.cpp'
1256--- miral-qt/src/platforms/mirserver/windowmanagementpolicy.cpp 2016-11-01 10:28:07 +0000
1257+++ miral-qt/src/platforms/mirserver/windowmanagementpolicy.cpp 2016-11-03 12:11:13 +0000
1258@@ -192,12 +192,12 @@
1259
1260 void WindowManagementPolicy::advise_begin()
1261 {
1262- // TODO
1263+ Q_EMIT m_windowModel.modificationsStarted();
1264 }
1265
1266 void WindowManagementPolicy::advise_end()
1267 {
1268- // TODO
1269+ Q_EMIT m_windowModel.modificationsEnded();
1270 }
1271
1272 /* Following methods all called from the Qt GUI thread to deliver events to clients */
1273@@ -248,13 +248,15 @@
1274 // raises the window tree and focus it.
1275 void WindowManagementPolicy::activate(const miral::Window &window)
1276 {
1277- auto &windowInfo = m_tools.info_for(window);
1278+ if (window) {
1279+ auto &windowInfo = m_tools.info_for(window);
1280
1281- // restore from minimized if needed
1282- if (windowInfo.state() == mir_surface_state_minimized) {
1283- auto extraInfo = getExtraInfo(windowInfo);
1284- Q_ASSERT(extraInfo->previousState != Mir::MinimizedState);
1285- requestState(window, extraInfo->previousState);
1286+ // restore from minimized if needed
1287+ if (windowInfo.state() == mir_surface_state_minimized) {
1288+ auto extraInfo = getExtraInfo(windowInfo);
1289+ Q_ASSERT(extraInfo->previousState != Mir::MinimizedState);
1290+ requestState(window, extraInfo->previousState);
1291+ }
1292 }
1293
1294 m_tools.invoke_under_lock([&]() {

Subscribers

People subscribed via source and target branches