Close the TabGames when closing the TabSupervisor (#5735)

* Close the `TabGame`s when closing the `TabSupervisor`

This ensures that we go through the same code path (in terms of Qt
events) when closing the whole supervisor as when closing a single tab.
Also, use the `close` event instead of the `hide` event to detect when
we are closing a game.

Fixes #5697

* Compat with old Qt versions

* Old Qt, reloaded

* Review: use hideEvent and call super
This commit is contained in:
Basile Clement 2025-03-17 00:05:04 +01:00 committed by GitHub
parent 57a8960841
commit 37382dea44
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 47 additions and 27 deletions

View file

@ -119,7 +119,6 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay)
refreshShortcuts();
messageLog->logReplayStarted(gameInfo.game_id());
this->installEventFilter(this);
QTimer::singleShot(0, this, SLOT(loadLayout()));
}
@ -164,7 +163,6 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor,
for (int i = gameInfo.game_types_size() - 1; i >= 0; i--)
gameTypes.append(roomGameTypes.find(gameInfo.game_types(i)).value());
this->installEventFilter(this);
QTimer::singleShot(0, this, SLOT(loadLayout()));
}
@ -1753,6 +1751,27 @@ void TabGame::createMessageDock(bool bReplay)
connect(messageLayoutDock, SIGNAL(topLevelChanged(bool)), this, SLOT(dockTopLevelChanged(bool)));
}
void TabGame::hideEvent(QHideEvent *event)
{
LayoutsSettings &layouts = SettingsCache::instance().layouts();
if (replay) {
layouts.setReplayPlayAreaState(saveState());
layouts.setReplayPlayAreaGeometry(saveGeometry());
layouts.setReplayCardInfoSize(cardInfoDock->size());
layouts.setReplayMessageLayoutSize(messageLayoutDock->size());
layouts.setReplayPlayerListSize(playerListDock->size());
layouts.setReplayReplaySize(replayDock->size());
} else {
layouts.setGamePlayAreaState(saveState());
layouts.setGamePlayAreaGeometry(saveGeometry());
layouts.setGameCardInfoSize(cardInfoDock->size());
layouts.setGameMessageLayoutSize(messageLayoutDock->size());
layouts.setGamePlayerListSize(playerListDock->size());
}
Tab::hideEvent(event);
}
// Method uses to sync docks state with menu items state
bool TabGame::eventFilter(QObject *o, QEvent *e)
{
@ -1772,23 +1791,6 @@ bool TabGame::eventFilter(QObject *o, QEvent *e)
}
}
if (o == this && e->type() == QEvent::Hide) {
LayoutsSettings &layouts = SettingsCache::instance().layouts();
if (replay) {
layouts.setReplayPlayAreaState(saveState());
layouts.setReplayPlayAreaGeometry(saveGeometry());
layouts.setReplayCardInfoSize(cardInfoDock->size());
layouts.setReplayMessageLayoutSize(messageLayoutDock->size());
layouts.setReplayPlayerListSize(playerListDock->size());
layouts.setReplayReplaySize(replayDock->size());
} else {
layouts.setGamePlayAreaState(saveState());
layouts.setGamePlayAreaGeometry(saveGeometry());
layouts.setGameCardInfoSize(cardInfoDock->size());
layouts.setGameMessageLayoutSize(messageLayoutDock->size());
layouts.setGamePlayerListSize(playerListDock->size());
}
}
return false;
}

View file

@ -208,6 +208,7 @@ private slots:
void actResetLayout();
void freeDocksSize();
void hideEvent(QHideEvent *event) override;
bool eventFilter(QObject *o, QEvent *e) override;
void dockVisibleTriggered();
void dockFloatingTriggered();

View file

@ -232,22 +232,39 @@ void TabSupervisor::refreshShortcuts()
aTabLog->setShortcuts(shortcuts.getShortcut("Tabs/aTabLog"));
}
bool TabSupervisor::closeRequest()
void TabSupervisor::closeEvent(QCloseEvent *event)
{
// This will accept the event, which we may then override.
QTabWidget::closeEvent(event);
if (getGameCount()) {
if (QMessageBox::question(this, tr("Are you sure?"),
tr("There are still open games. Are you sure you want to quit?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) {
return false;
event->ignore();
return;
}
}
for (AbstractTabDeckEditor *tab : deckEditorTabs) {
if (!tab->confirmClose())
return false;
if (!tab->confirmClose()) {
event->ignore();
}
}
return true;
// Close the game tabs in order to make sure they store their layout.
QSet<int> gameTabsToRemove;
for (auto it = gameTabs.begin(), end = gameTabs.end(); it != end; ++it) {
if (it.value()->close()) {
gameTabsToRemove.insert(it.key());
} else {
event->ignore();
}
}
for (auto tabId : gameTabsToRemove) {
gameTabs.remove(tabId);
}
}
AbstractClient *TabSupervisor::getClient() const

View file

@ -138,7 +138,7 @@ public:
return deckEditorTabs;
}
bool getAdminLocked() const;
bool closeRequest();
void closeEvent(QCloseEvent *event) override;
bool switchToGameTabIfAlreadyExists(const int gameId);
static void actShowPopup(const QString &message);
signals:
@ -192,4 +192,4 @@ private slots:
void processNotifyUserEvent(const Event_NotifyUser &event);
};
#endif
#endif

View file

@ -1018,7 +1018,7 @@ void MainWindow::closeEvent(QCloseEvent *event)
return;
bClosingDown = true;
if (!tabSupervisor->closeRequest()) {
if (!tabSupervisor->close()) {
event->ignore();
bClosingDown = false;
return;