@@ -15,163 +15,190 @@
1515 */
1616
1717#include "Screen.h"
18+#include "Screens.h"
1819#include "WorkspaceManager.h"
1920#include "Workspace.h"
2021
21−#include <QQmlEngine>
22−
23−Screen::Screen(qtmir::Screen* screen)
24− : m_wrapped(screen)
25− , m_workspaces(new WorkspaceModel)
26−{
27− QQmlEngine::setObjectOwnership(m_workspaces.data(), QQmlEngine::CppOwnership);
28−
29− connect(m_wrapped, &qtmir::Screen::usedChanged, this, &Screen::usedChanged);
30− connect(m_wrapped, &qtmir::Screen::nameChanged, this, &Screen::nameChanged);
31− connect(m_wrapped, &qtmir::Screen::outputTypeChanged, this, &Screen::outputTypeChanged);
32− connect(m_wrapped, &qtmir::Screen::scaleChanged, this, &Screen::scaleChanged);
33− connect(m_wrapped, &qtmir::Screen::formFactorChanged, this, &Screen::formFactorChanged);
34− connect(m_wrapped, &qtmir::Screen::physicalSizeChanged, this, &Screen::physicalSizeChanged);
35− connect(m_wrapped, &qtmir::Screen::positionChanged, this, &Screen::positionChanged);
36− connect(m_wrapped, &qtmir::Screen::activeChanged, this, &Screen::activeChanged);
37− connect(m_wrapped, &qtmir::Screen::currentModeIndexChanged, this, &Screen::currentModeIndexChanged);
38− connect(m_wrapped, &qtmir::Screen::availableModesChanged, this, &Screen::availableModesChanged);
39−
40− // Connect the active workspace to activate the screen.
41− connect(m_workspaces.data(), &WorkspaceModel::workspaceAdded, this, [this](Workspace* workspace) {
42− connect(workspace, &Workspace::activeChanged, this, [this, workspace](bool active) {
43− if (active) {
44− setCurrentWorkspace(workspace);
45− activate();
46− }
47− });
48− if (workspace->isActive()) {
49− activate();
50− setCurrentWorkspace(workspace);
51− }
52− if (!m_currentWorspace) {
53− setCurrentWorkspace(workspace);
54− }
55− });
56− connect(m_workspaces.data(), &WorkspaceModel::workspaceRemoved, this, [this](Workspace* workspace) {
57− disconnect(workspace, &Workspace::activeChanged, this, 0);
58− if (workspace == m_currentWorspace) {
59− resetCurrentWorkspace();
60− }
61− });
62− connect(this, &Screen::activeChanged, this, [this](bool active) {
63− if (active && m_currentWorspace) {
64− m_currentWorspace->activate();
65− }
66− });
67−
68− WorkspaceManager::instance()->createWorkspace()->assign(m_workspaces.data());
69− WorkspaceManager::instance()->createWorkspace()->assign(m_workspaces.data());
70−}
71−
72−Screen::Screen(const Screen &other)
73− : qtmir::Screen(nullptr)
74− , m_wrapped(other.m_wrapped)
75− , m_workspaces(new WorkspaceModelProxy(other.m_workspaces.data()))
22+ScreenInterface::ScreenInterface(QObject *parent)
23+ : QObject(parent)
7624{
77− QQmlEngine::setObjectOwnership(m_workspaces.data(), QQmlEngine::CppOwnership);
78−
79− connect(m_wrapped, &qtmir::Screen::usedChanged, this, &Screen::usedChanged);
80− connect(m_wrapped, &qtmir::Screen::nameChanged, this, &Screen::nameChanged);
81− connect(m_wrapped, &qtmir::Screen::outputTypeChanged, this, &Screen::outputTypeChanged);
82− connect(m_wrapped, &qtmir::Screen::scaleChanged, this, &Screen::scaleChanged);
83− connect(m_wrapped, &qtmir::Screen::formFactorChanged, this, &Screen::formFactorChanged);
84− connect(m_wrapped, &qtmir::Screen::physicalSizeChanged, this, &Screen::physicalSizeChanged);
85− connect(m_wrapped, &qtmir::Screen::positionChanged, this, &Screen::positionChanged);
86− connect(m_wrapped, &qtmir::Screen::activeChanged, this, &Screen::activeChanged);
87− connect(m_wrapped, &qtmir::Screen::currentModeIndexChanged, this, &Screen::currentModeIndexChanged);
88− connect(m_wrapped, &qtmir::Screen::availableModesChanged, this, &Screen::availableModesChanged);
8925}
9026
91−void Screen::resetCurrentWorkspace()
27+void ScreenInterface::connectToScreen(qtmir::Screen *screen)
9228{
93− auto newCurrent = m_workspaces->rowCount() > 0 ? m_workspaces->get(0) : nullptr;
94− if (m_currentWorspace != newCurrent) {
95− m_currentWorspace = newCurrent;
96− Q_EMIT currentWorkspaceChanged(newCurrent);
97− }
29+ m_wrapped = screen;
30+ connect(screen, &qtmir::Screen::usedChanged, this, &ScreenInterface::usedChanged);
31+ connect(screen, &qtmir::Screen::nameChanged, this, &ScreenInterface::nameChanged);
32+ connect(screen, &qtmir::Screen::outputTypeChanged, this, &ScreenInterface::outputTypeChanged);
33+ connect(screen, &qtmir::Screen::scaleChanged, this, &ScreenInterface::scaleChanged);
34+ connect(screen, &qtmir::Screen::formFactorChanged, this, &ScreenInterface::formFactorChanged);
35+ connect(screen, &qtmir::Screen::physicalSizeChanged, this, &ScreenInterface::physicalSizeChanged);
36+ connect(screen, &qtmir::Screen::positionChanged, this, &ScreenInterface::positionChanged);
37+ connect(screen, &qtmir::Screen::activeChanged, this, &ScreenInterface::activeChanged);
38+ connect(screen, &qtmir::Screen::currentModeIndexChanged, this, &ScreenInterface::currentModeIndexChanged);
39+ connect(screen, &qtmir::Screen::availableModesChanged, this, &ScreenInterface::availableModesChanged);
9840}
9941
100−qtmir::OutputId Screen::outputId() const
42+qtmir::OutputId ScreenInterface::outputId() const
10143{
44+ if (!m_wrapped) return qtmir::OutputId(-1);
10245 return m_wrapped->outputId();
10346}
10447
105−bool Screen::used() const
48+bool ScreenInterface::used() const
10649{
50+ if (!m_wrapped) return false;
10751 return m_wrapped->used();
10852}
10953
110−QString Screen::name() const
54+QString ScreenInterface::name() const
11155{
56+ if (!m_wrapped) return QString();
11257 return m_wrapped->name();
11358}
11459
115−float Screen::scale() const
60+float ScreenInterface::scale() const
11661{
62+ if (!m_wrapped) return 1.0;
11763 return m_wrapped->scale();
11864}
11965
120−QSizeF Screen::physicalSize() const
66+QSizeF ScreenInterface::physicalSize() const
12167{
68+ if (!m_wrapped) return QSizeF();
12269 return m_wrapped->physicalSize();
12370}
12471
125−qtmir::FormFactor Screen::formFactor() const
72+qtmir::FormFactor ScreenInterface::formFactor() const
12673{
74+ if (!m_wrapped) return qtmir::FormFactorUnknown;
12775 return m_wrapped->formFactor();
12876}
12977
130−qtmir::OutputTypes Screen::outputType() const
78+qtmir::OutputTypes ScreenInterface::outputType() const
13179{
80+ if (!m_wrapped) return qtmir::Unknown;
13281 return m_wrapped->outputType();
13382}
13483
135−MirPowerMode Screen::powerMode() const
84+MirPowerMode ScreenInterface::powerMode() const
13685{
86+ if (!m_wrapped) return mir_power_mode_on;
13787 return m_wrapped->powerMode();
13888}
13989
140−Qt::ScreenOrientation Screen::orientation() const
90+Qt::ScreenOrientation ScreenInterface::orientation() const
14191{
92+ if (!m_wrapped) return Qt::PrimaryOrientation;
14293 return m_wrapped->orientation();
14394}
14495
145−QPoint Screen::position() const
96+QPoint ScreenInterface::position() const
14697{
98+ if (!m_wrapped) return QPoint();
14799 return m_wrapped->position();
148100}
149101
150−QQmlListProperty<qtmir::ScreenMode> Screen::availableModes()
102+QQmlListProperty<qtmir::ScreenMode> ScreenInterface::availableModes()
151103{
104+ if (!m_wrapped) return QQmlListProperty<qtmir::ScreenMode>();
152105 return m_wrapped->availableModes();
153106}
154107
155−uint Screen::currentModeIndex() const
108+uint ScreenInterface::currentModeIndex() const
156109{
110+ if (!m_wrapped) return -1;
157111 return m_wrapped->currentModeIndex();
158112}
159113
160−bool Screen::isActive() const
114+bool ScreenInterface::isActive() const
161115{
116+ if (!m_wrapped) return false;
162117 return m_wrapped->isActive();
163118}
164119
165−qtmir::ScreenConfiguration *Screen::beginConfiguration() const
120+void ScreenInterface::activate()
121+{
122+ setActive(true);
123+}
124+
125+void ScreenInterface::setActive(bool active)
126+{
127+ if (!m_wrapped) return;
128+ m_wrapped->setActive(active);
129+}
130+
131+QScreen *ScreenInterface::qscreen() const
166132{
133+ if (!m_wrapped) return nullptr;
134+ return m_wrapped->qscreen();
135+}
136+
137+qtmir::ScreenConfiguration *ScreenInterface::beginConfiguration() const
138+{
139+ if (!m_wrapped) return nullptr;
167140 return m_wrapped->beginConfiguration();
168141}
169142
170−bool Screen::applyConfiguration(qtmir::ScreenConfiguration *configuration)
143+bool ScreenInterface::applyConfiguration(qtmir::ScreenConfiguration *configuration)
171144{
145+ if (!m_wrapped) return false;
172146 return m_wrapped->applyConfiguration(configuration);
173147}
174148
149+void ScreenInterface::sync(ScreenInterface *proxy)
150+{
151+ if (!proxy) return;
152+ workspaces()->sync(proxy->workspaces());
153+}
154+
155+Screen::Screen(qtmir::Screen* wrapped)
156+ : m_workspaces(new WorkspaceModel)
157+{
158+ connectToScreen(wrapped);
159+
160+ // Connect the active workspace to activate the screen.
161+ connect(m_workspaces.data(), &WorkspaceModel::workspaceAdded, this, [this](Workspace* workspace) {
162+ connect(workspace, &Workspace::activeChanged, this, [this, workspace](bool active) {
163+ if (active) {
164+ setCurrentWorkspace(workspace);
165+ activate();
166+ }
167+ });
168+ if (workspace->isActive()) {
169+ activate();
170+ setCurrentWorkspace(workspace);
171+ }
172+ if (!m_currentWorspace) {
173+ setCurrentWorkspace(workspace);
174+ }
175+ });
176+ connect(m_workspaces.data(), &WorkspaceModel::workspaceRemoved, this, [this](Workspace* workspace) {
177+ disconnect(workspace, &Workspace::activeChanged, this, 0);
178+ if (workspace == m_currentWorspace) {
179+ resetCurrentWorkspace();
180+ }
181+ });
182+ connect(this, &Screen::activeChanged, this, [this](bool active) {
183+ if (active && m_currentWorspace) {
184+ m_currentWorspace->activate();
185+ }
186+ });
187+
188+ WorkspaceManager::instance()->createWorkspace()->assign(m_workspaces.data());
189+ WorkspaceManager::instance()->createWorkspace()->assign(m_workspaces.data());
190+}
191+
192+void Screen::resetCurrentWorkspace()
193+{
194+ auto newCurrent = m_workspaces->rowCount() > 0 ? m_workspaces->get(0) : nullptr;
195+ if (m_currentWorspace != newCurrent) {
196+ m_currentWorspace = newCurrent;
197+ Q_EMIT currentWorkspaceChanged(newCurrent);
198+ }
199+}
200+
201+
175202WorkspaceModel *Screen::workspaces() const
176203{
177204 return m_workspaces.data();
@@ -190,32 +217,43 @@ void Screen::setCurrentWorkspace(Workspace *workspace)
190217 }
191218}
192219
193−void Screen::sync(Screen *proxy)
194−{
195− if (!proxy) return;
196−
197− workspaces()->sync(proxy->workspaces());
198−}
199−
200−void Screen::activate()
220+ScreenProxy::ScreenProxy(ScreenInterface *const screen)
221+ : m_workspaces(new WorkspaceModelProxy(screen->workspaces()))
222+ , m_original(screen)
201223{
202− setActive(true);
224+ connectToScreen(screen->wrapped());
225+
226+ auto updateCurrentWorkspaceFn = [this](Workspace* realWorkspace) {
227+ Q_FOREACH(Workspace* workspace, m_workspaces->list()) {
228+ auto p = qobject_cast<WorkspaceProxy*>(workspace);
229+ if (p && p->proxyObject() == realWorkspace) {
230+ if (m_currentWorspace != p) {
231+ m_currentWorspace = p;
232+ Q_EMIT currentWorkspaceChanged(p);
233+ }
234+ }
235+ }
236+ };
237+ connect(screen, &ScreenInterface::currentWorkspaceChanged, this, updateCurrentWorkspaceFn);
238+ updateCurrentWorkspaceFn(screen->currentWorkspace());
203239}
204240
205−void Screen::setActive(bool active)
241+WorkspaceModel *ScreenProxy::workspaces() const
206242{
207− m_wrapped->setActive(active);
243+ return m_workspaces.data();
208244}
209245
210−QScreen *Screen::qscreen() const
246+Workspace *ScreenProxy::currentWorkspace() const
211247{
212− return m_wrapped->qscreen();
248+ return m_currentWorspace.data();
213249}
214250
215−ScreenProxy::ScreenProxy(ScreenProxy::Screen *const screen)
216− : Screen(*screen)
217− , m_original(screen)
251+void ScreenProxy::setCurrentWorkspace(Workspace *workspace)
218252{
253+ auto p = qobject_cast<WorkspaceProxy*>(workspace);
254+ if (p) {
255+ m_original->setCurrentWorkspace(p->proxyObject());
256+ }
219257}
220258
221259void ScreenProxy::addWorkspace()