1 /*
2 SPDX-FileCopyrightText: 2015 Eike Hein <hein@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 #include "plasmawindowmodel.h"
7 #include "plasmawindowmanagement.h"
8
9 #include <QMetaEnum>
10
11 namespace KWayland
12 {
13 namespace Client
14 {
15 class Q_DECL_HIDDEN PlasmaWindowModel::Private
16 {
17 public:
18 Private(PlasmaWindowModel *q);
19 QList<PlasmaWindow *> windows;
20 PlasmaWindow *window = nullptr;
21
22 void addWindow(PlasmaWindow *window);
23 void dataChanged(PlasmaWindow *window, int role);
24
25 private:
26 PlasmaWindowModel *q;
27 };
28
Private(PlasmaWindowModel * q)29 PlasmaWindowModel::Private::Private(PlasmaWindowModel *q)
30 : q(q)
31 {
32 }
33
addWindow(PlasmaWindow * window)34 void PlasmaWindowModel::Private::addWindow(PlasmaWindow *window)
35 {
36 if (windows.indexOf(window) != -1) {
37 return;
38 }
39
40 const int count = windows.count();
41 q->beginInsertRows(QModelIndex(), count, count);
42 windows.append(window);
43 q->endInsertRows();
44
45 auto removeWindow = [window, this] {
46 const int row = windows.indexOf(window);
47 if (row != -1) {
48 q->beginRemoveRows(QModelIndex(), row, row);
49 windows.removeAt(row);
50 q->endRemoveRows();
51 }
52 };
53
54 QObject::connect(window, &PlasmaWindow::unmapped, q, removeWindow);
55 QObject::connect(window, &QObject::destroyed, q, removeWindow);
56
57 QObject::connect(window, &PlasmaWindow::titleChanged, q, [window, this] {
58 this->dataChanged(window, Qt::DisplayRole);
59 });
60
61 QObject::connect(window, &PlasmaWindow::iconChanged, q, [window, this] {
62 this->dataChanged(window, Qt::DecorationRole);
63 });
64
65 QObject::connect(window, &PlasmaWindow::appIdChanged, q, [window, this] {
66 this->dataChanged(window, PlasmaWindowModel::AppId);
67 });
68
69 QObject::connect(window, &PlasmaWindow::activeChanged, q, [window, this] {
70 this->dataChanged(window, IsActive);
71 });
72
73 QObject::connect(window, &PlasmaWindow::fullscreenableChanged, q, [window, this] {
74 this->dataChanged(window, IsFullscreenable);
75 });
76
77 QObject::connect(window, &PlasmaWindow::fullscreenChanged, q, [window, this] {
78 this->dataChanged(window, IsFullscreen);
79 });
80
81 QObject::connect(window, &PlasmaWindow::maximizeableChanged, q, [window, this] {
82 this->dataChanged(window, IsMaximizable);
83 });
84
85 QObject::connect(window, &PlasmaWindow::maximizedChanged, q, [window, this] {
86 this->dataChanged(window, IsMaximized);
87 });
88
89 QObject::connect(window, &PlasmaWindow::minimizeableChanged, q, [window, this] {
90 this->dataChanged(window, IsMinimizable);
91 });
92
93 QObject::connect(window, &PlasmaWindow::minimizedChanged, q, [window, this] {
94 this->dataChanged(window, IsMinimized);
95 });
96
97 QObject::connect(window, &PlasmaWindow::keepAboveChanged, q, [window, this] {
98 this->dataChanged(window, IsKeepAbove);
99 });
100
101 QObject::connect(window, &PlasmaWindow::keepBelowChanged, q, [window, this] {
102 this->dataChanged(window, IsKeepBelow);
103 });
104
105 QObject::connect(window, &PlasmaWindow::virtualDesktopChanged, q, [window, this] {
106 this->dataChanged(window, VirtualDesktop);
107 });
108
109 QObject::connect(window, &PlasmaWindow::onAllDesktopsChanged, q, [window, this] {
110 this->dataChanged(window, IsOnAllDesktops);
111 });
112
113 QObject::connect(window, &PlasmaWindow::demandsAttentionChanged, q, [window, this] {
114 this->dataChanged(window, IsDemandingAttention);
115 });
116
117 QObject::connect(window, &PlasmaWindow::skipTaskbarChanged, q, [window, this] {
118 this->dataChanged(window, SkipTaskbar);
119 });
120
121 QObject::connect(window, &PlasmaWindow::skipSwitcherChanged, q, [window, this] {
122 this->dataChanged(window, SkipSwitcher);
123 });
124
125 QObject::connect(window, &PlasmaWindow::shadeableChanged, q, [window, this] {
126 this->dataChanged(window, IsShadeable);
127 });
128
129 QObject::connect(window, &PlasmaWindow::shadedChanged, q, [window, this] {
130 this->dataChanged(window, IsShaded);
131 });
132
133 QObject::connect(window, &PlasmaWindow::movableChanged, q, [window, this] {
134 this->dataChanged(window, IsMovable);
135 });
136
137 QObject::connect(window, &PlasmaWindow::resizableChanged, q, [window, this] {
138 this->dataChanged(window, IsResizable);
139 });
140
141 QObject::connect(window, &PlasmaWindow::virtualDesktopChangeableChanged, q, [window, this] {
142 this->dataChanged(window, IsVirtualDesktopChangeable);
143 });
144
145 QObject::connect(window, &PlasmaWindow::closeableChanged, q, [window, this] {
146 this->dataChanged(window, IsCloseable);
147 });
148
149 QObject::connect(window, &PlasmaWindow::geometryChanged, q, [window, this] {
150 this->dataChanged(window, Geometry);
151 });
152
153 QObject::connect(window, &PlasmaWindow::plasmaVirtualDesktopEntered, q, [window, this] {
154 this->dataChanged(window, VirtualDesktops);
155 });
156
157 QObject::connect(window, &PlasmaWindow::plasmaVirtualDesktopLeft, q, [window, this] {
158 this->dataChanged(window, VirtualDesktops);
159 });
160 }
161
dataChanged(PlasmaWindow * window,int role)162 void PlasmaWindowModel::Private::dataChanged(PlasmaWindow *window, int role)
163 {
164 QModelIndex idx = q->index(windows.indexOf(window));
165 Q_EMIT q->dataChanged(idx, idx, QVector<int>() << role);
166 }
167
PlasmaWindowModel(PlasmaWindowManagement * parent)168 PlasmaWindowModel::PlasmaWindowModel(PlasmaWindowManagement *parent)
169 : QAbstractListModel(parent)
170 , d(new Private(this))
171 {
172 connect(parent, &PlasmaWindowManagement::interfaceAboutToBeReleased, this, [this] {
173 beginResetModel();
174 d->windows.clear();
175 endResetModel();
176 });
177
178 connect(parent, &PlasmaWindowManagement::windowCreated, this, [this](PlasmaWindow *window) {
179 d->addWindow(window);
180 });
181
182 for (auto it = parent->windows().constBegin(); it != parent->windows().constEnd(); ++it) {
183 d->addWindow(*it);
184 }
185 }
186
~PlasmaWindowModel()187 PlasmaWindowModel::~PlasmaWindowModel()
188 {
189 }
190
roleNames() const191 QHash<int, QByteArray> PlasmaWindowModel::roleNames() const
192 {
193 QHash<int, QByteArray> roles;
194
195 roles.insert(Qt::DisplayRole, "DisplayRole");
196 roles.insert(Qt::DecorationRole, "DecorationRole");
197
198 QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("AdditionalRoles"));
199
200 for (int i = 0; i < e.keyCount(); ++i) {
201 roles.insert(e.value(i), e.key(i));
202 }
203
204 return roles;
205 }
206
data(const QModelIndex & index,int role) const207 QVariant PlasmaWindowModel::data(const QModelIndex &index, int role) const
208 {
209 if (!index.isValid() || index.row() >= d->windows.count()) {
210 return QVariant();
211 }
212
213 const PlasmaWindow *window = d->windows.at(index.row());
214
215 if (role == Qt::DisplayRole) {
216 return window->title();
217 } else if (role == Qt::DecorationRole) {
218 return window->icon();
219 } else if (role == AppId) {
220 return window->appId();
221 } else if (role == Pid) {
222 return window->pid();
223 } else if (role == IsActive) {
224 return window->isActive();
225 } else if (role == IsFullscreenable) {
226 return window->isFullscreenable();
227 } else if (role == IsFullscreen) {
228 return window->isFullscreen();
229 } else if (role == IsMaximizable) {
230 return window->isMaximizeable();
231 } else if (role == IsMaximized) {
232 return window->isMaximized();
233 } else if (role == IsMinimizable) {
234 return window->isMinimizeable();
235 } else if (role == IsMinimized) {
236 return window->isMinimized();
237 } else if (role == IsKeepAbove) {
238 return window->isKeepAbove();
239 } else if (role == IsKeepBelow) {
240 return window->isKeepBelow();
241 } else if (role == VirtualDesktop) {
242 return window->virtualDesktop();
243 } else if (role == IsOnAllDesktops) {
244 return window->isOnAllDesktops();
245 } else if (role == IsDemandingAttention) {
246 return window->isDemandingAttention();
247 } else if (role == SkipTaskbar) {
248 return window->skipTaskbar();
249 } else if (role == SkipSwitcher) {
250 return window->skipSwitcher();
251 } else if (role == IsShadeable) {
252 return window->isShadeable();
253 } else if (role == IsShaded) {
254 return window->isShaded();
255 } else if (role == IsMovable) {
256 return window->isMovable();
257 } else if (role == IsResizable) {
258 return window->isResizable();
259 } else if (role == IsVirtualDesktopChangeable) {
260 return window->isVirtualDesktopChangeable();
261 } else if (role == IsCloseable) {
262 return window->isCloseable();
263 } else if (role == Geometry) {
264 return window->geometry();
265 } else if (role == VirtualDesktops) {
266 return window->plasmaVirtualDesktops();
267 } else if (role == Uuid) {
268 return window->uuid();
269 }
270
271 return QVariant();
272 }
273
rowCount(const QModelIndex & parent) const274 int PlasmaWindowModel::rowCount(const QModelIndex &parent) const
275 {
276 return parent.isValid() ? 0 : d->windows.count();
277 }
278
index(int row,int column,const QModelIndex & parent) const279 QModelIndex PlasmaWindowModel::index(int row, int column, const QModelIndex &parent) const
280 {
281 return hasIndex(row, column, parent) ? createIndex(row, column, d->windows.at(row)) : QModelIndex();
282 }
283
requestActivate(int row)284 Q_INVOKABLE void PlasmaWindowModel::requestActivate(int row)
285 {
286 if (row >= 0 && row < d->windows.count()) {
287 d->windows.at(row)->requestActivate();
288 }
289 }
290
requestClose(int row)291 Q_INVOKABLE void PlasmaWindowModel::requestClose(int row)
292 {
293 if (row >= 0 && row < d->windows.count()) {
294 d->windows.at(row)->requestClose();
295 }
296 }
297
requestMove(int row)298 Q_INVOKABLE void PlasmaWindowModel::requestMove(int row)
299 {
300 if (row >= 0 && row < d->windows.count()) {
301 d->windows.at(row)->requestMove();
302 }
303 }
304
requestResize(int row)305 Q_INVOKABLE void PlasmaWindowModel::requestResize(int row)
306 {
307 if (row >= 0 && row < d->windows.count()) {
308 d->windows.at(row)->requestResize();
309 }
310 }
311
requestVirtualDesktop(int row,quint32 desktop)312 Q_INVOKABLE void PlasmaWindowModel::requestVirtualDesktop(int row, quint32 desktop)
313 {
314 if (row >= 0 && row < d->windows.count()) {
315 d->windows.at(row)->requestVirtualDesktop(desktop);
316 }
317 }
318
requestToggleKeepAbove(int row)319 Q_INVOKABLE void PlasmaWindowModel::requestToggleKeepAbove(int row)
320 {
321 if (row >= 0 && row < d->windows.count()) {
322 d->windows.at(row)->requestToggleKeepAbove();
323 }
324 }
325
requestToggleKeepBelow(int row)326 Q_INVOKABLE void PlasmaWindowModel::requestToggleKeepBelow(int row)
327 {
328 if (row >= 0 && row < d->windows.count()) {
329 d->windows.at(row)->requestToggleKeepBelow();
330 }
331 }
332
requestToggleMinimized(int row)333 Q_INVOKABLE void PlasmaWindowModel::requestToggleMinimized(int row)
334 {
335 if (row >= 0 && row < d->windows.count()) {
336 d->windows.at(row)->requestToggleMinimized();
337 }
338 }
339
requestToggleMaximized(int row)340 Q_INVOKABLE void PlasmaWindowModel::requestToggleMaximized(int row)
341 {
342 if (row >= 0 && row < d->windows.count()) {
343 d->windows.at(row)->requestToggleMaximized();
344 }
345 }
346
setMinimizedGeometry(int row,Surface * panel,const QRect & geom)347 Q_INVOKABLE void PlasmaWindowModel::setMinimizedGeometry(int row, Surface *panel, const QRect &geom)
348 {
349 if (row >= 0 && row < d->windows.count()) {
350 d->windows.at(row)->setMinimizedGeometry(panel, geom);
351 }
352 }
353
requestToggleShaded(int row)354 Q_INVOKABLE void PlasmaWindowModel::requestToggleShaded(int row)
355 {
356 if (row >= 0 && row < d->windows.count()) {
357 d->windows.at(row)->requestToggleShaded();
358 }
359 }
360
361 }
362 }
363