KWin
Loading...
Searching...
No Matches
windowmodel.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "windowmodel.h"
8#include "core/output.h"
10#include "virtualdesktops.h"
11#include "window.h"
12#include "workspace.h"
13
14namespace KWin
15{
16
18 : QAbstractListModel(parent)
19{
20 connect(workspace(), &Workspace::windowAdded, this, &WindowModel::handleWindowAdded);
21 connect(workspace(), &Workspace::windowRemoved, this, &WindowModel::handleWindowRemoved);
22
23 m_windows = workspace()->windows();
24 for (Window *window : std::as_const(m_windows)) {
25 setupWindowConnections(window);
26 }
27}
28
29void WindowModel::markRoleChanged(Window *window, int role)
30{
31 const QModelIndex row = index(m_windows.indexOf(window), 0);
32 Q_EMIT dataChanged(row, row, {role});
33}
34
35void WindowModel::setupWindowConnections(Window *window)
36{
37 connect(window, &Window::desktopsChanged, this, [this, window]() {
38 markRoleChanged(window, DesktopRole);
39 });
40 connect(window, &Window::outputChanged, this, [this, window]() {
41 markRoleChanged(window, OutputRole);
42 });
43 connect(window, &Window::activitiesChanged, this, [this, window]() {
44 markRoleChanged(window, ActivityRole);
45 });
46}
47
48void WindowModel::handleWindowAdded(Window *window)
49{
50 beginInsertRows(QModelIndex(), m_windows.count(), m_windows.count());
51 m_windows.append(window);
52 endInsertRows();
53
54 setupWindowConnections(window);
55}
56
57void WindowModel::handleWindowRemoved(Window *window)
58{
59 const int index = m_windows.indexOf(window);
60 Q_ASSERT(index != -1);
61
62 beginRemoveRows(QModelIndex(), index, index);
63 m_windows.removeAt(index);
64 endRemoveRows();
65}
66
67QHash<int, QByteArray> WindowModel::roleNames() const
68{
69 return {
70 {Qt::DisplayRole, QByteArrayLiteral("display")},
71 {WindowRole, QByteArrayLiteral("window")},
72 {OutputRole, QByteArrayLiteral("output")},
73 {DesktopRole, QByteArrayLiteral("desktop")},
74 {ActivityRole, QByteArrayLiteral("activity")},
75 };
76}
77
78QVariant WindowModel::data(const QModelIndex &index, int role) const
79{
80 if (!index.isValid() || index.row() < 0 || index.row() >= m_windows.count()) {
81 return QVariant();
82 }
83
84 Window *window = m_windows[index.row()];
85 switch (role) {
86 case Qt::DisplayRole:
87 case WindowRole:
88 return QVariant::fromValue(window);
89 case OutputRole:
90 return QVariant::fromValue(window->output());
91 case DesktopRole:
92 return QVariant::fromValue(window->desktops());
93 case ActivityRole:
94 return window->activities();
95 default:
96 return QVariant();
97 }
98}
99
100int WindowModel::rowCount(const QModelIndex &parent) const
101{
102 return parent.isValid() ? 0 : m_windows.count();
103}
104
106 : QSortFilterProxyModel(parent)
107{
108}
109
111{
112 return m_windowModel;
113}
114
116{
117 if (windowModel == m_windowModel) {
118 return;
119 }
120 m_windowModel = windowModel;
121 setSourceModel(m_windowModel);
122 Q_EMIT windowModelChanged();
123}
124
126{
127 return m_activity.value_or(QString());
128}
129
130void WindowFilterModel::setActivity(const QString &activity)
131{
132 if (m_activity != activity) {
133 m_activity = activity;
134 Q_EMIT activityChanged();
135 invalidateFilter();
136 }
137}
138
140{
141 if (m_activity.has_value()) {
142 m_activity.reset();
143 Q_EMIT activityChanged();
144 invalidateFilter();
145 }
146}
147
149{
150 return m_desktop;
151}
152
154{
155 if (m_desktop != desktop) {
156 m_desktop = desktop;
157 Q_EMIT desktopChanged();
158 invalidateFilter();
159 }
160}
161
163{
164 setDesktop(nullptr);
165}
166
168{
169 return m_filter;
170}
171
172void WindowFilterModel::setFilter(const QString &filter)
173{
174 if (filter == m_filter) {
175 return;
176 }
177 m_filter = filter;
178 Q_EMIT filterChanged();
179 invalidateFilter();
180}
181
183{
184 return m_output ? m_output->name() : QString();
185}
186
187void WindowFilterModel::setScreenName(const QString &screen)
188{
189 Output *output = kwinApp()->outputBackend()->findOutput(screen);
190 if (m_output != output) {
191 m_output = output;
192 Q_EMIT screenNameChanged();
193 invalidateFilter();
194 }
195}
196
198{
199 if (m_output) {
200 m_output = nullptr;
201 Q_EMIT screenNameChanged();
202 invalidateFilter();
203 }
204}
205
206WindowFilterModel::WindowTypes WindowFilterModel::windowType() const
207{
208 return m_windowType.value_or(WindowTypes());
209}
210
211void WindowFilterModel::setWindowType(WindowTypes windowType)
212{
213 if (m_windowType != windowType) {
214 m_windowType = windowType;
215 Q_EMIT windowTypeChanged();
216 invalidateFilter();
217 }
218}
219
221{
222 if (m_windowType.has_value()) {
223 m_windowType.reset();
224 Q_EMIT windowTypeChanged();
225 invalidateFilter();
226 }
227}
228
230{
231 if (m_showMinimizedWindows == show) {
232 return;
233 }
234
235 m_showMinimizedWindows = show;
236 invalidateFilter();
238}
239
241{
242 return m_showMinimizedWindows;
243}
244
245bool WindowFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
246{
247 if (!m_windowModel) {
248 return false;
249 }
250 const QModelIndex index = m_windowModel->index(sourceRow, 0, sourceParent);
251 if (!index.isValid()) {
252 return false;
253 }
254 const QVariant data = index.data();
255 if (!data.isValid()) {
256 // an invalid QVariant is valid data
257 return true;
258 }
259
260 Window *window = qvariant_cast<Window *>(data);
261 if (!window) {
262 return false;
263 }
264
265 if (m_activity.has_value()) {
266 if (!window->isOnActivity(*m_activity)) {
267 return false;
268 }
269 }
270
271 if (m_desktop) {
272 if (!window->isOnDesktop(m_desktop)) {
273 return false;
274 }
275 }
276
277 if (m_output) {
278 if (!window->isOnOutput(m_output)) {
279 return false;
280 }
281 }
282
283 if (m_windowType.has_value()) {
284 if (!(windowTypeMask(window) & *m_windowType)) {
285 return false;
286 }
287 }
288
289 if (!m_filter.isEmpty()) {
290 if (window->caption().contains(m_filter, Qt::CaseInsensitive)) {
291 return true;
292 }
293 if (window->windowRole().contains(m_filter, Qt::CaseInsensitive)) {
294 return true;
295 }
296 if (window->resourceName().contains(m_filter, Qt::CaseInsensitive)) {
297 return true;
298 }
299 if (window->resourceClass().contains(m_filter, Qt::CaseInsensitive)) {
300 return true;
301 }
302 return false;
303 }
304
305 if (!m_showMinimizedWindows) {
306 return !window->isMinimized();
307 }
308 return true;
309}
310
311WindowFilterModel::WindowTypes WindowFilterModel::windowTypeMask(Window *window) const
312{
313 WindowTypes mask;
314 if (window->isNormalWindow()) {
315 mask |= WindowType::Normal;
316 } else if (window->isDialog()) {
317 mask |= WindowType::Dialog;
318 } else if (window->isDock()) {
319 mask |= WindowType::Dock;
320 } else if (window->isDesktop()) {
321 mask |= WindowType::Desktop;
322 } else if (window->isNotification()) {
324 } else if (window->isCriticalNotification()) {
326 }
327 return mask;
328}
329
330} // namespace KWin
331
332#include "moc_windowmodel.cpp"
KWin::VirtualDesktop * desktop
Definition windowmodel.h:55
void setFilter(const QString &filter)
void setDesktop(VirtualDesktop *desktop)
WindowModel * windowModel
Definition windowmodel.h:53
void setMinimizedWindows(bool show)
void setWindowModel(WindowModel *windowModel)
WindowFilterModel(QObject *parent=nullptr)
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
void setScreenName(const QString &screenName)
void setActivity(const QString &activity)
void setWindowType(WindowTypes windowType)
bool isOnActivity(const QString &activity) const
Definition window.h:2042
bool isNotification() const
Definition window.h:1977
bool isDialog() const
Definition window.h:1952
bool isNormalWindow() const
Definition window.h:1957
bool isCriticalNotification() const
Definition window.h:1982
void outputChanged()
bool isMinimized() const
Definition window.h:988
void desktopsChanged()
QString resourceClass
Definition window.h:115
bool isDesktop() const
Definition window.h:1922
QList< KWin::VirtualDesktop * > desktops
Definition window.h:295
QString resourceName
Definition window.h:114
QString caption
Definition window.h:392
QStringList activities
Definition window.h:305
bool isOnDesktop(VirtualDesktop *desktop) const
Definition window.cpp:843
bool isDock() const
Definition window.h:1927
void activitiesChanged()
KWin::Output * output
Definition window.h:111
bool isOnOutput(Output *output) const
Definition window.cpp:254
QString windowRole
Definition window.h:116
WindowModel(QObject *parent=nullptr)
int rowCount(const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QHash< int, QByteArray > roleNames() const override
void windowRemoved(KWin::Window *)
void windowAdded(KWin::Window *)
const QList< Window * > windows() const
Definition workspace.h:248
Workspace * workspace()
Definition workspace.h:830