From e3a3ce0521578f24d764e7c06c6bc469269d026d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Sat, 19 Sep 2026 07:46:51 +0200 Subject: [PATCH] [DeckStorage] Refresh the visibility column with a guarded timer instead of a latch counter A dropped visibility reply used to leave the pendingVisibilityChanges counter permanently positive, so the Public/Private column never refreshed again and nothing reset it on disconnect. A restartable single-shot timer with a boolean guard re-reads the tree whenever publishes quiet down and is stopped on disconnect, so a lost reply costs one stale refresh instead of killing the column for the session. --- .../widgets/tabs/tab_deck_storage.cpp | 31 +++++++++++++++---- .../interface/widgets/tabs/tab_deck_storage.h | 4 ++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/cockatrice/src/interface/widgets/tabs/tab_deck_storage.cpp b/cockatrice/src/interface/widgets/tabs/tab_deck_storage.cpp index 93bac0ea3..886693a5b 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_deck_storage.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_deck_storage.cpp @@ -44,6 +44,12 @@ #include #include +namespace { +// How long to wait after the last visibility change before reading back the +// Public/Private column, in milliseconds. +constexpr int VISIBILITY_REFRESH_DELAY = 500; +} // namespace + TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor, AbstractClient *_client, const ServerInfo_User *currentUserInfo) @@ -120,6 +126,15 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor, SettingsCache::instance().network().getKeepAlive() * 1000)); connect(shareTimeoutTimer, &QTimer::timeout, this, &TabDeckStorage::onShareFromTreeTimeout); + // Restartable single-shot refresh for the Public/Private column. A dropped + // visibility reply must not leave the widget permanently stale, so the tree + // is re-read whenever publishes quiet down instead of waiting on a count + // that can get stuck above zero. + visibilityRefreshTimer = new QTimer(this); + visibilityRefreshTimer->setSingleShot(true); + visibilityRefreshTimer->setInterval(VISIBILITY_REFRESH_DELAY); + connect(visibilityRefreshTimer, &QTimer::timeout, this, &TabDeckStorage::onVisibilityRefreshTimeout); + QVBoxLayout *rightVbox = new QVBoxLayout; rightVbox->addWidget(shareBar); rightVbox->addWidget(serverDirView); @@ -255,6 +270,8 @@ void TabDeckStorage::handleConnected(const ServerInfo_User &userInfo) void TabDeckStorage::handleConnectionChanged(ClientStatus status) { if (status == StatusDisconnected) { + visibilityRefreshTimer->stop(); + visibilityRefreshStarted = false; setRemoteEnabled(false); } } @@ -864,7 +881,8 @@ void TabDeckStorage::actPublishDeck() PendingCommand *pend = client->prepareSessionCommand(cmd); connect(pend, &PendingCommand::finished, this, &TabDeckStorage::setVisibilityFinished); - ++pendingVisibilityChanges; + visibilityRefreshStarted = true; + visibilityRefreshTimer->start(); client->sendCommand(pend); } } @@ -876,9 +894,10 @@ void TabDeckStorage::setVisibilityFinished(const Response &r, const CommandConta tr("Failed to change deck visibility on server (response code %1).") .arg(QString::number(static_cast(r.response_code())))); } - // Refresh once the last in-flight change has been acknowledged so the - // Public/Private column reflects every selected node. - if (--pendingVisibilityChanges == 0) { - serverDirView->refreshTree(); - } +} + +void TabDeckStorage::onVisibilityRefreshTimeout() +{ + visibilityRefreshStarted = false; + serverDirView->refreshTree(); } diff --git a/cockatrice/src/interface/widgets/tabs/tab_deck_storage.h b/cockatrice/src/interface/widgets/tabs/tab_deck_storage.h index 67954eed7..af59c46b9 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_deck_storage.h +++ b/cockatrice/src/interface/widgets/tabs/tab_deck_storage.h @@ -45,7 +45,8 @@ private: QAction *aOpenLocalDeck, *aRenameLocal, *aUpload, *aNewLocalFolder, *aDeleteLocalDeck; QAction *aOpenDecksFolder; QAction *aOpenRemoteDeck, *aDownload, *aShareDecks, *aPublishDeck, *aNewFolder, *aDeleteRemoteDeck; - int pendingVisibilityChanges = 0; + bool visibilityRefreshStarted = false; + QTimer *visibilityRefreshTimer; QString getTargetPath() const; void setRemoteEnabled(bool enabled); @@ -95,6 +96,7 @@ private slots: void actPublishDeck(); void setVisibilityFinished(const Response &r, const CommandContainer &commandContainer); + void onVisibilityRefreshTimeout(); void actDeleteRemoteDeck(); void deleteFolderFinished(const Response &response, const CommandContainer &commandContainer);