@@ -15,125 +15,138 @@
1515 */
1616
1717#include "Screen.h"
18+#include "Screens.h"
1819#include "WorkspaceManager.h"
1920#include "Workspace.h"
2021
21−#include <QQmlEngine>
22+ScreenInterface::ScreenInterface(QObject *parent)
23+ : QObject(parent)
24+{
25+}
2226
23−Screen::Screen(qtmir::Screen* screen)
24− : m_wrapped(screen)
25− , m_workspaces(new WorkspaceModel)
27+void ScreenInterface::connectToScreen(qtmir::Screen *screen)
2628{
27− QQmlEngine::setObjectOwnership(m_workspaces.data(), QQmlEngine::CppOwnership);
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);
40+}
2841
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− connect(m_wrapped, &qtmir::Screen::outputTypeChanged, this, &Screen::outputTypeNameChanged);
42+qtmir::OutputId ScreenInterface::outputId() const
43+{
44+ if (!m_wrapped) return qtmir::OutputId(-1);
45+ return m_wrapped->outputId();
46+}
4047
41− // Connect the active workspace to activate the screen.
42− connect(m_workspaces.data(), &WorkspaceModel::workspaceAdded, this, [this](Workspace* workspace) {
43− connect(workspace, &Workspace::activeChanged, this, [this, workspace](bool active) {
44− if (active) {
45− setCurrentWorkspace(workspace);
46− activate();
47− }
48− });
49− if (workspace->isActive()) {
50− activate();
51− setCurrentWorkspace(workspace);
52− }
53− if (!m_currentWorspace) {
54− setCurrentWorkspace(workspace);
55− }
56− });
57− connect(m_workspaces.data(), &WorkspaceModel::workspaceRemoved, this, [this](Workspace* workspace) {
58− disconnect(workspace, &Workspace::activeChanged, this, 0);
59− if (workspace == m_currentWorspace) {
60− resetCurrentWorkspace();
61− }
62− });
63− connect(this, &Screen::activeChanged, this, [this](bool active) {
64− if (active && m_currentWorspace) {
65− m_currentWorspace->activate();
66− }
67− });
48+bool ScreenInterface::used() const
49+{
50+ if (!m_wrapped) return false;
51+ return m_wrapped->used();
52+}
6853
69− WorkspaceManager::instance()->createWorkspace()->assign(m_workspaces.data());
70− WorkspaceManager::instance()->createWorkspace()->assign(m_workspaces.data());
54+QString ScreenInterface::name() const
55+{
56+ if (!m_wrapped) return QString();
57+ return m_wrapped->name();
7158}
7259
73−Screen::Screen(const Screen &other)
74− : qtmir::Screen(nullptr)
75− , m_wrapped(other.m_wrapped)
76− , m_workspaces(new WorkspaceModelProxy(other.m_workspaces.data()))
60+float ScreenInterface::scale() const
7761{
78− QQmlEngine::setObjectOwnership(m_workspaces.data(), QQmlEngine::CppOwnership);
62+ if (!m_wrapped) return 1.0;
63+ return m_wrapped->scale();
64+}
7965
80− connect(m_wrapped, &qtmir::Screen::usedChanged, this, &Screen::usedChanged);
81− connect(m_wrapped, &qtmir::Screen::nameChanged, this, &Screen::nameChanged);
82− connect(m_wrapped, &qtmir::Screen::outputTypeChanged, this, &Screen::outputTypeChanged);
83− connect(m_wrapped, &qtmir::Screen::scaleChanged, this, &Screen::scaleChanged);
84− connect(m_wrapped, &qtmir::Screen::formFactorChanged, this, &Screen::formFactorChanged);
85− connect(m_wrapped, &qtmir::Screen::physicalSizeChanged, this, &Screen::physicalSizeChanged);
86− connect(m_wrapped, &qtmir::Screen::positionChanged, this, &Screen::positionChanged);
87− connect(m_wrapped, &qtmir::Screen::activeChanged, this, &Screen::activeChanged);
88− connect(m_wrapped, &qtmir::Screen::currentModeIndexChanged, this, &Screen::currentModeIndexChanged);
89− connect(m_wrapped, &qtmir::Screen::availableModesChanged, this, &Screen::availableModesChanged);
66+QSizeF ScreenInterface::physicalSize() const
67+{
68+ if (!m_wrapped) return QSizeF();
69+ return m_wrapped->physicalSize();
9070}
9171
92−void Screen::resetCurrentWorkspace()
72+qtmir::FormFactor ScreenInterface::formFactor() const
9373{
94− auto newCurrent = m_workspaces->rowCount() > 0 ? m_workspaces->get(0) : nullptr;
95− if (m_currentWorspace != newCurrent) {
96− m_currentWorspace = newCurrent;
97− Q_EMIT currentWorkspaceChanged(newCurrent);
98− }
74+ if (!m_wrapped) return qtmir::FormFactorUnknown;
75+ return m_wrapped->formFactor();
9976}
10077
101−qtmir::OutputId Screen::outputId() const
78+qtmir::OutputTypes ScreenInterface::outputType() const
10279{
103− return m_wrapped->outputId();
80+ if (!m_wrapped) return qtmir::Unknown;
81+ return m_wrapped->outputType();
10482}
10583
106−bool Screen::used() const
84+MirPowerMode ScreenInterface::powerMode() const
10785{
108− return m_wrapped->used();
86+ if (!m_wrapped) return mir_power_mode_on;
87+ return m_wrapped->powerMode();
10988}
11089
111−QString Screen::name() const
90+Qt::ScreenOrientation ScreenInterface::orientation() const
11291{
113− return m_wrapped->name();
92+ if (!m_wrapped) return Qt::PrimaryOrientation;
93+ return m_wrapped->orientation();
11494}
11595
116−float Screen::scale() const
96+QPoint ScreenInterface::position() const
11797{
118− return m_wrapped->scale();
98+ if (!m_wrapped) return QPoint();
99+ return m_wrapped->position();
119100}
120101
121−QSizeF Screen::physicalSize() const
102+QQmlListProperty<qtmir::ScreenMode> ScreenInterface::availableModes()
122103{
123− return m_wrapped->physicalSize();
104+ if (!m_wrapped) return QQmlListProperty<qtmir::ScreenMode>();
105+ return m_wrapped->availableModes();
124106}
125107
126−qtmir::FormFactor Screen::formFactor() const
108+uint ScreenInterface::currentModeIndex() const
127109{
128− return m_wrapped->formFactor();
110+ if (!m_wrapped) return -1;
111+ return m_wrapped->currentModeIndex();
129112}
130113
131−qtmir::OutputTypes Screen::outputType() const
114+bool ScreenInterface::isActive() const
132115{
133− return m_wrapped->outputType();
116+ if (!m_wrapped) return false;
117+ return m_wrapped->isActive();
118+}
119+
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
132+{
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;
140+ return m_wrapped->beginConfiguration();
141+}
142+
143+bool ScreenInterface::applyConfiguration(qtmir::ScreenConfiguration *configuration)
144+{
145+ if (!m_wrapped) return false;
146+ return m_wrapped->applyConfiguration(configuration);
134147}
135148
136−QString Screen::outputTypeName() const
149+QString ScreenInterface::outputTypeName() const
137150{
138151 switch (m_wrapped->outputType()) {
139152 case qtmir::Unknown:
@@ -162,47 +175,61 @@ QString Screen::outputTypeName() const
162175 case qtmir::TV:
163176 return tr("TV");
164177 }
178+ return QString();
165179}
166180
167−MirPowerMode Screen::powerMode() const
168−{
169− return m_wrapped->powerMode();
170−}
171−
172−Qt::ScreenOrientation Screen::orientation() const
181+void ScreenInterface::sync(ScreenInterface *proxy)
173182{
174− return m_wrapped->orientation();
175−}
176−
177−QPoint Screen::position() const
178−{
179− return m_wrapped->position();
183+ if (!proxy) return;
184+ workspaces()->sync(proxy->workspaces());
180185}
181186
182−QQmlListProperty<qtmir::ScreenMode> Screen::availableModes()
187+Screen::Screen(qtmir::Screen* wrapped)
188+ : m_workspaces(new WorkspaceModel)
183189{
184− return m_wrapped->availableModes();
185−}
190+ connectToScreen(wrapped);
186191
187−uint Screen::currentModeIndex() const
188−{
189− return m_wrapped->currentModeIndex();
190−}
192+ // Connect the active workspace to activate the screen.
193+ connect(m_workspaces.data(), &WorkspaceModel::workspaceInserted, this, [this](int, Workspace* workspace) {
194+ connect(workspace, &Workspace::activeChanged, this, [this, workspace](bool active) {
195+ if (active) {
196+ setCurrentWorkspace(workspace);
197+ activate();
198+ }
199+ });
200+ if (workspace->isActive()) {
201+ activate();
202+ setCurrentWorkspace(workspace);
203+ }
204+ if (!m_currentWorspace) {
205+ setCurrentWorkspace(workspace);
206+ }
207+ });
208+ connect(m_workspaces.data(), &WorkspaceModel::workspaceRemoved, this, [this](Workspace* workspace) {
209+ disconnect(workspace, &Workspace::activeChanged, this, 0);
210+ if (workspace == m_currentWorspace) {
211+ resetCurrentWorkspace();
212+ }
213+ });
214+ connect(this, &Screen::activeChanged, this, [this](bool active) {
215+ if (active && m_currentWorspace) {
216+ m_currentWorspace->activate();
217+ }
218+ });
191219
192−bool Screen::isActive() const
193−{
194− return m_wrapped->isActive();
220+ WorkspaceManager::instance()->createWorkspace()->assign(m_workspaces.data());
221+ WorkspaceManager::instance()->createWorkspace()->assign(m_workspaces.data());
195222}
196223
197−qtmir::ScreenConfiguration *Screen::beginConfiguration() const
224+void Screen::resetCurrentWorkspace()
198225{
199− return m_wrapped->beginConfiguration();
226+ auto newCurrent = m_workspaces->rowCount() > 0 ? m_workspaces->get(0) : nullptr;
227+ if (m_currentWorspace != newCurrent) {
228+ m_currentWorspace = newCurrent;
229+ Q_EMIT currentWorkspaceChanged(newCurrent);
230+ }
200231}
201232
202−bool Screen::applyConfiguration(qtmir::ScreenConfiguration *configuration)
203−{
204− return m_wrapped->applyConfiguration(configuration);
205−}
206233
207234WorkspaceModel *Screen::workspaces() const
208235{
@@ -222,32 +249,43 @@ void Screen::setCurrentWorkspace(Workspace *workspace)
222249 }
223250}
224251
225−void Screen::sync(Screen *proxy)
226−{
227− if (!proxy) return;
228−
229− workspaces()->sync(proxy->workspaces());
230−}
231−
232−void Screen::activate()
252+ScreenProxy::ScreenProxy(ScreenInterface *const screen)
253+ : m_workspaces(new WorkspaceModelProxy(screen->workspaces()))
254+ , m_original(screen)
233255{
234− setActive(true);
256+ connectToScreen(screen->wrapped());
257+
258+ auto updateCurrentWorkspaceFn = [this](Workspace* realWorkspace) {
259+ Q_FOREACH(Workspace* workspace, m_workspaces->list()) {
260+ auto p = qobject_cast<WorkspaceProxy*>(workspace);
261+ if (p && p->proxyObject() == realWorkspace) {
262+ if (m_currentWorspace != p) {
263+ m_currentWorspace = p;
264+ Q_EMIT currentWorkspaceChanged(p);
265+ }
266+ }
267+ }
268+ };
269+ connect(screen, &ScreenInterface::currentWorkspaceChanged, this, updateCurrentWorkspaceFn);
270+ updateCurrentWorkspaceFn(screen->currentWorkspace());
235271}
236272
237−void Screen::setActive(bool active)
273+WorkspaceModel *ScreenProxy::workspaces() const
238274{
239− m_wrapped->setActive(active);
275+ return m_workspaces.data();
240276}
241277
242−QScreen *Screen::qscreen() const
278+Workspace *ScreenProxy::currentWorkspace() const
243279{
244− return m_wrapped->qscreen();
280+ return m_currentWorspace.data();
245281}
246282
247−ScreenProxy::ScreenProxy(ScreenProxy::Screen *const screen)
248− : Screen(*screen)
249− , m_original(screen)
283+void ScreenProxy::setCurrentWorkspace(Workspace *workspace)
250284{
285+ auto p = qobject_cast<WorkspaceProxy*>(workspace);
286+ if (p) {
287+ m_original->setCurrentWorkspace(p->proxyObject());
288+ }
251289}
252290
253291void ScreenProxy::addWorkspace()