File indexing completed on 2024-05-19 05:35:55
0001 /* 0002 SPDX-FileCopyrightText: 2016 Eike Hein <hein.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "windowmodel.h" 0007 #include "pagermodel.h" 0008 0009 #include <abstracttasksmodel.h> 0010 0011 #include <QGuiApplication> 0012 #include <QMetaEnum> 0013 #include <QScreen> 0014 0015 #include <KWindowSystem> 0016 #include <KX11Extras> 0017 0018 using namespace TaskManager; 0019 0020 class WindowModel::Private 0021 { 0022 public: 0023 Private(WindowModel *q); 0024 0025 PagerModel *pagerModel = nullptr; 0026 0027 private: 0028 WindowModel *q; 0029 }; 0030 0031 WindowModel::Private::Private(WindowModel *q) 0032 : q(q) 0033 { 0034 Q_UNUSED(this->q); 0035 } 0036 0037 WindowModel::WindowModel(PagerModel *parent) 0038 : TaskFilterProxyModel(parent) 0039 , d(new Private(this)) 0040 { 0041 d->pagerModel = parent; 0042 connect(parent, &PagerModel::pagerItemSizeChanged, this, &WindowModel::onPagerItemSizeChanged); 0043 connect(this, &QAbstractItemModel::dataChanged, this, [this](const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList<int> &roles) { 0044 if (roles.contains(AbstractTasksModel::StackingOrder)) { 0045 Q_EMIT dataChanged(topLeft, bottomRight, {WindowModelRoles::StackingOrder}); 0046 } 0047 }); 0048 } 0049 0050 WindowModel::~WindowModel() 0051 { 0052 } 0053 0054 QHash<int, QByteArray> WindowModel::roleNames() const 0055 { 0056 QHash<int, QByteArray> roles = TaskFilterProxyModel::roleNames(); 0057 0058 QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("WindowModelRoles")); 0059 0060 for (int i = 0; i < e.keyCount(); ++i) { 0061 roles.insert(e.value(i), e.key(i)); 0062 } 0063 0064 return roles; 0065 } 0066 0067 QVariant WindowModel::data(const QModelIndex &index, int role) const 0068 { 0069 if (role == AbstractTasksModel::Geometry) { 0070 QRect windowGeo = TaskFilterProxyModel::data(index, role).toRect(); 0071 const QRect clampingRect(QPoint(0, 0), d->pagerModel->pagerItemSize()); 0072 0073 if (KWindowSystem::isPlatformX11() && KX11Extras::mapViewport()) { 0074 int x = windowGeo.center().x() % clampingRect.width(); 0075 int y = windowGeo.center().y() % clampingRect.height(); 0076 0077 if (x < 0) { 0078 x = x + clampingRect.width(); 0079 } 0080 0081 if (y < 0) { 0082 y = y + clampingRect.height(); 0083 } 0084 0085 const QRect mappedGeo(x - windowGeo.width() / 2, y - windowGeo.height() / 2, windowGeo.width(), windowGeo.height()); 0086 0087 if (filterByScreen() && screenGeometry().isValid()) { 0088 const QPoint &screenOffset = screenGeometry().topLeft(); 0089 0090 windowGeo = mappedGeo.translated(0 - screenOffset.x(), 0 - screenOffset.y()); 0091 } 0092 } else if (filterByScreen() && screenGeometry().isValid()) { 0093 const QPoint &screenOffset = screenGeometry().topLeft(); 0094 0095 windowGeo.translate(0 - screenOffset.x(), 0 - screenOffset.y()); 0096 } 0097 0098 // Restrict to desktop/screen rect. 0099 return windowGeo.intersected(clampingRect); 0100 } else if (role == StackingOrder) { 0101 const auto &winId = TaskFilterProxyModel::data(index, AbstractTasksModel::WinIdList); 0102 const int z = d->pagerModel->stackingOrder(index).indexOf(winId); 0103 0104 if (z != -1) { 0105 return z; 0106 } 0107 return 0; 0108 } 0109 0110 return TaskFilterProxyModel::data(index, role); 0111 } 0112 0113 void WindowModel::onPagerItemSizeChanged() 0114 { 0115 if (rowCount() > 0) { 0116 Q_EMIT dataChanged(index(0, 0), index(rowCount() - 1, 0), {AbstractTasksModel::Geometry}); 0117 } 0118 }