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
This commit is contained in:
Ismael Asensio 2023-03-02 00:38:03 +01:00
parent 83398dce7b
commit e89c09a62e
2 changed files with 36 additions and 20 deletions

View file

@ -152,8 +152,9 @@ void ClientModel::createClientList(bool partialReset)
createClientList(tabBox->currentDesktop(), partialReset); createClientList(tabBox->currentDesktop(), partialReset);
} }
void ClientModel::createFocusChainClientList(int desktop, TabBoxClientList ClientModel::createFocusChainClientList(int desktop,
const QSharedPointer<TabBoxClient> &start, TabBoxClientList &stickyClients) const QSharedPointer<TabBoxClient> &start,
TabBoxClientList &stickyClients) const
{ {
auto c = start; auto c = start;
if (!tabBox->isInFocusChain(c.data())) { if (!tabBox->isInFocusChain(c.data())) {
@ -163,23 +164,29 @@ void ClientModel::createFocusChainClientList(int desktop,
} }
} }
auto stop = c; auto stop = c;
TabBoxClientList newClientList;
do { do {
QSharedPointer<TabBoxClient> add = tabBox->clientToAddToList(c.data(), desktop); QSharedPointer<TabBoxClient> add = tabBox->clientToAddToList(c.data(), desktop);
if (!add.isNull()) { if (!add.isNull()) {
m_clientList += add; newClientList += add;
if (add.data()->isFirstInTabBox()) { if (add.data()->isFirstInTabBox()) {
stickyClients << add; stickyClients << add;
} }
} }
c = tabBox->nextClientFocusChain(c.data()); c = tabBox->nextClientFocusChain(c.data());
} while (c && c != stop); } while (c && c != stop);
return newClientList;
} }
void ClientModel::createStackingOrderClientList(int desktop, TabBoxClientList ClientModel::createStackingOrderClientList(int desktop,
const QSharedPointer<TabBoxClient> &start, TabBoxClientList &stickyClients) const QSharedPointer<TabBoxClient> &start,
TabBoxClientList &stickyClients) const
{ {
// TODO: needs improvement // TODO: needs improvement
const TabBoxClientList stacking = tabBox->stackingOrder(); const TabBoxClientList stacking = tabBox->stackingOrder();
TabBoxClientList newClientList;
auto c = stacking.first().toStrongRef(); auto c = stacking.first().toStrongRef();
auto stop = c; auto stop = c;
int index = 0; int index = 0;
@ -187,10 +194,10 @@ void ClientModel::createStackingOrderClientList(int desktop,
QSharedPointer<TabBoxClient> add = tabBox->clientToAddToList(c.data(), desktop); QSharedPointer<TabBoxClient> add = tabBox->clientToAddToList(c.data(), desktop);
if (!add.isNull()) { if (!add.isNull()) {
if (start == add.data()) { if (start == add.data()) {
m_clientList.removeAll(add); newClientList.removeAll(add);
m_clientList.prepend(add); newClientList.prepend(add);
} else { } else {
m_clientList += add; newClientList += add;
} }
if (add.data()->isFirstInTabBox()) { if (add.data()->isFirstInTabBox()) {
stickyClients << add; stickyClients << add;
@ -206,6 +213,8 @@ void ClientModel::createStackingOrderClientList(int desktop,
break; break;
} }
} }
return newClientList;
} }
void ClientModel::createClientList(int desktop, bool partialReset) void ClientModel::createClientList(int desktop, bool partialReset)
@ -219,39 +228,46 @@ void ClientModel::createClientList(int desktop, bool partialReset)
} }
} }
beginResetModel(); TabBoxClientList newClientList;
m_clientList.clear();
TabBoxClientList stickyClients; TabBoxClientList stickyClients;
switch (tabBox->config().clientSwitchingMode()) { switch (tabBox->config().clientSwitchingMode()) {
case TabBoxConfig::FocusChainSwitching: { case TabBoxConfig::FocusChainSwitching: {
createFocusChainClientList(desktop, start, stickyClients); newClientList = createFocusChainClientList(desktop, start, stickyClients);
break; break;
} }
case TabBoxConfig::StackingOrderSwitching: { case TabBoxConfig::StackingOrderSwitching: {
createStackingOrderClientList(desktop, start, stickyClients); newClientList = createStackingOrderClientList(desktop, start, stickyClients);
break; break;
} }
} }
if (tabBox->config().orderMinimizedMode() == TabBoxConfig::GroupByMinimized) { if (tabBox->config().orderMinimizedMode() == TabBoxConfig::GroupByMinimized) {
// Put all non-minimized included clients first. // 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(); return !client.toStrongRef()->isMinimized();
}); });
} }
for (const QWeakPointer<TabBoxClient> &c : std::as_const(stickyClients)) { for (const QWeakPointer<TabBoxClient> &c : std::as_const(stickyClients)) {
m_clientList.removeAll(c); newClientList.removeAll(c);
m_clientList.prepend(c); newClientList.prepend(c);
} }
if (tabBox->config().clientApplicationsMode() != TabBoxConfig::AllWindowsCurrentApplication if (tabBox->config().clientApplicationsMode() != TabBoxConfig::AllWindowsCurrentApplication
&& (tabBox->config().showDesktopMode() == TabBoxConfig::ShowDesktopClient || m_clientList.isEmpty())) { && (tabBox->config().showDesktopMode() == TabBoxConfig::ShowDesktopClient || m_clientList.isEmpty())) {
QWeakPointer<TabBoxClient> desktopClient = tabBox->desktopClient(); QWeakPointer<TabBoxClient> desktopClient = tabBox->desktopClient();
if (!desktopClient.isNull()) { if (!desktopClient.isNull()) {
m_clientList.append(desktopClient); newClientList.append(desktopClient);
} }
} }
if (m_clientList == newClientList) {
return;
}
beginResetModel();
m_clientList = newClientList;
endResetModel(); endResetModel();
} }

View file

@ -93,10 +93,10 @@ public Q_SLOTS:
void activate(int index); void activate(int index);
private: private:
void createFocusChainClientList(int desktop, const QSharedPointer<TabBoxClient> &start, TabBoxClientList createFocusChainClientList(int desktop, const QSharedPointer<TabBoxClient> &start,
TabBoxClientList &stickyClients); TabBoxClientList &stickyClients) const;
void createStackingOrderClientList(int desktop, const QSharedPointer<TabBoxClient> &start, TabBoxClientList createStackingOrderClientList(int desktop, const QSharedPointer<TabBoxClient> &start,
TabBoxClientList &stickyClients); TabBoxClientList &stickyClients) const;
TabBoxClientList m_clientList; TabBoxClientList m_clientList;
}; };