Lomiri
Loading...
Searching...
No Matches
ScreenAttached.cpp
1/*
2 * Copyright (C) 2017 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License version 3, as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10 * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "ScreenAttached.h"
18#include "ScreenWindow.h"
19#include "Screens.h"
20
21#include <QQuickItem>
22#include <QScreen>
23
24namespace
25{
26QQuickItem* itemForOwner(QObject* obj) {
27 QObject* parent = obj;
28 while(parent) {
29 auto item = qobject_cast<QQuickItem*>(parent);
30 if (item) return item;
31 parent = parent->parent();
32 }
33 return nullptr;
34}
35} // namesapce
36
37ScreenAttached::ScreenAttached(QObject *owner)
38 : Screen(owner)
39 , m_window(nullptr)
40{
41 if (auto item = itemForOwner(owner)) {
42 connect(item, &QQuickItem::windowChanged, this, &ScreenAttached::windowChanged);
43 windowChanged(item->window());
44 } else if (auto window = qobject_cast<QQuickWindow*>(owner)) {
45 windowChanged(window);
46 }
47}
48
49WorkspaceModel *ScreenAttached::workspaces() const
50{
51 if (!m_screen) return nullptr;
52 return m_screen->workspaces();
53}
54
55Workspace *ScreenAttached::currentWorkspace() const
56{
57 if (!m_screen) return nullptr;
58 return m_screen->currentWorkspace();
59}
60
61void ScreenAttached::setCurrentWorkspace(Workspace *workspace)
62{
63 if (!m_screen) return;
64 return m_screen->setCurrentWorkspace(workspace);
65}
66
67void ScreenAttached::windowChanged(QQuickWindow *window)
68{
69 if (m_window) {
70 disconnect(m_window, &QWindow::screenChanged, this, &ScreenAttached::screenChanged);
71 }
72
73 m_window = window;
74 auto screenWindow = qobject_cast<ScreenWindow*>(window);
75
76 if (screenWindow) {
77 screenChanged2(screenWindow->screenWrapper());
78 connect(screenWindow, &ScreenWindow::screenWrapperChanged, this, &ScreenAttached::screenChanged2);
79 } else {
80 screenChanged(window ? window->screen() : NULL);
81 if (window) {
82 connect(window, &QWindow::screenChanged, this, &ScreenAttached::screenChanged);
83 }
84 }
85}
86
87void ScreenAttached::screenChanged(QScreen *qscreen)
88{
89 // Find a screen that matches.
90 // Should only get here in mocks if we don't have a ScreenWindow
91 Screen* screen{nullptr};
92 Q_FOREACH(auto s, ConcreteScreens::self()->list()) {
93 if (s->qscreen() == qscreen) {
94 screen = s;
95 }
96 }
97 screenChanged2(screen);
98}
99
100void ScreenAttached::screenChanged2(Screen* screen)
101{
102 if (screen == m_screen) return;
103
104 Screen* oldScreen = m_screen;
105 m_screen = screen;
106
107 if (oldScreen)
108 oldScreen->disconnect(this);
109
110 if (!screen)
111 return; //Don't bother emitting signals, because the new values are garbage anyways
112
113 if (!oldScreen || screen->isActive() != oldScreen->isActive())
114 Q_EMIT activeChanged(screen->isActive());
115 if (!oldScreen || screen->used() != oldScreen->used())
116 Q_EMIT usedChanged();
117 if (!oldScreen || screen->name() != oldScreen->name())
118 Q_EMIT nameChanged();
119 if (!oldScreen || screen->outputType() != oldScreen->outputType())
120 Q_EMIT outputTypeChanged();
121 if (!oldScreen || screen->scale() != oldScreen->scale())
122 Q_EMIT scaleChanged();
123 if (!oldScreen || screen->formFactor() != oldScreen->formFactor())
124 Q_EMIT formFactorChanged();
125 if (!oldScreen || screen->powerMode() != oldScreen->powerMode())
126 Q_EMIT powerModeChanged();
127 if (!oldScreen || screen->orientation() != oldScreen->orientation())
128 Q_EMIT orientationChanged();
129 if (!oldScreen || screen->position() != oldScreen->position())
130 Q_EMIT positionChanged();
131 if (!oldScreen || screen->currentModeIndex() != oldScreen->currentModeIndex())
132 Q_EMIT currentModeIndexChanged();
133 if (!oldScreen || screen->physicalSize() != oldScreen->physicalSize())
134 Q_EMIT physicalSizeChanged();
135 if (!oldScreen || screen->currentWorkspace() != oldScreen->currentWorkspace())
136 Q_EMIT currentWorkspaceChanged(currentWorkspace());
137
138 if (oldScreen) {
139 QVector<qtmir::ScreenMode*> oldModes;
140 auto oldModesQmlList = oldScreen->availableModes();
141 for (int i = 0; i < oldModesQmlList.count(&oldModesQmlList); i++) {
142 oldModes << oldModesQmlList.at(&oldModesQmlList, i);
143 }
144
145 QVector<qtmir::ScreenMode*> newModes;
146 auto newModesQmlList = screen->availableModes();
147 for (int i = 0; i < newModesQmlList.count(&newModesQmlList); i++) {
148 newModes << newModesQmlList.at(&newModesQmlList, i);
149 }
150
151 if (newModes != newModes) {
152 Q_EMIT availableModesChanged();
153 }
154 } else {
155 Q_EMIT availableModesChanged();
156 }
157
158 connectToScreen(screen);
159}
160
161ScreenAttached *WMScreen::qmlAttachedProperties(QObject *owner)
162{
163 return new ScreenAttached(owner);
164}