Lomiri
TopLevelWindowModel.h
1 /*
2  * Copyright (C) 2016-2017 Canonical Ltd.
3  * Copyright 2019 UBports Foundation
4  *
5  * This program is free software: you can redistribute it and/or modify it under
6  * the terms of the GNU Lesser General Public License version 3, as published by
7  * the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
11  * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef TOPLEVELWINDOWMODEL_H
19 #define TOPLEVELWINDOWMODEL_H
20 
21 #include <QAbstractListModel>
22 #include <QAtomicInteger>
23 #include <QLoggingCategory>
24 
25 #include <memory>
26 
27 #include "WindowManagerGlobal.h"
28 
29 Q_DECLARE_LOGGING_CATEGORY(TOPLEVELWINDOWMODEL)
30 
31 class Window;
32 class Workspace;
33 
34 namespace miral { class Workspace; }
35 
36 namespace lomiri {
37  namespace shell {
38  namespace application {
39  class ApplicationInfoInterface;
40  class ApplicationManagerInterface;
41  class MirSurfaceInterface;
42  class SurfaceManagerInterface;
43  }
44  }
45 }
46 
59 class WINDOWMANAGERQML_EXPORT TopLevelWindowModel : public QAbstractListModel
60 {
61  Q_OBJECT
62 
68  Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
69 
70 
75  Q_PROPERTY(lomiri::shell::application::MirSurfaceInterface* inputMethodSurface READ inputMethodSurface NOTIFY inputMethodSurfaceChanged)
76 
80  Q_PROPERTY(Window* focusedWindow READ focusedWindow NOTIFY focusedWindowChanged)
81 
86  Q_PROPERTY(int nextId READ nextId)
87 
88 
107  Q_PROPERTY(bool rootFocus READ rootFocus WRITE setRootFocus NOTIFY rootFocusChanged)
108 
109 public:
116  enum Roles {
117  WindowRole = Qt::UserRole,
118  ApplicationRole = Qt::UserRole + 1,
119  };
120 
121  TopLevelWindowModel(Workspace* workspace);
123 
124  // From QAbstractItemModel
125  int rowCount(const QModelIndex &parent = QModelIndex()) const override;
126  QVariant data(const QModelIndex& index, int role) const override;
127  QHash<int, QByteArray> roleNames() const override {
128  QHash<int, QByteArray> roleNames { {WindowRole, "window"},
129  {ApplicationRole, "application"} };
130  return roleNames;
131  }
132 
133  // Own API;
134 
135  lomiri::shell::application::MirSurfaceInterface* inputMethodSurface() const;
136  Window* focusedWindow() const;
137 
138 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
139  int nextId() const { return m_nextId.loadRelaxed(); }
140 #else
141  int nextId() const { return m_nextId.load(); }
142 #endif
143 
144 public:
153  Q_INVOKABLE lomiri::shell::application::MirSurfaceInterface *surfaceAt(int index) const;
154 
160  Q_INVOKABLE Window *windowAt(int index) const;
161 
165  Q_INVOKABLE lomiri::shell::application::ApplicationInfoInterface *applicationAt(int index) const;
166 
170  Q_INVOKABLE int idAt(int index) const;
171 
177  Q_INVOKABLE int indexForId(int id) const;
178 
182  Q_INVOKABLE void raiseId(int id);
183 
187  Q_INVOKABLE void closeAllWindows();
188 
192  Q_INVOKABLE void pendingActivation();
193 
194  void setApplicationManager(lomiri::shell::application::ApplicationManagerInterface*);
195  void setSurfaceManager(lomiri::shell::application::SurfaceManagerInterface*);
196  void setRootFocus(bool focus);
197  bool rootFocus();
198 
199 Q_SIGNALS:
200  void countChanged();
201  void inputMethodSurfaceChanged(lomiri::shell::application::MirSurfaceInterface* inputMethodSurface);
202  void focusedWindowChanged(Window *focusedWindow);
203 
209  void listChanged();
210 
211  void closedAllWindows();
212 
213  void rootFocusChanged();
214 
215 private Q_SLOTS:
216  void onSurfacesAddedToWorkspace(const std::shared_ptr<miral::Workspace>& workspace,
217  const QVector<lomiri::shell::application::MirSurfaceInterface*> surfaces);
218  void onSurfacesRaised(const QVector<lomiri::shell::application::MirSurfaceInterface*> &surfaces);
219 
220  void onModificationsStarted();
221  void onModificationsEnded();
222 
223 private:
224  void doRaiseId(int id);
225  int generateId();
226  int nextFreeId(int candidateId, const int latestId);
227  int nextId(int id) const;
228  QString toString();
229  int indexOf(lomiri::shell::application::MirSurfaceInterface *surface);
230 
231  void setInputMethodWindow(Window *window);
232  void setFocusedWindow(Window *window);
233  void removeInputMethodWindow();
234  void deleteAt(int index);
235  void removeAt(int index);
236  void removeSurfaces(const QVector<lomiri::shell::application::MirSurfaceInterface *> surfaces);
237 
238  void addApplication(lomiri::shell::application::ApplicationInfoInterface *application);
239  void removeApplication(lomiri::shell::application::ApplicationInfoInterface *application);
240 
241  void prependPlaceholder(lomiri::shell::application::ApplicationInfoInterface *application);
242  void prependSurface(lomiri::shell::application::MirSurfaceInterface *surface,
243  lomiri::shell::application::ApplicationInfoInterface *application);
244  void prependSurfaceHelper(lomiri::shell::application::MirSurfaceInterface *surface,
245  lomiri::shell::application::ApplicationInfoInterface *application);
246  void prependWindow(Window *window, lomiri::shell::application::ApplicationInfoInterface *application);
247 
248  void connectWindow(Window *window);
249  void connectSurface(lomiri::shell::application::MirSurfaceInterface *surface);
250 
251  void onSurfaceDied(lomiri::shell::application::MirSurfaceInterface *surface);
252  void onSurfaceDestroyed(lomiri::shell::application::MirSurfaceInterface *surface);
253 
254  void move(int from, int to);
255 
256  void activateEmptyWindow(Window *window);
257 
258  void activateTopMostWindowWithoutId(int forbiddenId);
259  void refreshWindows();
260  void clear();
261 
262  Window *createWindow(lomiri::shell::application::MirSurfaceInterface *surface);
263  Window *createWindowWithId(lomiri::shell::application::MirSurfaceInterface *surface, int id);
264  Window *createNullWindow();
265 
266  struct ModelEntry {
267  ModelEntry() {}
268  ModelEntry(Window *window,
269  lomiri::shell::application::ApplicationInfoInterface *application)
270  : window(window), application(application) {}
271  Window *window{nullptr};
272  lomiri::shell::application::ApplicationInfoInterface *application{nullptr};
273  bool removeOnceSurfaceDestroyed{false};
274  };
275 
276  QVector<ModelEntry> m_windowModel;
277  Window* m_inputMethodWindow{nullptr};
278  Window* m_focusedWindow{nullptr};
279  Window* m_nullWindow;
280  Workspace* m_workspace{nullptr};
281  // track all the surfaces we've been told about.
282  QSet<lomiri::shell::application::MirSurfaceInterface*> m_allSurfaces;
283  Window* m_previousWindow{nullptr};
284  bool m_pendingActivation;
285 
286  QAtomicInteger<int> m_nextId{1};
287 
288  lomiri::shell::application::ApplicationManagerInterface* m_applicationManager{nullptr};
289  lomiri::shell::application::SurfaceManagerInterface *m_surfaceManager{nullptr};
290  bool m_surfaceManagerBusy;
291 
292  enum ModelState {
293  IdleState,
294  InsertingState,
295  RemovingState,
296  MovingState,
297  ResettingState
298  };
299  ModelState m_modelState{IdleState};
300 
301  // Valid between modificationsStarted and modificationsEnded
302  bool m_focusedWindowCleared{false};
303 
304  bool m_closingAllApps{false};
305 };
306 
307 #endif // TOPLEVELWINDOWMODEL_H
TopLevelWindowModel::Roles
Roles
The Roles supported by the model.
Definition: TopLevelWindowModel.h:116
Window
A slightly higher concept than MirSurface.
Definition: Window.h:47
TopLevelWindowModel
A model of top-level surfaces.
Definition: TopLevelWindowModel.h:59