KWin
Loading...
Searching...
No Matches
clientmodel.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2009 Martin Gräßlin <mgraesslin@kde.org>
6
7 SPDX-License-Identifier: GPL-2.0-or-later
8*/
9
10#include "clientmodel.h"
11#include "tabboxconfig.h"
12#include "window.h"
13
14#include <KLocalizedString>
15
16#include <QIcon>
17#include <QUuid>
18
19#include <cmath>
20
21namespace KWin
22{
23namespace TabBox
24{
25
27 : QAbstractItemModel(parent)
28{
29}
30
34
35QVariant ClientModel::data(const QModelIndex &index, int role) const
36{
37 if (!index.isValid()) {
38 return QVariant();
39 }
40
41 if (m_clientList.isEmpty()) {
42 return QVariant();
43 }
44
45 int clientIndex = index.row();
46 if (clientIndex >= m_clientList.count()) {
47 return QVariant();
48 }
49 Window *client = m_clientList[clientIndex];
50 if (!client) {
51 return QVariant();
52 }
53 switch (role) {
54 case Qt::DisplayRole:
55 case CaptionRole: {
56 if (client->isDesktop()) {
57 return i18nc("Special entry in alt+tab list for minimizing all windows",
58 "Show Desktop");
59 }
60 return client->caption();
61 }
62 case ClientRole:
63 return QVariant::fromValue<void *>(client);
64 case DesktopNameRole: {
65 return tabBox->desktopName(client);
66 }
67 case WIdRole:
68 return client->internalId();
69 case MinimizedRole:
70 return client->isMinimized();
71 case CloseableRole:
72 return client->isCloseable();
73 case IconRole:
74 if (client->isDesktop()) {
75 return QIcon::fromTheme(QStringLiteral("user-desktop"));
76 }
77 return client->icon();
78 default:
79 return QVariant();
80 }
81}
82
84{
85 QString caption;
86 for (Window *window : std::as_const(m_clientList)) {
87 if (window->caption().size() > caption.size()) {
88 caption = window->caption();
89 }
90 }
91 return caption;
92}
93
94int ClientModel::columnCount(const QModelIndex &parent) const
95{
96 return 1;
97}
98
99int ClientModel::rowCount(const QModelIndex &parent) const
100{
101 if (parent.isValid()) {
102 return 0;
103 }
104 return m_clientList.count();
105}
106
107QModelIndex ClientModel::parent(const QModelIndex &child) const
108{
109 return QModelIndex();
110}
111
112QModelIndex ClientModel::index(int row, int column, const QModelIndex &parent) const
113{
114 if (row < 0 || column != 0 || parent.isValid()) {
115 return QModelIndex();
116 }
117 int index = row * columnCount();
118 if (index >= m_clientList.count() && !m_clientList.isEmpty()) {
119 return QModelIndex();
120 }
121 return createIndex(row, 0);
122}
123
124QHash<int, QByteArray> ClientModel::roleNames() const
125{
126 return {
127 {CaptionRole, QByteArrayLiteral("caption")},
128 {DesktopNameRole, QByteArrayLiteral("desktopName")},
129 {MinimizedRole, QByteArrayLiteral("minimized")},
130 {WIdRole, QByteArrayLiteral("windowId")},
131 {CloseableRole, QByteArrayLiteral("closeable")},
132 {IconRole, QByteArrayLiteral("icon")},
133 };
134}
135
136QModelIndex ClientModel::index(Window *client) const
137{
138 const int index = m_clientList.indexOf(client);
139 if (index == -1) {
140 return QModelIndex();
141 }
142 int row = index / columnCount();
143 int column = index % columnCount();
144 return createIndex(row, column);
145}
146
147void ClientModel::createFocusChainClientList(Window *start)
148{
149 auto c = start;
150 if (!tabBox->isInFocusChain(c)) {
151 Window *firstClient = tabBox->firstClientFocusChain();
152 if (firstClient) {
153 c = firstClient;
154 }
155 }
156 auto stop = c;
157 do {
159 if (add) {
160 m_mutableClientList += add;
161 }
163 } while (c && c != stop);
164}
165
166void ClientModel::createStackingOrderClientList(Window *start)
167{
168 // TODO: needs improvement
169 const QList<Window *> stacking = tabBox->stackingOrder();
170 auto c = stacking.first();
171 auto stop = c;
172 int index = 0;
173 while (c) {
175 if (add) {
176 if (start == add) {
177 m_mutableClientList.removeAll(add);
178 m_mutableClientList.prepend(add);
179 } else {
180 m_mutableClientList += add;
181 }
182 }
183 if (index >= stacking.size() - 1) {
184 c = nullptr;
185 } else {
186 c = stacking[++index];
187 }
188
189 if (c == stop) {
190 break;
191 }
192 }
193}
194
195void ClientModel::createClientList(bool partialReset)
196{
197 auto start = tabBox->activeClient();
198 // TODO: new clients are not added at correct position
199 if (partialReset && !m_mutableClientList.isEmpty()) {
200 Window *firstClient = m_mutableClientList.constFirst();
201 if (!firstClient->isDeleted()) {
202 start = firstClient;
203 }
204 }
205
206 m_mutableClientList.clear();
207
208 switch (tabBox->config().clientSwitchingMode()) {
210 createFocusChainClientList(start);
211 break;
212 }
214 createStackingOrderClientList(start);
215 break;
216 }
217 }
218
220 // Put all non-minimized included clients first.
221 std::stable_partition(m_mutableClientList.begin(), m_mutableClientList.end(), [](const auto &client) {
222 return !client->isMinimized();
223 });
224 }
225
226 if (!m_mutableClientList.isEmpty()
229 Window *desktopClient = tabBox->desktopClient();
230 if (desktopClient) {
231 m_mutableClientList.append(desktopClient);
232 }
233 }
234
235 if (m_clientList == m_mutableClientList) {
236 return;
237 }
238
239 beginResetModel();
240 m_clientList = m_mutableClientList;
241 endResetModel();
242}
243
245{
246 QModelIndex ind = index(i, 0);
247 if (!ind.isValid()) {
248 return;
249 }
250 Window *client = m_mutableClientList.at(i);
251 if (client) {
252 client->closeWindow();
253 }
254}
255
257{
258 QModelIndex ind = index(i, 0);
259 if (!ind.isValid()) {
260 return;
261 }
264}
265
266} // namespace Tabbox
267} // namespace KWin
268
269#include "moc_clientmodel.cpp"
QHash< int, QByteArray > roleNames() const override
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
@ CloseableRole
Window can be closed.
Definition clientmodel.h:45
@ CaptionRole
The caption of Window.
Definition clientmodel.h:40
@ DesktopNameRole
The name of the desktop the Window is on.
Definition clientmodel.h:41
@ MinimizedRole
Window is minimized.
Definition clientmodel.h:44
@ WIdRole
The window ID of Window.
Definition clientmodel.h:43
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
QModelIndex parent(const QModelIndex &child) const override
ClientModel(QObject *parent=nullptr)
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void createClientList(bool partialReset=false)
Q_INVOKABLE QString longestCaption() const
int columnCount(const QModelIndex &parent=QModelIndex()) const override
ClientApplicationsMode clientApplicationsMode() const
@ AllWindowsCurrentApplication
Only Windows for the current application are included.
@ GroupByMinimized
Windows are grouped by whether they are minimized or not.
ClientSwitchingMode clientSwitchingMode() const
@ StackingOrderSwitching
Sort by current stacking order.
@ FocusChainSwitching
Sort by recently used. Most recently used Window is the first.
ShowDesktopMode showDesktopMode() const
@ ShowDesktopClient
A Window representing the desktop is included.
OrderMinimizedMode orderMinimizedMode() const
virtual Window * desktopClient() const =0
virtual Window * nextClientFocusChain(Window *client) const =0
virtual bool isInFocusChain(Window *client) const =0
virtual Window * firstClientFocusChain() const =0
virtual Window * clientToAddToList(Window *client) const =0
virtual QString desktopName(Window *client) const =0
virtual QList< Window * > stackingOrder() const =0
const TabBoxConfig & config() const
virtual Window * activeClient() const =0
void setCurrentIndex(const QModelIndex &index)
virtual void activateAndClose()=0
QUuid internalId
Definition window.h:259
QIcon icon
Definition window.h:327
virtual void closeWindow()=0
bool isMinimized() const
Definition window.h:988
bool isDesktop() const
Definition window.h:1922
virtual bool isCloseable() const =0
QString caption
Definition window.h:392
bool isDeleted() const
Definition window.cpp:540
TabBoxHandler * tabBox