Fix that Restart Now might not close Qt Creator

The call of QWidget::close() on the main window is blocked by Qt if
there are modal windows open. First close/accept all currently open
modal dialogs, then close the main window.

Reverts a8bc9774f9 which was specific to
the Link with Qt functionality, and generalizes the code in
MainWindow::exit().

Fixes: QTCREATORBUG-26525
Task-number: QTCREATORBUG-24098
Change-Id: I4c62f684cdfd749dfb3d3c18bd513b9fee10ddda
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
Eike Ziller
2021-11-05 12:27:45 +01:00
parent af8937f10f
commit f16589f969
2 changed files with 28 additions and 15 deletions

View File

@@ -92,6 +92,7 @@
#include <QStyleFactory> #include <QStyleFactory>
#include <QToolButton> #include <QToolButton>
#include <QUrl> #include <QUrl>
#include <QWindow>
using namespace ExtensionSystem; using namespace ExtensionSystem;
using namespace Utils; using namespace Utils;
@@ -939,6 +940,20 @@ void MainWindow::setFocusToEditor()
EditorManagerPrivate::doEscapeKeyFocusMoveMagic(); EditorManagerPrivate::doEscapeKeyFocusMoveMagic();
} }
static void acceptModalDialogs()
{
const QWidgetList topLevels = QApplication::topLevelWidgets();
QList<QDialog *> dialogsToClose;
for (QWidget *topLevel : topLevels) {
if (auto dialog = qobject_cast<QDialog *>(topLevel)) {
if (dialog->isModal())
dialogsToClose.append(dialog);
}
}
for (QDialog *dialog : dialogsToClose)
dialog->accept();
}
void MainWindow::exit() void MainWindow::exit()
{ {
// this function is most likely called from a user action // this function is most likely called from a user action
@@ -946,7 +961,15 @@ void MainWindow::exit()
// since on close we are going to delete everything // since on close we are going to delete everything
// so to prevent the deleting of that object we // so to prevent the deleting of that object we
// just append it // just append it
QMetaObject::invokeMethod(this, &QWidget::close, Qt::QueuedConnection); QMetaObject::invokeMethod(
this,
[this] {
// Modal dialogs block the close event. So close them, in case this was triggered from
// a RestartDialog in the settings dialog.
acceptModalDialogs();
close();
},
Qt::QueuedConnection);
} }
void MainWindow::openFileWith() void MainWindow::openFileWith()

View File

@@ -177,7 +177,7 @@ public:
QtOptionsPageWidget(); QtOptionsPageWidget();
~QtOptionsPageWidget(); ~QtOptionsPageWidget();
static bool linkWithQt(); static void linkWithQt();
private: private:
void apply() final; void apply() final;
@@ -857,16 +857,7 @@ void QtOptionsPageWidget::setupLinkWithQtButton()
QString tip; QString tip;
canLinkWithQt(&tip); canLinkWithQt(&tip);
m_ui.linkWithQtButton->setToolTip(tip); m_ui.linkWithQtButton->setToolTip(tip);
connect(m_ui.linkWithQtButton, &QPushButton::clicked, this, [this] { connect(m_ui.linkWithQtButton, &QPushButton::clicked, this, &QtOptionsPage::linkWithQt);
if (linkWithQt()) {
QWidget *w = window();
// close options dialog
if (QDialog *dialog = qobject_cast<QDialog *>(w))
dialog->accept();
else
window()->close();
}
});
} }
void QtOptionsPageWidget::updateCurrentQtName() void QtOptionsPageWidget::updateCurrentQtName()
@@ -959,7 +950,7 @@ static FilePath defaultQtInstallationPath()
return FileUtils::homePath() / "Qt"; return FileUtils::homePath() / "Qt";
} }
bool QtOptionsPageWidget::linkWithQt() void QtOptionsPageWidget::linkWithQt()
{ {
const QString title = tr("Choose Qt Installation"); const QString title = tr("Choose Qt Installation");
const QString restartText = tr("The change will take effect after restart."); const QString restartText = tr("The change will take effect after restart.");
@@ -1028,9 +1019,8 @@ bool QtOptionsPageWidget::linkWithQt()
} }
if (askForRestart) { if (askForRestart) {
Core::RestartDialog restartDialog(Core::ICore::dialogParent(), restartText); Core::RestartDialog restartDialog(Core::ICore::dialogParent(), restartText);
return restartDialog.exec() == QDialog::Accepted; restartDialog.exec();
} }
return false;
} }
// QtOptionsPage // QtOptionsPage