diff --git a/ChangeLog b/ChangeLog index 84abd9be19..e39b30546c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,10 +7,11 @@ Unreleased Version 2.2.0-pre * Server Feature: Allow setting web admin auth through DRAWPILESRV_WEB_ADMIN_AUTH environment variable. The --web-admin-auth parameter takes precedence. * Fix: Show the fill tool size limit rectangle even when the outline width is set to zero pixels. Thanks Blozzom for reporting. * Server Fix: Show an error message if listing on a certain server is not allowed. - * Fix: Unlist sessions more reliably when terminating sessions hosted "on this computer". + * Fix: Unlist sessions more reliably when terminating sessions hosted "on this computer". Thanks to Buch for helping figure this out. * Fix: Don't select a newly created layer when there's a default layer. * Fix: Give the timeline dock a sensible minimum height. Thanks Kink for reporting. * Fix: Make notification sounds work in the AppImage release. Thanks anonymous for reporting. + * Fix: Don't exit the program in the pathological case of initiating a quit, being prompted to save, cancelling the save dialog and then saving again. 2023-12-08 Version 2.2.0-beta.11 * Server Fix: No longer show "cannot look up one session and then join another" when joining a session with an ID alias. Thanks Kink and Fabian for finding this. diff --git a/src/desktop/mainwindow.cpp b/src/desktop/mainwindow.cpp index 1a2fee6c62..4a3f3241e3 100644 --- a/src/desktop/mainwindow.cpp +++ b/src/desktop/mainwindow.cpp @@ -179,7 +179,7 @@ MainWindow::MainWindow(bool restoreWindowPosition) m_notificationsMuted(false), m_initialCatchup(false), m_doc(nullptr), - m_exitAfterSave(false) + m_exitAction(RUNNING) { // Avoid flickering of intermediate states. setUpdatesEnabled(false); @@ -1158,12 +1158,11 @@ void MainWindow::closeEvent(QCloseEvent *event) if(m_doc->isSaveInProgress()) { // Don't quit while save is in progress - m_exitAfterSave = true; + m_exitAction = SAVING; event->ignore(); return; } - QElapsedTimer disconnectTimer; if(canReplace() == false) { // First confirm disconnection @@ -1182,12 +1181,16 @@ void MainWindow::closeEvent(QCloseEvent *event) box.exec(); if(box.clickedButton() == exitbtn) { - disconnectTimer.start(); + // Disconnect and wait a moment for things to settle so that + // e.g. the builtin server gets a chance to shut down properly + // and any pending drawing commands get executed. + m_exitAction = DISCONNECTING; m_doc->client()->disconnectFromServer(); - } else { - event->ignore(); - return; + setEnabled(false); + QApplication::setOverrideCursor(Qt::WaitCursor); } + event->ignore(); + return; } // Then confirm unsaved changes @@ -1208,8 +1211,9 @@ void MainWindow::closeEvent(QCloseEvent *event) // Save and exit, or cancel exit if couldn't save. if(box.clickedButton() == savebtn) { cancel = true; - m_exitAfterSave = true; - save(); + if(save()) { + m_exitAction = SAVING; + } } // Cancel exit @@ -1219,19 +1223,8 @@ void MainWindow::closeEvent(QCloseEvent *event) } } } - // If we just disconnected, give things another moment to settle so that - // e.g. the builtin server gets a chance to shut down gracefully and delete - // any session announcements that may have been made. - qint64 delay = disconnectTimer.isValid() && !m_exitAfterSave - ? 1000 - disconnectTimer.elapsed() : 0; - if(delay > 0) { - event->ignore(); - setEnabled(false); - QApplication::setOverrideCursor(Qt::WaitCursor); - QTimer::singleShot(delay, this, &QMainWindow::close); - } else { - exit(); - } + + exit(); } bool MainWindow::event(QEvent *event) @@ -1532,11 +1525,14 @@ void MainWindow::open() /** * If no file name has been selected, \a saveas is called. */ -void MainWindow::save() +bool MainWindow::save() { QString result = FileWrangler{this}.saveImage(m_doc); - if(!result.isEmpty()) { + if(result.isEmpty()) { + return false; + } else { addRecentFile(result); + return true; } } @@ -1613,9 +1609,9 @@ void MainWindow::onCanvasSaved(const QString &errorMessage) // Cancel exit if canvas is modified while it was being saved if(m_doc->isDirty()) - m_exitAfterSave = false; + m_exitAction = RUNNING; - if(m_exitAfterSave) + if(m_exitAction == SAVING) close(); } @@ -2304,6 +2300,11 @@ void MainWindow::onServerDisconnected(const QString &message, const QString &err dpApp().notifications()->trigger( this, notification::Event::Disconnect, notif); } + + if(m_exitAction != RUNNING) { + m_exitAction = RUNNING; + QTimer::singleShot(100, this, &QMainWindow::close); + } } /** diff --git a/src/desktop/mainwindow.h b/src/desktop/mainwindow.h index b502e76644..d55331f45f 100644 --- a/src/desktop/mainwindow.h +++ b/src/desktop/mainwindow.h @@ -119,7 +119,7 @@ public slots: void showNew(); void open(); void open(const QUrl &url); - void save(); + bool save(); void saveas(); void saveSelection(); void exportImage(); @@ -361,7 +361,7 @@ private slots: Document *m_doc; MainActions *m_ma; - bool m_exitAfterSave; + enum { RUNNING, DISCONNECTING, SAVING } m_exitAction; drawdance::CanvasState m_preResetCanvasState;