From e89c09a62e3891abc6c85e79bc770ce1c8549ead Mon Sep 17 00:00:00 2001 From: Ismael Asensio Date: Thu, 2 Mar 2023 00:38:03 +0100 Subject: [PATCH] TabBox: Avoid unnecesary resets of the client model When the tabbox switcher is shown and any window is added or removed, its client model is fully reset, even if this window is not included in the model. This can be a bit expensive and also produce small visual quirks on certain switchers, so let's check if the window list changes before resetting the model. BUG: 466660 FIXED-IN: 5.27.3 --- src/tabbox/clientmodel.cpp | 48 +++++++++++++++++++++++++------------- src/tabbox/clientmodel.h | 8 +++---- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/tabbox/clientmodel.cpp b/src/tabbox/clientmodel.cpp index d6c6b1c91a..dd08bbef88 100644 --- a/src/tabbox/clientmodel.cpp +++ b/src/tabbox/clientmodel.cpp @@ -152,8 +152,9 @@ void ClientModel::createClientList(bool partialReset) createClientList(tabBox->currentDesktop(), partialReset); } -void ClientModel::createFocusChainClientList(int desktop, - const QSharedPointer &start, TabBoxClientList &stickyClients) +TabBoxClientList ClientModel::createFocusChainClientList(int desktop, + const QSharedPointer &start, + TabBoxClientList &stickyClients) const { auto c = start; if (!tabBox->isInFocusChain(c.data())) { @@ -163,23 +164,29 @@ void ClientModel::createFocusChainClientList(int desktop, } } auto stop = c; + + TabBoxClientList newClientList; do { QSharedPointer add = tabBox->clientToAddToList(c.data(), desktop); if (!add.isNull()) { - m_clientList += add; + newClientList += add; if (add.data()->isFirstInTabBox()) { stickyClients << add; } } c = tabBox->nextClientFocusChain(c.data()); } while (c && c != stop); + + return newClientList; } -void ClientModel::createStackingOrderClientList(int desktop, - const QSharedPointer &start, TabBoxClientList &stickyClients) +TabBoxClientList ClientModel::createStackingOrderClientList(int desktop, + const QSharedPointer &start, + TabBoxClientList &stickyClients) const { // TODO: needs improvement const TabBoxClientList stacking = tabBox->stackingOrder(); + TabBoxClientList newClientList; auto c = stacking.first().toStrongRef(); auto stop = c; int index = 0; @@ -187,10 +194,10 @@ void ClientModel::createStackingOrderClientList(int desktop, QSharedPointer add = tabBox->clientToAddToList(c.data(), desktop); if (!add.isNull()) { if (start == add.data()) { - m_clientList.removeAll(add); - m_clientList.prepend(add); + newClientList.removeAll(add); + newClientList.prepend(add); } else { - m_clientList += add; + newClientList += add; } if (add.data()->isFirstInTabBox()) { stickyClients << add; @@ -206,6 +213,8 @@ void ClientModel::createStackingOrderClientList(int desktop, break; } } + + return newClientList; } void ClientModel::createClientList(int desktop, bool partialReset) @@ -219,39 +228,46 @@ void ClientModel::createClientList(int desktop, bool partialReset) } } - beginResetModel(); - m_clientList.clear(); + TabBoxClientList newClientList; TabBoxClientList stickyClients; switch (tabBox->config().clientSwitchingMode()) { case TabBoxConfig::FocusChainSwitching: { - createFocusChainClientList(desktop, start, stickyClients); + newClientList = createFocusChainClientList(desktop, start, stickyClients); break; } case TabBoxConfig::StackingOrderSwitching: { - createStackingOrderClientList(desktop, start, stickyClients); + newClientList = createStackingOrderClientList(desktop, start, stickyClients); break; } } if (tabBox->config().orderMinimizedMode() == TabBoxConfig::GroupByMinimized) { // Put all non-minimized included clients first. - std::stable_partition(m_clientList.begin(), m_clientList.end(), [](const auto &client) { + std::stable_partition(newClientList.begin(), newClientList.end(), [](const auto &client) { return !client.toStrongRef()->isMinimized(); }); } for (const QWeakPointer &c : std::as_const(stickyClients)) { - m_clientList.removeAll(c); - m_clientList.prepend(c); + newClientList.removeAll(c); + newClientList.prepend(c); } + if (tabBox->config().clientApplicationsMode() != TabBoxConfig::AllWindowsCurrentApplication && (tabBox->config().showDesktopMode() == TabBoxConfig::ShowDesktopClient || m_clientList.isEmpty())) { QWeakPointer desktopClient = tabBox->desktopClient(); if (!desktopClient.isNull()) { - m_clientList.append(desktopClient); + newClientList.append(desktopClient); } } + + if (m_clientList == newClientList) { + return; + } + + beginResetModel(); + m_clientList = newClientList; endResetModel(); } diff --git a/src/tabbox/clientmodel.h b/src/tabbox/clientmodel.h index e1e0dbe1b4..6f1336ead6 100644 --- a/src/tabbox/clientmodel.h +++ b/src/tabbox/clientmodel.h @@ -93,10 +93,10 @@ public Q_SLOTS: void activate(int index); private: - void createFocusChainClientList(int desktop, const QSharedPointer &start, - TabBoxClientList &stickyClients); - void createStackingOrderClientList(int desktop, const QSharedPointer &start, - TabBoxClientList &stickyClients); + TabBoxClientList createFocusChainClientList(int desktop, const QSharedPointer &start, + TabBoxClientList &stickyClients) const; + TabBoxClientList createStackingOrderClientList(int desktop, const QSharedPointer &start, + TabBoxClientList &stickyClients) const; TabBoxClientList m_clientList; };