File indexing completed on 2024-12-22 05:09:22

0001 /*
0002     SPDX-FileCopyrightText: 2015 Eike Hein <hein@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 #include "plasmawindowmodel.h"
0007 #include "plasmawindowmanagement.h"
0008 
0009 #include <QMetaEnum>
0010 
0011 namespace KWayland
0012 {
0013 namespace Client
0014 {
0015 class Q_DECL_HIDDEN PlasmaWindowModel::Private
0016 {
0017 public:
0018     Private(PlasmaWindowModel *q);
0019     QList<PlasmaWindow *> windows;
0020     PlasmaWindow *window = nullptr;
0021 
0022     void addWindow(PlasmaWindow *window);
0023     void dataChanged(PlasmaWindow *window, int role);
0024 
0025 private:
0026     PlasmaWindowModel *q;
0027 };
0028 
0029 PlasmaWindowModel::Private::Private(PlasmaWindowModel *q)
0030     : q(q)
0031 {
0032 }
0033 
0034 void PlasmaWindowModel::Private::addWindow(PlasmaWindow *window)
0035 {
0036     if (windows.indexOf(window) != -1) {
0037         return;
0038     }
0039 
0040     const int count = windows.count();
0041     q->beginInsertRows(QModelIndex(), count, count);
0042     windows.append(window);
0043     q->endInsertRows();
0044 
0045     auto removeWindow = [window, this] {
0046         const int row = windows.indexOf(window);
0047         if (row != -1) {
0048             q->beginRemoveRows(QModelIndex(), row, row);
0049             windows.removeAt(row);
0050             q->endRemoveRows();
0051         }
0052     };
0053 
0054     QObject::connect(window, &PlasmaWindow::unmapped, q, removeWindow);
0055     QObject::connect(window, &QObject::destroyed, q, removeWindow);
0056 
0057     QObject::connect(window, &PlasmaWindow::titleChanged, q, [window, this] {
0058         this->dataChanged(window, Qt::DisplayRole);
0059     });
0060 
0061     QObject::connect(window, &PlasmaWindow::iconChanged, q, [window, this] {
0062         this->dataChanged(window, Qt::DecorationRole);
0063     });
0064 
0065     QObject::connect(window, &PlasmaWindow::appIdChanged, q, [window, this] {
0066         this->dataChanged(window, PlasmaWindowModel::AppId);
0067     });
0068 
0069     QObject::connect(window, &PlasmaWindow::activeChanged, q, [window, this] {
0070         this->dataChanged(window, IsActive);
0071     });
0072 
0073     QObject::connect(window, &PlasmaWindow::fullscreenableChanged, q, [window, this] {
0074         this->dataChanged(window, IsFullscreenable);
0075     });
0076 
0077     QObject::connect(window, &PlasmaWindow::fullscreenChanged, q, [window, this] {
0078         this->dataChanged(window, IsFullscreen);
0079     });
0080 
0081     QObject::connect(window, &PlasmaWindow::maximizeableChanged, q, [window, this] {
0082         this->dataChanged(window, IsMaximizable);
0083     });
0084 
0085     QObject::connect(window, &PlasmaWindow::maximizedChanged, q, [window, this] {
0086         this->dataChanged(window, IsMaximized);
0087     });
0088 
0089     QObject::connect(window, &PlasmaWindow::minimizeableChanged, q, [window, this] {
0090         this->dataChanged(window, IsMinimizable);
0091     });
0092 
0093     QObject::connect(window, &PlasmaWindow::minimizedChanged, q, [window, this] {
0094         this->dataChanged(window, IsMinimized);
0095     });
0096 
0097     QObject::connect(window, &PlasmaWindow::keepAboveChanged, q, [window, this] {
0098         this->dataChanged(window, IsKeepAbove);
0099     });
0100 
0101     QObject::connect(window, &PlasmaWindow::keepBelowChanged, q, [window, this] {
0102         this->dataChanged(window, IsKeepBelow);
0103     });
0104 
0105     QObject::connect(window, &PlasmaWindow::onAllDesktopsChanged, q, [window, this] {
0106         this->dataChanged(window, IsOnAllDesktops);
0107     });
0108 
0109     QObject::connect(window, &PlasmaWindow::demandsAttentionChanged, q, [window, this] {
0110         this->dataChanged(window, IsDemandingAttention);
0111     });
0112 
0113     QObject::connect(window, &PlasmaWindow::skipTaskbarChanged, q, [window, this] {
0114         this->dataChanged(window, SkipTaskbar);
0115     });
0116 
0117     QObject::connect(window, &PlasmaWindow::skipSwitcherChanged, q, [window, this] {
0118         this->dataChanged(window, SkipSwitcher);
0119     });
0120 
0121     QObject::connect(window, &PlasmaWindow::shadeableChanged, q, [window, this] {
0122         this->dataChanged(window, IsShadeable);
0123     });
0124 
0125     QObject::connect(window, &PlasmaWindow::shadedChanged, q, [window, this] {
0126         this->dataChanged(window, IsShaded);
0127     });
0128 
0129     QObject::connect(window, &PlasmaWindow::movableChanged, q, [window, this] {
0130         this->dataChanged(window, IsMovable);
0131     });
0132 
0133     QObject::connect(window, &PlasmaWindow::resizableChanged, q, [window, this] {
0134         this->dataChanged(window, IsResizable);
0135     });
0136 
0137     QObject::connect(window, &PlasmaWindow::virtualDesktopChangeableChanged, q, [window, this] {
0138         this->dataChanged(window, IsVirtualDesktopChangeable);
0139     });
0140 
0141     QObject::connect(window, &PlasmaWindow::closeableChanged, q, [window, this] {
0142         this->dataChanged(window, IsCloseable);
0143     });
0144 
0145     QObject::connect(window, &PlasmaWindow::geometryChanged, q, [window, this] {
0146         this->dataChanged(window, Geometry);
0147     });
0148 
0149     QObject::connect(window, &PlasmaWindow::plasmaVirtualDesktopEntered, q, [window, this] {
0150         this->dataChanged(window, VirtualDesktops);
0151     });
0152 
0153     QObject::connect(window, &PlasmaWindow::plasmaVirtualDesktopLeft, q, [window, this] {
0154         this->dataChanged(window, VirtualDesktops);
0155     });
0156 }
0157 
0158 void PlasmaWindowModel::Private::dataChanged(PlasmaWindow *window, int role)
0159 {
0160     QModelIndex idx = q->index(windows.indexOf(window));
0161     Q_EMIT q->dataChanged(idx, idx, QList<int>() << role);
0162 }
0163 
0164 PlasmaWindowModel::PlasmaWindowModel(PlasmaWindowManagement *parent)
0165     : QAbstractListModel(parent)
0166     , d(new Private(this))
0167 {
0168     connect(parent, &PlasmaWindowManagement::interfaceAboutToBeReleased, this, [this] {
0169         beginResetModel();
0170         d->windows.clear();
0171         endResetModel();
0172     });
0173 
0174     connect(parent, &PlasmaWindowManagement::windowCreated, this, [this](PlasmaWindow *window) {
0175         d->addWindow(window);
0176     });
0177 
0178     for (auto it = parent->windows().constBegin(); it != parent->windows().constEnd(); ++it) {
0179         d->addWindow(*it);
0180     }
0181 }
0182 
0183 PlasmaWindowModel::~PlasmaWindowModel()
0184 {
0185 }
0186 
0187 QHash<int, QByteArray> PlasmaWindowModel::roleNames() const
0188 {
0189     QHash<int, QByteArray> roles;
0190 
0191     roles.insert(Qt::DisplayRole, "display");
0192     roles.insert(Qt::DecorationRole, "decoration");
0193 
0194     QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("AdditionalRoles"));
0195 
0196     for (int i = 0; i < e.keyCount(); ++i) {
0197         roles.insert(e.value(i), e.key(i));
0198     }
0199 
0200     return roles;
0201 }
0202 
0203 QVariant PlasmaWindowModel::data(const QModelIndex &index, int role) const
0204 {
0205     if (!index.isValid() || index.row() >= d->windows.count()) {
0206         return QVariant();
0207     }
0208 
0209     const PlasmaWindow *window = d->windows.at(index.row());
0210 
0211     if (role == Qt::DisplayRole) {
0212         return window->title();
0213     } else if (role == Qt::DecorationRole) {
0214         return window->icon();
0215     } else if (role == AppId) {
0216         return window->appId();
0217     } else if (role == Pid) {
0218         return window->pid();
0219     } else if (role == IsActive) {
0220         return window->isActive();
0221     } else if (role == IsFullscreenable) {
0222         return window->isFullscreenable();
0223     } else if (role == IsFullscreen) {
0224         return window->isFullscreen();
0225     } else if (role == IsMaximizable) {
0226         return window->isMaximizeable();
0227     } else if (role == IsMaximized) {
0228         return window->isMaximized();
0229     } else if (role == IsMinimizable) {
0230         return window->isMinimizeable();
0231     } else if (role == IsMinimized) {
0232         return window->isMinimized();
0233     } else if (role == IsKeepAbove) {
0234         return window->isKeepAbove();
0235     } else if (role == IsKeepBelow) {
0236         return window->isKeepBelow();
0237     } else if (role == IsOnAllDesktops) {
0238         return window->isOnAllDesktops();
0239     } else if (role == IsDemandingAttention) {
0240         return window->isDemandingAttention();
0241     } else if (role == SkipTaskbar) {
0242         return window->skipTaskbar();
0243     } else if (role == SkipSwitcher) {
0244         return window->skipSwitcher();
0245     } else if (role == IsShadeable) {
0246         return window->isShadeable();
0247     } else if (role == IsShaded) {
0248         return window->isShaded();
0249     } else if (role == IsMovable) {
0250         return window->isMovable();
0251     } else if (role == IsResizable) {
0252         return window->isResizable();
0253     } else if (role == IsVirtualDesktopChangeable) {
0254         return window->isVirtualDesktopChangeable();
0255     } else if (role == IsCloseable) {
0256         return window->isCloseable();
0257     } else if (role == Geometry) {
0258         return window->geometry();
0259     } else if (role == VirtualDesktops) {
0260         return window->plasmaVirtualDesktops();
0261     } else if (role == Uuid) {
0262         return window->uuid();
0263     }
0264 
0265     return QVariant();
0266 }
0267 QMap<int, QVariant> PlasmaWindowModel::itemData(const QModelIndex &index) const
0268 {
0269     QMap<int, QVariant> ret = QAbstractItemModel::itemData(index);
0270     for (int role = AppId; role < LastRole; ++role) {
0271         ret.insert(role, data(index, role));
0272     }
0273     return ret;
0274 }
0275 
0276 int PlasmaWindowModel::rowCount(const QModelIndex &parent) const
0277 {
0278     return parent.isValid() ? 0 : d->windows.count();
0279 }
0280 
0281 QModelIndex PlasmaWindowModel::index(int row, int column, const QModelIndex &parent) const
0282 {
0283     return hasIndex(row, column, parent) ? createIndex(row, column, d->windows.at(row)) : QModelIndex();
0284 }
0285 
0286 Q_INVOKABLE void PlasmaWindowModel::requestActivate(int row)
0287 {
0288     if (row >= 0 && row < d->windows.count()) {
0289         d->windows.at(row)->requestActivate();
0290     }
0291 }
0292 
0293 Q_INVOKABLE void PlasmaWindowModel::requestClose(int row)
0294 {
0295     if (row >= 0 && row < d->windows.count()) {
0296         d->windows.at(row)->requestClose();
0297     }
0298 }
0299 
0300 Q_INVOKABLE void PlasmaWindowModel::requestMove(int row)
0301 {
0302     if (row >= 0 && row < d->windows.count()) {
0303         d->windows.at(row)->requestMove();
0304     }
0305 }
0306 
0307 Q_INVOKABLE void PlasmaWindowModel::requestResize(int row)
0308 {
0309     if (row >= 0 && row < d->windows.count()) {
0310         d->windows.at(row)->requestResize();
0311     }
0312 }
0313 
0314 Q_INVOKABLE void PlasmaWindowModel::requestEnterVirtualDesktop(int row, const QString &id)
0315 {
0316     if (row >= 0 && row < d->windows.count()) {
0317         d->windows.at(row)->requestEnterVirtualDesktop(id);
0318     }
0319 }
0320 
0321 Q_INVOKABLE void PlasmaWindowModel::requestToggleKeepAbove(int row)
0322 {
0323     if (row >= 0 && row < d->windows.count()) {
0324         d->windows.at(row)->requestToggleKeepAbove();
0325     }
0326 }
0327 
0328 Q_INVOKABLE void PlasmaWindowModel::requestToggleKeepBelow(int row)
0329 {
0330     if (row >= 0 && row < d->windows.count()) {
0331         d->windows.at(row)->requestToggleKeepBelow();
0332     }
0333 }
0334 
0335 Q_INVOKABLE void PlasmaWindowModel::requestToggleMinimized(int row)
0336 {
0337     if (row >= 0 && row < d->windows.count()) {
0338         d->windows.at(row)->requestToggleMinimized();
0339     }
0340 }
0341 
0342 Q_INVOKABLE void PlasmaWindowModel::requestToggleMaximized(int row)
0343 {
0344     if (row >= 0 && row < d->windows.count()) {
0345         d->windows.at(row)->requestToggleMaximized();
0346     }
0347 }
0348 
0349 Q_INVOKABLE void PlasmaWindowModel::requestToggleFullscreen(int row)
0350 {
0351     if (row >= 0 && row < d->windows.count()) {
0352         d->windows.at(row)->requestToggleFullscreen();
0353     }
0354 }
0355 
0356 Q_INVOKABLE void PlasmaWindowModel::setMinimizedGeometry(int row, Surface *panel, const QRect &geom)
0357 {
0358     if (row >= 0 && row < d->windows.count()) {
0359         d->windows.at(row)->setMinimizedGeometry(panel, geom);
0360     }
0361 }
0362 
0363 Q_INVOKABLE void PlasmaWindowModel::requestToggleShaded(int row)
0364 {
0365     if (row >= 0 && row < d->windows.count()) {
0366         d->windows.at(row)->requestToggleShaded();
0367     }
0368 }
0369 
0370 }
0371 }
0372 
0373 #include "moc_plasmawindowmodel.cpp"