Lomiri
Workspace.cpp
1 /*
2  * Copyright (C) 2017 Canonical Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 3.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #include "Workspace.h"
18 #include "WorkspaceModel.h"
19 #include "WorkspaceManager.h"
20 #include "TopLevelWindowModel.h"
21 #include "Screen.h"
22 
23 #include "wmpolicyinterface.h"
24 
25 int nextWorkspace = 0;
26 
27 Workspace::Workspace(QObject *parent)
28  : QObject(parent)
29  , m_workspace(WMPolicyInterface::instance()->createWorkspace())
30  , m_model(nullptr)
31 {
32  setObjectName((QString("Wks%1").arg(nextWorkspace++)));
33 }
34 
35 Workspace::Workspace(const Workspace &other)
36  : QObject(nullptr)
37  , m_workspace(other.m_workspace)
38  , m_model(nullptr)
39 {
40  setObjectName(other.objectName());
41 
42  connect(&other, &Workspace::activeChanged, this, &Workspace::activeChanged);
43 }
44 
45 Workspace::~Workspace()
46 {
47  if (m_model) {
48  m_model->remove(this);
49  }
50 }
51 
52 void Workspace::assign(WorkspaceModel *model, const QVariant& vIndex)
53 {
54  if (m_model == model) return;
55 
56  if (m_model) {
57  disconnect(m_model, 0, this, 0);
58  m_model->remove(this);
59  }
60 
61  m_model = model;
62 
63  if (model) {
64  int index = m_model->rowCount();
65  if (vIndex.isValid() && vIndex.canConvert(QVariant::Int)) {
66  index = vIndex.toInt();
67  }
68  m_model->insert(index, this);
69 
70  connect(m_model, &QObject::destroyed, this, [this]() {
71  m_model = nullptr;
72  Q_EMIT unassigned();
73  });
74  Q_EMIT assigned();
75  } else {
76  Q_EMIT unassigned();
77  }
78 }
79 
80 void Workspace::unassign()
81 {
82  assign(nullptr);
83 }
84 
85 bool Workspace::isAssigned() const
86 {
87  return m_model != nullptr;
88 }
89 
90 bool Workspace::isSameAs(Workspace *wks) const
91 {
92  if (!wks) return false;
93  if (wks == this) return true;
94  return wks->workspace() == workspace();
95 }
96 
97 
98 ConcreteWorkspace::ConcreteWorkspace(QObject *parent)
99  : Workspace(parent)
100  , m_active(false)
101  , m_windowModel(new TopLevelWindowModel(this))
102 {
103  connect(WorkspaceManager::instance(), &WorkspaceManager::activeWorkspaceChanged, this, [this](Workspace* activeWorkspace) {
104  bool newActive = activeWorkspace == this;
105  if (newActive != m_active) {
106  m_active = newActive;
107  Q_EMIT activeChanged(m_active);
108 
109  if (m_active) {
110  WMPolicyInterface::instance()->setActiveWorkspace(m_workspace);
111  }
112  }
113  });
114 }
115 
116 ConcreteWorkspace::~ConcreteWorkspace()
117 {
118  WorkspaceManager::instance()->destroyWorkspace(this);
119  WMPolicyInterface::instance()->releaseWorkspace(m_workspace);
120 }
121 
122 TopLevelWindowModel *ConcreteWorkspace::windowModel() const
123 {
124  return m_windowModel.data();
125 }
126 
127 void ConcreteWorkspace::activate()
128 {
129  WorkspaceManager::instance()->setActiveWorkspace(this);
130 }
131 
132 void ConcreteWorkspace::setCurrentOn(Screen *screen)
133 {
134  if (screen) {
135  screen->setCurrentWorkspace(this);
136  }
137 }
138 
139 
140 ProxyWorkspace::ProxyWorkspace(Workspace * const workspace)
141  : Workspace(*workspace)
142  , m_original(workspace)
143 {
144 }
145 
146 void ProxyWorkspace::assign(WorkspaceModel *model, const QVariant &index)
147 {
148  Workspace::assign(model, index);
149 }
150 
151 void ProxyWorkspace::unassign()
152 {
153  Workspace::unassign();
154 }
155 
156 bool ProxyWorkspace::isActive() const
157 {
158  return m_original ? m_original->isActive() : false;
159 }
160 
161 TopLevelWindowModel *ProxyWorkspace::windowModel() const
162 {
163  return m_original ? m_original->windowModel() : nullptr;
164 }
165 
166 void ProxyWorkspace::activate()
167 {
168  if (m_original) {
169  m_original->activate();
170  }
171 }
172 
173 void ProxyWorkspace::setCurrentOn(Screen *screen)
174 {
175  if (screen && m_original) {
176  screen->setCurrentWorkspace(m_original);
177  }
178 }
TopLevelWindowModel
A model of top-level surfaces.
Definition: TopLevelWindowModel.h:59