Skip to content

Commit

Permalink
[Mac] Cmd-Q should raise Closing events
Browse files Browse the repository at this point in the history
It should also be cancelable.
  • Loading branch information
thefiddler committed Apr 28, 2014
1 parent 160e6ec commit 53d2c8d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
24 changes: 22 additions & 2 deletions Source/OpenTK/Platform/MacOS/Cocoa/NSApplication.cs
Expand Up @@ -28,6 +28,7 @@
#endregion

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using OpenTK.Platform.MacOS;

Expand All @@ -38,13 +39,19 @@ static class NSApplication
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);
Expand All @@ -65,7 +72,7 @@ internal static void Initialize()
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);
Expand All @@ -74,5 +81,18 @@ internal static void Initialize()
// 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);
}
}
}
}
12 changes: 11 additions & 1 deletion Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs
Expand Up @@ -127,7 +127,7 @@ static CocoaNativeWindow()
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();
Expand Down Expand Up @@ -184,6 +184,9 @@ public CocoaNativeWindow(int x, int y, int width, int height, string title, Grap
SetTitle(title, false);

ResetTrackingArea();

exists = true;
NSApplication.Quit += ApplicationQuit;
}

delegate void WindowKeyDownDelegate(IntPtr self, IntPtr cmd, IntPtr notification);
Expand Down Expand Up @@ -222,6 +225,12 @@ private void OnResize(bool resetTracking)
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,
Expand Down Expand Up @@ -919,6 +928,7 @@ protected virtual void Dispose(bool disposing)
return;

Debug.Print("Disposing of CocoaNativeWindow.");
NSApplication.Quit -= ApplicationQuit;

CursorVisible = true;
disposed = true;
Expand Down

0 comments on commit 53d2c8d

Please sign in to comment.