From f7467eea99ee285acd31ab19692cfaf6214d2f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Thu, 20 Jun 2024 11:18:34 +0200 Subject: [PATCH] Call cancelled/dismissed callbacks when user closes window Make sure that the callback function set with win_sparkle_set_update_cancelled_callback() is called even when the user just closes the window without clicking any button. Previously, this wouldn't be done. Do the same for the similar win_sparkle_set_update_dismissed_callback(). Document the difference between the two more clearly. Fixes #127, fixes #271. --- include/winsparkle.h | 12 ++++++++---- src/ui.cpp | 24 ++++++++++++++++++------ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/include/winsparkle.h b/include/winsparkle.h index bea0b92e..0db0654b 100644 --- a/include/winsparkle.h +++ b/include/winsparkle.h @@ -447,7 +447,9 @@ WIN_SPARKLE_API void __cdecl win_sparkle_set_did_not_find_update_callback(win_sp typedef void (__cdecl *win_sparkle_update_cancelled_callback_t)(); /** - Set callback to be called when the user cancels a download. + Set callback to be called when the user cancels an update, e.g. + by closing the window, skipping an update or cancelling download. + This callback is not called when there's no update to install or an error occurs. This is useful in combination with win_sparkle_check_update_with_ui_and_install() as it allows you to perform @@ -455,7 +457,7 @@ typedef void (__cdecl *win_sparkle_update_cancelled_callback_t)(); @since 0.5 - @see win_sparkle_check_update_with_ui_and_install() + @see win_sparkle_check_update_with_ui_and_install(), win_sparkle_set_update_dismissed_callback() */ WIN_SPARKLE_API void __cdecl win_sparkle_set_update_cancelled_callback(win_sparkle_update_cancelled_callback_t callback); @@ -499,14 +501,16 @@ typedef void(__cdecl* win_sparkle_update_dismissed_callback_t)(); /** Set callback to be called when the user dismisses - (closes) update dialog. + (closes) update dialog, including when there were no updates or an error occured. + See win_sparkle_set_update_cancelled_callback() for a subtly different callback + that may be more appropriate. This is useful in combination with win_sparkle_check_update_with_ui() or similar as it allows you to perform some action when the update dialog is closed. - @see win_sparkle_check_update_with_ui() + @see win_sparkle_check_update_with_ui(), win_sparkle_set_update_cancelled_callback() @since 0.8 */ diff --git a/src/ui.cpp b/src/ui.cpp index e94ef96d..546ff5b1 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -480,6 +480,8 @@ class UpdateDialog : public WinSparkleDialog bool m_installAutomatically; // whether an error occurred (used to properly call NotifyUpdateCancelled) bool m_errorOccurred; + // whether window closure was updater-initiated (i.e. not caused by user) + bool m_closeInitiatedByUpdater; static const int RELNOTES_WIDTH = 460; static const int RELNOTES_HEIGHT = 200; @@ -492,6 +494,7 @@ UpdateDialog::UpdateDialog() { m_installAutomatically = false; m_errorOccurred = false; + m_closeInitiatedByUpdater = false; m_heading = new wxStaticText(this, wxID_ANY, ""); SetHeadingFont(m_heading); @@ -594,7 +597,7 @@ void UpdateDialog::OnTimer(wxTimerEvent&) void UpdateDialog::OnCloseButton(wxCommandEvent&) { - ApplicationController::NotifyUpdateDismissed(); + m_closeInitiatedByUpdater = false; Close(); } @@ -615,11 +618,15 @@ void UpdateDialog::OnClose(wxCloseEvent&) // destroy itself in Close(). Destroy(); - // If the update was not downloaded and the appcast is empty and we're closing, - // it means that we're about to restart or there was an error, and that the - // window-close event wasn't initiated by the user. - if ( m_appcast.IsValid() && m_updateFile.IsEmpty() && !m_errorOccurred ) - ApplicationController::NotifyUpdateCancelled(); + // Notify about window being dismissed or update cancelled. We must not notify + // if window closure was initiated by WinSparkle itself e.g. to run the installer. + if (!m_closeInitiatedByUpdater) + { + if (!m_errorOccurred && m_appcast.IsValid()) + ApplicationController::NotifyUpdateCancelled(); + + ApplicationController::NotifyUpdateDismissed(); + } } @@ -627,6 +634,7 @@ void UpdateDialog::OnSkipVersion(wxCommandEvent&) { Settings::WriteConfigValue("SkipThisVersion", m_appcast.Version); ApplicationController::NotifyUpdateSkipped(); + m_closeInitiatedByUpdater = false; // skipping is cancellation Close(); } @@ -636,6 +644,7 @@ void UpdateDialog::OnRemindLater(wxCommandEvent&) // Just abort the update. Next time it's scheduled to run, // the user will be prompted. ApplicationController::NotifyUpdatePostponed(); + m_closeInitiatedByUpdater = false; // skipping is cancellation Close(); } @@ -645,6 +654,7 @@ void UpdateDialog::OnInstall(wxCommandEvent&) if ( !m_appcast.HasDownload() ) { wxLaunchDefaultBrowser(m_appcast.WebBrowserURL, wxBROWSER_NEW_WINDOW); + m_closeInitiatedByUpdater = true; Close(); } else if ( m_downloader == NULL ) @@ -685,6 +695,7 @@ void UpdateDialog::OnRunInstaller(wxCommandEvent&) } else { + m_closeInitiatedByUpdater = true; Close(); ApplicationController::RequestShutdown(); } @@ -757,6 +768,7 @@ void UpdateDialog::StateNoUpdateFound(bool installAutomatically) if ( m_installAutomatically ) { + m_closeInitiatedByUpdater = true; Close(); return; }