// SPDX-FileCopyrightText: 2021 Vlad Zahorodnii // SPDX-FileCopyrightText: 2024 Devin Lin // SPDX-License-Identifier: GPL-2.0-or-later #include "taskfiltermodel.h" // KWin #include #include #include #include #include namespace KWin { TaskFilterModel::TaskFilterModel(QObject *parent) : QSortFilterProxyModel(parent) { setSortRole(TaskModel::LastActivatedRole); // Don't auto-sort, because this model is loaded at runtime during the task switcher // -> We don't want to re-sort while the task switcher is open setDynamicSortFilter(false); } TaskModel *TaskFilterModel::windowModel() const { return m_taskModel; } void TaskFilterModel::setWindowModel(TaskModel *taskModel) { if (taskModel == m_taskModel) { return; } m_taskModel = taskModel; setSourceModel(m_taskModel); Q_EMIT windowModelChanged(); // Sort after source model is set sort(0); } QString TaskFilterModel::screenName() const { return m_output ? m_output->name() : QString(); } void TaskFilterModel::setScreenName(const QString &screen) { Output *output = kwinApp()->outputBackend()->findOutput(screen); if (m_output != output) { m_output = output; Q_EMIT screenNameChanged(); invalidateFilter(); } } bool TaskFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { if (!m_taskModel) { return false; } const QModelIndex index = m_taskModel->index(sourceRow, 0, sourceParent); if (!index.isValid()) { return false; } const QVariant data = index.data(); if (!data.isValid()) { // an invalid QVariant is valid data return true; } Window *window = qvariant_cast(data); if (!window || !window->isClient()) { return false; } // Filter by same activity auto activity = Workspace::self()->activities()->current(); if (!window->isOnActivity(activity)) { return false; } // Filter by same desktop auto desktop = VirtualDesktopManager::self()->currentDesktop(); if (!window->isOnDesktop(desktop)) { return false; } // Filter by same screen if (window->output() != m_output) { return false; } if (window->isDock()) { return false; } if (window->isDesktop()) { return false; } if (window->isNotification()) { return false; } if (window->isCriticalNotification()) { return false; } if (window->skipSwitcher()) { return false; } return true; } bool TaskFilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { qint64 leftLastActivated = qvariant_cast(left.data(TaskModel::LastActivatedRole)); qint64 rightLastActivated = qvariant_cast(right.data(TaskModel::LastActivatedRole)); // Sort order: oldest -> newest // - For ties: alphabetically if (leftLastActivated != rightLastActivated) { return leftLastActivated > rightLastActivated; } else { // If leftLastActivated == rightLastActivated, sort alphabetically by window title Window *leftWindow = qvariant_cast(left.data(TaskModel::WindowRole)); Window *rightWindow = qvariant_cast(right.data(TaskModel::WindowRole)); if (!leftWindow || !rightWindow) { return true; } return leftWindow->caption() < rightWindow->caption(); } } } // namespace KWin