From 057b58b76df0dfc71fb1dcfe4dc64de1df300585 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Mon, 2 Oct 2023 22:15:46 +0300 Subject: [PATCH] libs: rework KTaskManager to not cache information other than the window ID otherwise the name and desktop number have to be refreshed each time a task window changes and that information may or may not be used in, say, the pager applet Signed-off-by: Ivailo Monev --- libs/kworkspace/ktaskmanager.cpp | 133 +++++++----------- libs/kworkspace/ktaskmanager.h | 29 ++-- plasma/applets/pager/pager.cpp | 55 ++++---- .../switchwindow/switch.cpp | 31 ++-- 4 files changed, 104 insertions(+), 144 deletions(-) diff --git a/libs/kworkspace/ktaskmanager.cpp b/libs/kworkspace/ktaskmanager.cpp index a024d070..56b79374 100644 --- a/libs/kworkspace/ktaskmanager.cpp +++ b/libs/kworkspace/ktaskmanager.cpp @@ -48,110 +48,63 @@ static bool kIsTaskWindow(const WId window) return true; } -static void kUpdateTask(KTaskManager::Task &task, const bool force = false) +class KTaskManagerPrivate { - const KWindowInfo kwindowinfo = KWindowSystem::windowInfo( - task.window, - NET::WMVisibleName | NET::WMDesktop - ); - if (task.name.isEmpty() || force) { - task.name = kwindowinfo.visibleName(); - } - task.desktop = kwindowinfo.desktop(); -} - -class KTaskManagerPrivate : QObject -{ - Q_OBJECT public: - KTaskManagerPrivate(QObject *parent); + KTaskManagerPrivate(KTaskManager *ktaskmanager); - QList tasks; + QList tasks; -private Q_SLOTS: - void slotNewWindow(const WId window); - void slotChangedWindow(const WId window); - void slotRemovedWindow(const WId window); + void _k_slotNewWindow(const WId window); + void _k_slotChangedWindow(const WId window); + void _k_slotRemovedWindow(const WId window); private: QMutex m_mutex; + KTaskManager* m_taskmanager; }; -KTaskManagerPrivate::KTaskManagerPrivate(QObject *parent) - : QObject(parent) +KTaskManagerPrivate::KTaskManagerPrivate(KTaskManager *ktaskmanager) + : m_taskmanager(ktaskmanager) { foreach (const WId window, KWindowSystem::stackingOrder()) { if (!kIsTaskWindow(window)) { continue; } - kDebug() << "adding task for" << window; - KTaskManager::Task task; - task.window = window; - task.desktop = s_nodesktop; - kUpdateTask(task); - tasks.append(task); - KTaskManager* ktaskmanager = qobject_cast(parent); - emit ktaskmanager->taskAdded(task); + kDebug() << "adding task window" << window; + tasks.append(window); + emit m_taskmanager->taskAdded(window); } - connect( - KWindowSystem::self(), SIGNAL(windowAdded(WId)), - this, SLOT(slotNewWindow(WId)) - ); - connect( - KWindowSystem::self(), SIGNAL(windowChanged(WId)), - this, SLOT(slotChangedWindow(WId)) - ); - connect( - KWindowSystem::self(), SIGNAL(windowRemoved(WId)), - this, SLOT(slotRemovedWindow(WId)) - ); } -void KTaskManagerPrivate::slotNewWindow(const WId window) +void KTaskManagerPrivate::_k_slotNewWindow(const WId window) { if (!kIsTaskWindow(window)) { return; } QMutexLocker locker(&m_mutex); - kDebug() << "new window task for" << window; - KTaskManager::Task task; - task.window = window; - task.desktop = s_nodesktop; - kUpdateTask(task); - tasks.append(task); - KTaskManager* ktaskmanager = qobject_cast(parent()); - emit ktaskmanager->taskAdded(task); + kDebug() << "new task window" << window; + tasks.append(window); + emit m_taskmanager->taskAdded(window); } -void KTaskManagerPrivate::slotChangedWindow(const WId window) +void KTaskManagerPrivate::_k_slotChangedWindow(const WId window) { QMutexLocker locker(&m_mutex); - QMutableListIterator iter(tasks); - while (iter.hasNext()) { - KTaskManager::Task &task = iter.next(); - if (task.window == window) { - kDebug() << "changed window task for" << window; - kUpdateTask(task, true); - KTaskManager* ktaskmanager = qobject_cast(parent()); - emit ktaskmanager->taskChanged(task); - break; - } + if (tasks.contains(window)) { + kDebug() << "changed task window" << window; + emit m_taskmanager->taskChanged(window); } } -void KTaskManagerPrivate::slotRemovedWindow(const WId window) +void KTaskManagerPrivate::_k_slotRemovedWindow(const WId window) { QMutexLocker locker(&m_mutex); - QMutableListIterator iter(tasks); - while (iter.hasNext()) { - const KTaskManager::Task task = iter.next(); - if (task.window == window) { - kDebug() << "removed window task for" << window; - iter.remove(); - KTaskManager* ktaskmanager = qobject_cast(parent()); - emit ktaskmanager->taskRemoved(task); - break; - } + const int indexofwindow = tasks.indexOf(window); + if (indexofwindow >= 0) { + kDebug() << "removed task window" << window; + tasks.removeAt(indexofwindow); + emit m_taskmanager->taskRemoved(window); } } @@ -163,6 +116,18 @@ KTaskManager::KTaskManager(QObject *parent) d(nullptr) { d = new KTaskManagerPrivate(this); + connect( + KWindowSystem::self(), SIGNAL(windowAdded(WId)), + this, SLOT(_k_slotNewWindow(WId)) + ); + connect( + KWindowSystem::self(), SIGNAL(windowChanged(WId)), + this, SLOT(_k_slotChangedWindow(WId)) + ); + connect( + KWindowSystem::self(), SIGNAL(windowRemoved(WId)), + this, SLOT(_k_slotRemovedWindow(WId)) + ); } KTaskManager::~KTaskManager() @@ -170,41 +135,41 @@ KTaskManager::~KTaskManager() delete d; } -QList KTaskManager::tasks() const +QList KTaskManager::tasks() const { return d->tasks; } -bool KTaskManager::isActive(const KTaskManager::Task &task) +bool KTaskManager::isActive(const WId task) { const WId activewindow = KWindowSystem::activeWindow(); - return (task.window == activewindow || KWindowSystem::transientFor(task.window) == activewindow); + return (task == activewindow || KWindowSystem::transientFor(task) == activewindow); } -bool KTaskManager::demandsAttention(const KTaskManager::Task &task) +bool KTaskManager::demandsAttention(const WId task) { KWindowInfo kwindowinfo = KWindowSystem::windowInfo( - task.window, + task, NET::WMState | NET::XAWMState ); if (kwindowinfo.hasState(NET::DemandsAttention)) { return true; } kwindowinfo = KWindowSystem::windowInfo( - KWindowSystem::transientFor(task.window), + KWindowSystem::transientFor(task), NET::WMState | NET::XAWMState ); return kwindowinfo.hasState(NET::DemandsAttention); } -void KTaskManager::activateRaiseOrIconify(const KTaskManager::Task &task) +void KTaskManager::activateRaiseOrIconify(const WId task) { if (isActive(task)) { - KWindowSystem::minimizeWindow(task.window); + KWindowSystem::minimizeWindow(task); return; } - KWindowSystem::activateWindow(task.window); - KWindowSystem::raiseWindow(task.window); + KWindowSystem::activateWindow(task); + KWindowSystem::raiseWindow(task); } KTaskManager* KTaskManager::self() @@ -212,4 +177,4 @@ KTaskManager* KTaskManager::self() return globalktaskmanager; } -#include "ktaskmanager.moc" +#include "moc_ktaskmanager.cpp" diff --git a/libs/kworkspace/ktaskmanager.h b/libs/kworkspace/ktaskmanager.h index 22dc1785..f7029dcc 100644 --- a/libs/kworkspace/ktaskmanager.h +++ b/libs/kworkspace/ktaskmanager.h @@ -22,7 +22,7 @@ #include "kworkspace_export.h" #include -#include +#include class KTaskManagerPrivate; @@ -30,34 +30,29 @@ class KWORKSPACE_EXPORT KTaskManager : public QObject { Q_OBJECT public: - struct Task - { - QString name; - int desktop; - WId window; - }; - KTaskManager(QObject *parent = nullptr); ~KTaskManager(); - QList tasks() const; - static bool isActive(const KTaskManager::Task &task); - static bool demandsAttention(const KTaskManager::Task &task); - static void activateRaiseOrIconify(const KTaskManager::Task &task); + QList tasks() const; + static bool isActive(const WId task); + static bool demandsAttention(const WId task); + static void activateRaiseOrIconify(const WId task); static KTaskManager* self(); Q_SIGNALS: - void taskAdded(const KTaskManager::Task &task); - void taskChanged(const KTaskManager::Task &task); - void taskRemoved(const KTaskManager::Task &task); + void taskAdded(const WId task); + void taskChanged(const WId task); + void taskRemoved(const WId task); private: friend KTaskManagerPrivate; Q_DISABLE_COPY(KTaskManager); KTaskManagerPrivate* d; + + Q_PRIVATE_SLOT(d, void _k_slotNewWindow(const WId window)); + Q_PRIVATE_SLOT(d, void _k_slotChangedWindow(const WId window)); + Q_PRIVATE_SLOT(d, void _k_slotRemovedWindow(const WId window)); }; -Q_DECLARE_METATYPE(KTaskManager::Task); - #endif // KTASKMANAGER_H diff --git a/plasma/applets/pager/pager.cpp b/plasma/applets/pager/pager.cpp index 8fd074ba..780e4c6b 100644 --- a/plasma/applets/pager/pager.cpp +++ b/plasma/applets/pager/pager.cpp @@ -93,13 +93,13 @@ class PagerDialog : public Plasma::Dialog public: explicit PagerDialog(QWidget *parent = nullptr); - void updateTasks(const QList &tasks); + void updateTasks(const QList &tasks); private: QGraphicsScene* m_scene; QGraphicsWidget* m_widget; QGraphicsLinearLayout* m_layout; - QList m_tasks; + QList m_tasks; }; PagerDialog::PagerDialog(QWidget *parent) @@ -121,7 +121,7 @@ PagerDialog::PagerDialog(QWidget *parent) setGraphicsWidget(m_widget); } -void PagerDialog::updateTasks(const QList &tasks) +void PagerDialog::updateTasks(const QList &tasks) { // TODO: m_tasks = tasks; @@ -132,7 +132,7 @@ class PagerIcon : public Plasma::IconWidget { Q_OBJECT public: - explicit PagerIcon(const KTaskManager::Task &task, QGraphicsItem *parent); + explicit PagerIcon(const WId task, QGraphicsItem *parent); WId taskWindow() const; void animatedShow(); @@ -144,10 +144,10 @@ private Q_SLOTS: void slotWindowPreviewActivated(const WId window); private: - KTaskManager::Task m_task; + WId m_task; }; -PagerIcon::PagerIcon(const KTaskManager::Task &task, QGraphicsItem *parent) +PagerIcon::PagerIcon(const WId task, QGraphicsItem *parent) : Plasma::IconWidget(parent), m_task(task) { @@ -164,7 +164,7 @@ PagerIcon::PagerIcon(const KTaskManager::Task &task, QGraphicsItem *parent) WId PagerIcon::taskWindow() const { - return m_task.window; + return m_task; } void PagerIcon::animatedShow() @@ -190,10 +190,11 @@ void PagerIcon::animatedRemove() void PagerIcon::updateIconAndToolTip() { - setIcon(KWindowSystem::icon(m_task.window)); + const KWindowInfo kwindowinfo = KWindowSystem::windowInfo(m_task, NET::WMVisibleName); + setIcon(KWindowSystem::icon(m_task)); Plasma::ToolTipContent plasmatooltip; - plasmatooltip.setMainText(QString::fromLatin1("
%1
").arg(m_task.name)); - plasmatooltip.setWindowToPreview(m_task.window); + plasmatooltip.setMainText(QString::fromLatin1("
%1
").arg(kwindowinfo.visibleName())); + plasmatooltip.setWindowToPreview(m_task); plasmatooltip.setClickable(true); Plasma::ToolTipManager::self()->setContent(this, plasmatooltip); } @@ -230,9 +231,9 @@ private Q_SLOTS: void slotClicked(const Qt::MouseButton button); void slotUpdate(); void slotUpdateSvg(); - void slotTaskAdded(const KTaskManager::Task &task); - void slotTaskChanged(const KTaskManager::Task &task); - void slotTaskRemoved(const KTaskManager::Task &task); + void slotTaskAdded(const WId task); + void slotTaskChanged(const WId task); + void slotTaskRemoved(const WId task); void slotCheckSpace(); void slotShowDialog(); @@ -264,7 +265,7 @@ PagerSvg::PagerSvg(const int desktop, const Qt::Orientation orientation, QGraphi slotUpdateSvg(); setAcceptHoverEvents(true); - foreach (const KTaskManager::Task &task, KTaskManager::self()->tasks()) { + foreach (const WId task, KTaskManager::self()->tasks()) { slotTaskAdded(task); } @@ -277,16 +278,16 @@ PagerSvg::PagerSvg(const int desktop, const Qt::Orientation orientation, QGraphi this, SLOT(slotUpdate()) ); connect( - KTaskManager::self(), SIGNAL(taskAdded(KTaskManager::Task)), - this, SLOT(slotTaskAdded(KTaskManager::Task)) + KTaskManager::self(), SIGNAL(taskAdded(WId)), + this, SLOT(slotTaskAdded(WId)) ); connect( - KTaskManager::self(), SIGNAL(taskChanged(KTaskManager::Task)), - this, SLOT(slotTaskChanged(KTaskManager::Task)) + KTaskManager::self(), SIGNAL(taskChanged(WId)), + this, SLOT(slotTaskChanged(WId)) ); connect( - KTaskManager::self(), SIGNAL(taskRemoved(KTaskManager::Task)), - this, SLOT(slotTaskRemoved(KTaskManager::Task)) + KTaskManager::self(), SIGNAL(taskRemoved(WId)), + this, SLOT(slotTaskRemoved(WId)) ); connect( Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), @@ -355,13 +356,13 @@ void PagerSvg::slotUpdateSvg() } } -void PagerSvg::slotTaskAdded(const KTaskManager::Task &task) +void PagerSvg::slotTaskAdded(const WId task) { QMutexLocker locker(&m_mutex); if (m_spacer) { m_layout->removeItem(m_spacer); } - const KWindowInfo kwindowinfo = KWindowSystem::windowInfo(task.window, NET::WMDesktop); + const KWindowInfo kwindowinfo = KWindowSystem::windowInfo(task, NET::WMDesktop); if (kwindowinfo.isOnDesktop(m_desktop)) { PagerIcon* pagericon = new PagerIcon(task, this); connect( @@ -393,18 +394,18 @@ void PagerSvg::slotTaskAdded(const KTaskManager::Task &task) slotCheckSpace(); } -void PagerSvg::slotTaskChanged(const KTaskManager::Task &task) +void PagerSvg::slotTaskChanged(const WId task) { // special case for tasks moved from one virtual desktop to another, the check is done via // KWindowInfo::isOnDesktop() because tasks may be shown on all desktops - const KWindowInfo kwindowinfo = KWindowSystem::windowInfo(task.window, NET::WMDesktop); + const KWindowInfo kwindowinfo = KWindowSystem::windowInfo(task, NET::WMDesktop); if (!kwindowinfo.isOnDesktop(m_desktop)) { slotTaskRemoved(task); } else { QMutexLocker locker(&m_mutex); PagerIcon* foundpagericon = nullptr; foreach (PagerIcon* pagericon, m_pagericons) { - if (pagericon->taskWindow() == task.window) { + if (pagericon->taskWindow() == task) { foundpagericon = pagericon; break; } @@ -418,11 +419,11 @@ void PagerSvg::slotTaskChanged(const KTaskManager::Task &task) } } -void PagerSvg::slotTaskRemoved(const KTaskManager::Task &task) +void PagerSvg::slotTaskRemoved(const WId task) { QMutexLocker locker(&m_mutex); foreach (PagerIcon* pagericon, m_pagericons) { - if (pagericon->taskWindow() == task.window) { + if (pagericon->taskWindow() == task) { m_pagericons.removeAll(pagericon); pagericon->animatedRemove(); break; diff --git a/plasma/containmentactions/switchwindow/switch.cpp b/plasma/containmentactions/switchwindow/switch.cpp index 8af3404d..273e5ddb 100644 --- a/plasma/containmentactions/switchwindow/switch.cpp +++ b/plasma/containmentactions/switchwindow/switch.cpp @@ -104,16 +104,21 @@ void SwitchWindow::makeMenu() QMultiHash desktops; // make all the window actions - foreach (const KTaskManager::Task &task, KTaskManager::self()->tasks()) { - if (task.name.isEmpty()) { - kDebug() << "skipping task with empty name" << task.window; + foreach (const WId task, KTaskManager::self()->tasks()) { + const KWindowInfo kwindowinfo = KWindowSystem::windowInfo( + task, + NET::WMVisibleName | NET::WMDesktop + ); + const QString taskname = kwindowinfo.visibleName(); + if (taskname.isEmpty()) { + kDebug() << "skipping task with empty name" << task; continue; } - QAction *action = new QAction(task.name, m_menu); - action->setIcon(KIcon(KWindowSystem::icon(task.window))); - action->setData(qlonglong(task.window)); - desktops.insert(task.desktop, action); + QAction *action = new QAction(taskname, m_menu); + action->setIcon(KIcon(KWindowSystem::icon(task))); + action->setData(qlonglong(task)); + desktops.insert(kwindowinfo.desktop(), action); } //sort into menu @@ -180,15 +185,9 @@ QList SwitchWindow::contextualActions() void SwitchWindow::switchTo(QAction *action) { - const qlonglong taskwindow = action->data().toLongLong(); - kDebug() << "task window" << taskwindow; - foreach (const KTaskManager::Task &task, KTaskManager::self()->tasks()) { - if (task.window == taskwindow) { - KTaskManager::self()->activateRaiseOrIconify(task); - return; - } - } - kWarning() << "could not find the task window"; + const qlonglong task = action->data().toLongLong(); + kDebug() << "task window" << task; + KTaskManager::self()->activateRaiseOrIconify(task); } void SwitchWindow::clearWindowsOrder()