[Mac] Cmd-Q should raise Closing events

It should also be cancelable.
This commit is contained in:
thefiddler 2014-04-28 16:19:04 +02:00
parent 160e6ecb31
commit 53d2c8d1e8
2 changed files with 33 additions and 3 deletions

View file

@ -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<CancelEventArgs> 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);
}
}
}
}

View file

@ -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;