sparkle-project / Sparkle

A software update framework for macOS
https://sparkle-project.org
Other
7.44k stars 1.05k forks source link

Update error alert runs modally and blocks the app #2442

Closed axelandersson closed 1 year ago

axelandersson commented 1 year ago

Summary

The alert with title "Update Error!" runs modally and hangs the entire application until the user presses "Cancel Update". This prevents the application from running its run loop and updating other windows.

Alert is run modally here: https://github.com/sparkle-project/Sparkle/blob/f0ceaf5cc9f3f23daa0ccb6dcebd79fc96ccc7d9/Sparkle/SPUStandardUserDriver.m#L711

Called from here on updater error: https://github.com/sparkle-project/Sparkle/blob/f0ceaf5cc9f3f23daa0ccb6dcebd79fc96ccc7d9/Sparkle/SPUStandardUserDriver.m#L593

Possible Fix

There doesn't seem to be any way to run NSAlert non-modally, but some solutions to explore:

Version

2.4.2

zorgiepoo commented 1 year ago

The modal alert blocks the app, not hangs it. In all cases for an error we might be able to show a sheet to a currently showing Sparkle window (checking window or status progress window). An experiment would need to be done to make sure it doesn't look weird, but if it's only an error cases it may be okay anyway.

For the no new update not found alert, it may be feasible to use a SPUStandardUserDriverDelegate's custom window to attach to (otherwise attaching to the status window would probably look weird?). Even this might feel weird though because it transitions from Sparkle's status window back to app's own window (requires experimenting).

However, an update alert does show up in response to a user's action and SPUStandardUserDriver does notify its delegate today when a modal prompt will run and has stopped running (standardUserDriverWillShowModalAlert, standardUserDriverDidShowModalAlert) so you may be able to handle it better.

zorgiepoo commented 1 year ago

After some experimenting, I don't think the current behavior should change.

If you need to run background work while a modal alert/error is shown you can consider running that work using a NSRunLoopMode that will still execute.

Another alternative is implementing/streamlining your own user interface (SPUUserDriver) if this is a big concern. I'm not sure delegating to one of the app's window will feel "right" and then anyway that will just block that window.