diff options
author | iain holmes <iain@xamarin.com> | 2019-07-05 13:01:56 +0300 |
---|---|---|
committer | monojenkins <jo.shields+jenkins@xamarin.com> | 2019-07-05 19:10:04 +0300 |
commit | d32c3cfaee201f4582760361ceb0f51115fe2c05 (patch) | |
tree | f9bbd9a72f4f7f06dda50b5ec1eb57f8cf4f1095 | |
parent | 999033766ca6a399f5466f9a61b7b9c19b303f3e (diff) |
[Mac] Don't hang when terminating through the dock icon
It turns out the answer to
// FIXME: could this block in rare cases?
was "No, it blocks every time", so make the delegate async and await on the call instead.
Also remove the old Carbon handler and move the important bits into the Cocoa handler instead as it hasn't been deprecated for at least a decade
Fixes VSTS #942401
-rw-r--r-- | main/src/addins/MacPlatform/MacPlatform.cs | 30 |
1 files changed, 4 insertions, 26 deletions
diff --git a/main/src/addins/MacPlatform/MacPlatform.cs b/main/src/addins/MacPlatform/MacPlatform.cs index 569ccbe782..34a34620e9 100644 --- a/main/src/addins/MacPlatform/MacPlatform.cs +++ b/main/src/addins/MacPlatform/MacPlatform.cs @@ -58,6 +58,7 @@ using MonoDevelop.Components.Mac; using System.Reflection; using MacPlatform; using MonoDevelop.Projects; +using System.Threading.Tasks; namespace MonoDevelop.MacIntegration { @@ -301,12 +302,13 @@ namespace MonoDevelop.MacIntegration var appDelegate = NSApplication.SharedApplication.Delegate as Xwt.Mac.AppDelegate; if (appDelegate != null) { - appDelegate.Terminating += (object o, TerminationEventArgs e) => { + appDelegate.Terminating += async (object o, TerminationEventArgs e) => { if (MonoDevelop.Ide.IdeApp.IsRunning) { // If GLib the mainloop is still running that means NSApplication.Terminate() was called // before Gtk.Application.Quit(). Cancel Cocoa termination and exit the mainloop. e.Reply = NSApplicationTerminateReply.Cancel; - Gtk.Main.Quit (); + + await IdeApp.Exit(); } else { // The mainloop has already exited and we've already cleaned up our application state // so it's now safe to terminate Cocoa. @@ -681,30 +683,6 @@ namespace MonoDevelop.MacIntegration { //FIXME: should we remove these when finalizing? try { - ApplicationEvents.Quit += delegate (object sender, ApplicationQuitEventArgs e) - { - // We can only attempt to quit safely if all windows are GTK windows and not modal - if (!IsModalDialogRunning ()) { - e.UserCancelled = !IdeApp.Exit ().Result; // FIXME: could this block in rare cases? - e.Handled = true; - return; - } - - // When a modal dialog is running, things are much harder. We can't just shut down MD behind the - // dialog, and aborting the dialog may not be appropriate. - // - // There's NSTerminateLater but I'm not sure how to access it from carbon, maybe - // we need to swizzle methods into the app's NSApplicationDelegate. - // Also, it stops the main CFRunLoop and enters a special runloop mode, not sure how that would - // interact with GTK+. - - // For now, just bounce - NSApplication.SharedApplication.RequestUserAttention (NSRequestUserAttentionType.CriticalRequest); - // and abort the quit. - e.UserCancelled = true; - e.Handled = true; - }; - ApplicationEvents.Reopen += delegate (object sender, ApplicationEventArgs e) { e.Handled = true; IdeApp.BringToFront (); |