…sing the "Install on Quit" functionality.
Bug #389869: "Sparkle runs thread-unsafe code on secondary threads" Bug #312995: "Canceling authentication request causes crash on next update" Bug #388793: "Need to notify SUUpdateDriverFinishedNotification on main thread" The unfortunate side-effect of this fix is that all the file-handling code is now CoreServices-based, since NSFileManager is not thread-safe. This is disgusting and will be stricken from all records when installation is performed by relaunch in Next Major, as it should have been in the first place.
… #if'd for 10.4 support; I look forward to removing them. :) Thanks for the patch, August.
…ter's delegate from within the update driver. Update drivers now have an initWithUpdater: method which I use instead.
… case of an LSUIElement. In that case, I think it's best for Sparkle to use NSFloatingWindowLevel, so that it's clear why the menu items are disabled (due to modality) when they click the menu icon again, thus focusing the update alert. We'll see how well this works.
Made Sparkle.h no longer a massive multi-headed abomination: now only SUAppcastItem, SUAppcast and SUUpdater (and SUVersionComparisonProtocol because it's part of the delegate protocol) are public. COMPATIBILITY ISSUE: This means there's no longer a public SUProbingUpdateDriver or a checkForUpdatesWithDriver: method. Now use checkForUpdateInformation. I may change that API before release, though. I'm thinking it might be better to give the delegate the opportunity to reject a potential update instead: then you'd just call checkForUpdatesInBackground and override that delegate method to always return NO. We'll see.
Fixes from Matt Stevens: "For background applications (menu bar, completely UI-less, etc) there are a couple of issues with Sparkle notifications: - When prompts such as the initial prompt to enable update checking are displayed they can be hidden behind other windows since the background app is not in focus. This can cause problems, as these prompts run modally and can stop the application from functioning without the user knowing why. - If the update notification window is displayed and the user clicks away to another application, the window disappears and there is no way to get it back since there is no other UI to cause the app to activate. In this case the update should probably operate as a standard window since it is effectively operating as the application's UI."
Made a first crack at redifining the SUUpdater delegate protocol. Still not sure about a couple things, so please don't change your delegate methods to conform until this gets merged into trunk. Also made the SUUpdateDrivers not have the updater's delegate as their delegate (that was really icky). Now they're just coupled with the SUUpdater, which is icky as well, but less icky, at least.
…Sparkle. More super-unstable refactorings to come...
… since the status window nib is unlocalized, localizers should be careful not to make their strings too long. Changed a French status string to fit in the status window.
…ation handling for B/KB/MB/GB by moving the code in the NSNumber category (which wouldn't work because it couldn't find the Sparkle localization table) to SUUIBasedUpdateDriver.
…s delegate methods instead of dumbly having its own. IF YOU ARE IMPLEMENTING ANY DELEGATE METHODS TO A SPARKLE CLASS, CHECK THESE DIFFS AND ENSURE THAT THE SELECTORS YOU'RE IMPLEMENTING HAVEN'T CHANGED. There's a pretty good chance they have. But for good reason, I promise!
…ge the strings file.
Basically, because I foolishly don't "[self abortUpdate]" on failure in the UI-based update driver, the SUUpdater instance thought an update was still in progress when it wasn't. This only affected user-initiated updates (SUScheduledUpdateDriver overrides that method), but it still was a serious issue.
…pps when the user cancels an update's download. That's kind of a big mistake. Sorry about that guys.
Finally adding real delegate support. The following methods are implemented; the comments document them. If you have suggestions for other methods that would be useful, feel free to suggest them. // Use this to override the default behavior for Sparkle prompting the user about automatic update checks. - (BOOL)shouldPromptForPermissionToCheckForUpdates; // Implement this if you want to do some special handling with the appcast once it finishes loading. - (void)appcastDidFinishLoading:(SUAppcast *)appcast; // If you're using special logic or extensions in your appcast, implement this to use your own logic for finding // a valid update, if any, in the given appcast. - (SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast; // Sent when a valid update is found by the update driver. - (void)didFindValidUpdate:(SUAppcastItem *)update; // Sent when the user makes a choice in the update alert dialog (install now / remind me later / skip this version). - (void)userChoseAction:(SUUpdateAlertChoice)action forUpdate:(SUAppcastItem *)update; // Sent immediately before installing the specified update. - (void)updateWillInstall:(SUAppcastItem *)update; // Return YES to delay the relaunch until you do some processing; invoke the given NSInvocation to continue. - (BOOL)shouldPostponeRelaunchForUpdate:(SUAppcastItem *)update untilInvoking:(NSInvocation *)invocation; // Called immediately before relaunching. - (void)updaterWillRelaunchApplication;
Sparkle now gies visual indication that it's checking for updates when hte update's user initiated. ie: it pops up a status controller saying "checking for updates..." What was SUUserInitiatedUpdateDriver is now SUUIBasedUpdateDriver; SUUserInitiatedUpdateDriver now is a subclass of that, along with SUScheduledUpdateDriver. This is a happy little refactoring that let me remove some redundant code.