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

source code of kwayland/src/client/plasmawindowmodel.cpp