diff --git a/libtaskmanager/xwindowtasksmodel.cpp b/libtaskmanager/xwindowtasksmodel.cpp --- a/libtaskmanager/xwindowtasksmodel.cpp +++ b/libtaskmanager/xwindowtasksmodel.cpp @@ -61,6 +61,7 @@ QMultiHash transientsDemandingAttention; QHash windowInfoCache; QHash appDataCache; + QHash m_urlFromMetadataCache; QHash delegateGeometries; QSet usingFallbackIcon; WId activeWindow = -1; @@ -254,6 +255,7 @@ appDataCache.remove(window); usingFallbackIcon.remove(window); delegateGeometries.remove(window); + m_urlFromMetadataCache.remove(window); q->endRemoveRows(); } else { // Could be a transient. // Removing a transient might change the demands attention state of the leader. @@ -402,7 +404,7 @@ KWindowInfo* XWindowTasksModel::Private::windowInfo(WId window) { - const auto &it = windowInfoCache.constFind(window); + const auto it = windowInfoCache.constFind(window); if (it != windowInfoCache.constEnd()) { return *it; @@ -416,7 +418,7 @@ AppData XWindowTasksModel::Private::appData(WId window) { - const auto &it = appDataCache.constFind(window); + const auto it = appDataCache.constFind(window); if (it != appDataCache.constEnd()) { return *it; @@ -504,9 +506,18 @@ } } - return windowUrlFromMetadata(info->windowClassClass(), + // Use a cache, windowUrlFromMetadata is quite expensive and can be called too many times. + const auto it = m_urlFromMetadataCache.constFind(window); + + if (it != m_urlFromMetadataCache.constEnd()) { + return *it; + } + + const auto url = windowUrlFromMetadata(info->windowClassClass(), NETWinInfo(QX11Info::connection(), window, QX11Info::appRootWindow(), NET::WMPid, 0).pid(), rulesConfig, info->windowClassName()); + m_urlFromMetadataCache.insert(window, url); + return url; } QUrl XWindowTasksModel::Private::launcherUrl(WId window, bool encodeFallbackIcon) @@ -574,11 +585,11 @@ } else if (role == Qt::DecorationRole) { return d->icon(window); } else if (role == AppId) { - return d->appData(window).id; + return d->windowInfo(window)->windowClassClass(); } else if (role == AppName) { - return d->appData(window).name; + return d->windowInfo(window)->name(); } else if (role == GenericName) { - return d->appData(window).genericName; + return d->windowInfo(window)->windowClassName(); } else if (role == LauncherUrl) { return d->launcherUrl(window); } else if (role == LauncherUrlWithoutIcon) {