From 53d2c8d1e84abd73fc5de5f6dbcdaf7e183ae504 Mon Sep 17 00:00:00 2001 From: thefiddler Date: Mon, 28 Apr 2014 16:19:04 +0200 Subject: [PATCH] [Mac] Cmd-Q should raise Closing events It should also be cancelable. --- .../Platform/MacOS/Cocoa/NSApplication.cs | 24 +++++++++++++++++-- .../Platform/MacOS/CocoaNativeWindow.cs | 12 +++++++++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Source/OpenTK/Platform/MacOS/Cocoa/NSApplication.cs b/Source/OpenTK/Platform/MacOS/Cocoa/NSApplication.cs index 8511a13f..cc0a34f9 100644 --- a/Source/OpenTK/Platform/MacOS/Cocoa/NSApplication.cs +++ b/Source/OpenTK/Platform/MacOS/Cocoa/NSApplication.cs @@ -28,6 +28,7 @@ #endregion using System; +using System.ComponentModel; using System.Runtime.InteropServices; using OpenTK.Platform.MacOS; @@ -38,13 +39,19 @@ namespace OpenTK.Platform.MacOS internal static IntPtr Handle; internal static IntPtr AutoreleasePool; + static readonly IntPtr selQuit = Selector.Get("quit"); + internal static void Initialize() { // Create the NSAutoreleasePool AutoreleasePool = Cocoa.SendIntPtr(Cocoa.SendIntPtr(Class.Get("NSAutoreleasePool"), Selector.Alloc), Selector.Init); + // Register a Quit method to be called on cmd-q + IntPtr nsapp = Class.Get("NSApplication"); + Class.RegisterMethod(nsapp, new OnQuitDelegate(OnQuit), "quit", "v@:"); + // Fetch the application handle - Handle = Cocoa.SendIntPtr(Class.Get("NSApplication"), Selector.Get("sharedApplication")); + Handle = Cocoa.SendIntPtr(nsapp, Selector.Get("sharedApplication")); // Setup the application Cocoa.SendBool(Handle, Selector.Get("setActivationPolicy:"), (int)NSApplicationActivationPolicy.Regular); @@ -65,7 +72,7 @@ namespace OpenTK.Platform.MacOS var appMenu = Cocoa.SendIntPtr(Cocoa.SendIntPtr(Class.Get("NSMenu"), Selector.Alloc), Selector.Autorelease); var quitMenuItem = Cocoa.SendIntPtr(Cocoa.SendIntPtr(Cocoa.SendIntPtr(Class.Get("NSMenuItem"), Selector.Alloc), - Selector.Get("initWithTitle:action:keyEquivalent:"), Cocoa.ToNSString("Quit"), Selector.Get("terminate:"), Cocoa.ToNSString("q")), + Selector.Get("initWithTitle:action:keyEquivalent:"), Cocoa.ToNSString("Quit"), selQuit, Cocoa.ToNSString("q")), Selector.Autorelease); Cocoa.SendIntPtr(appMenu, Selector.Get("addItem:"), quitMenuItem); @@ -74,5 +81,18 @@ namespace OpenTK.Platform.MacOS // Tell cocoa we're ready to run the application (usually called by [NSApp run]). Cocoa.SendVoid(Handle, Selector.Get("finishLaunching")); } + + internal static event EventHandler Quit = delegate { }; + + delegate void OnQuitDelegate(IntPtr self, IntPtr cmd); + static void OnQuit(IntPtr self, IntPtr cmd) + { + var e = new CancelEventArgs(); + Quit(null, e); + if (!e.Cancel) + { + Cocoa.SendVoid(Handle, Selector.Get("terminate:"), Handle); + } + } } } diff --git a/Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs b/Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs index 9afa9306..40d20e7b 100644 --- a/Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs +++ b/Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs @@ -127,7 +127,7 @@ namespace OpenTK.Platform.MacOS private IntPtr windowClass; private IntPtr trackingArea; private bool disposed = false; - private bool exists = true; + private bool exists; private bool cursorVisible = true; private System.Drawing.Icon icon; private LegacyInputDriver inputDriver = new LegacyInputDriver(); @@ -184,6 +184,9 @@ namespace OpenTK.Platform.MacOS SetTitle(title, false); ResetTrackingArea(); + + exists = true; + NSApplication.Quit += ApplicationQuit; } delegate void WindowKeyDownDelegate(IntPtr self, IntPtr cmd, IntPtr notification); @@ -222,6 +225,12 @@ namespace OpenTK.Platform.MacOS Resize(this, EventArgs.Empty); } + private void ApplicationQuit(object sender, CancelEventArgs e) + { + bool close = WindowShouldClose(windowInfo.Handle, IntPtr.Zero, IntPtr.Zero); + e.Cancel |= !close; + } + private void WindowDidMove(IntPtr self, IntPtr cmd, IntPtr notification) { // Problem: Called only when you stop moving for a brief moment, @@ -919,6 +928,7 @@ namespace OpenTK.Platform.MacOS return; Debug.Print("Disposing of CocoaNativeWindow."); + NSApplication.Quit -= ApplicationQuit; CursorVisible = true; disposed = true;