Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'pr/105' into develop

  • Loading branch information...
commit ffb7bd8a4cf198f66eaa75453b0b2ba31eb8e838 2 parents a07a61a + 53d2c8d
@thefiddler thefiddler authored
View
2  Source/OpenTK/Platform/MacOS/Cocoa/Cocoa.cs
@@ -223,8 +223,6 @@ public static void Initialize()
AppKitLibrary = NS.LoadLibrary("/System/Library/Frameworks/AppKit.framework/AppKit");
FoundationLibrary = NS.LoadLibrary("/System/Library/Frameworks/Foundation.framework/Foundation");
-
- NSApplication.Initialize();
}
}
}
View
32 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 @@ 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);
@@ -61,8 +68,31 @@ internal static void Initialize()
Cocoa.SendIntPtr(menubar, Selector.Get("addItem:"), menuItem);
Cocoa.SendIntPtr(Handle, Selector.Get("setMainMenu:"), menubar);
+ // Add a "Quit" menu item and bind the button.
+ 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"), selQuit, Cocoa.ToNSString("q")),
+ Selector.Autorelease);
+
+ Cocoa.SendIntPtr(appMenu, Selector.Get("addItem:"), quitMenuItem);
+ Cocoa.SendIntPtr(menuItem, Selector.Get("setSubmenu:"), appMenu);
+
// 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
30 Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs
@@ -61,7 +61,6 @@ class CocoaNativeWindow : INativeWindow
static readonly IntPtr selNextEventMatchingMask = Selector.Get("nextEventMatchingMask:untilDate:inMode:dequeue:");
static readonly IntPtr selSendEvent = Selector.Get("sendEvent:");
//static readonly IntPtr selUpdateWindows = Selector.Get("updateWindows");
- static readonly IntPtr selContentView = Selector.Get("contentView");
static readonly IntPtr selConvertRectFromScreen = Selector.Get("convertRectFromScreen:");
static readonly IntPtr selConvertRectToScreen = Selector.Get("convertRectToScreen:");
static readonly IntPtr selPerformClose = Selector.Get("performClose:");
@@ -120,6 +119,7 @@ class CocoaNativeWindow : INativeWindow
static CocoaNativeWindow()
{
Cocoa.Initialize();
+ NSApplication.Initialize(); // Problem: This does not allow creating a separate app and using CocoaNativeWindow.
NSDefaultRunLoopMode = Cocoa.GetStringConstant(Cocoa.FoundationLibrary, "NSDefaultRunLoopMode");
NSCursor = Class.Get("NSCursor");
}
@@ -128,7 +128,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();
@@ -154,6 +154,7 @@ public CocoaNativeWindow(int x, int y, int width, int height, string title, Grap
// Create the window class
Interlocked.Increment(ref UniqueId);
windowClass = Class.AllocateClass("OpenTK_GameWindow" + UniqueId, "NSWindow");
+ Class.RegisterMethod(windowClass, new WindowKeyDownDelegate(WindowKeyDown), "keyDown:", "v@:@");
Class.RegisterMethod(windowClass, new WindowDidResizeDelegate(WindowDidResize), "windowDidResize:", "v@:@");
Class.RegisterMethod(windowClass, new WindowDidMoveDelegate(WindowDidMove), "windowDidMove:", "v@:@");
Class.RegisterMethod(windowClass, new WindowDidBecomeKeyDelegate(WindowDidBecomeKey), "windowDidBecomeKey:", "v@:@");
@@ -186,8 +187,12 @@ 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);
delegate void WindowDidResizeDelegate(IntPtr self, IntPtr cmd, IntPtr notification);
delegate void WindowDidMoveDelegate(IntPtr self, IntPtr cmd, IntPtr notification);
delegate void WindowDidBecomeKeyDelegate(IntPtr self, IntPtr cmd, IntPtr notification);
@@ -201,6 +206,11 @@ public CocoaNativeWindow(int x, int y, int width, int height, string title, Grap
delegate bool CanBecomeKeyWindowDelegate(IntPtr self, IntPtr cmd);
delegate bool CanBecomeMainWindowDelegate(IntPtr self, IntPtr cmd);
+ private void WindowKeyDown(IntPtr self, IntPtr cmd, IntPtr notification)
+ {
+ // Steal the event to remove the "beep" sound that is normally played for unhandled key events.
+ }
+
private void WindowDidResize(IntPtr self, IntPtr cmd, IntPtr notification)
{
OnResize(true);
@@ -218,6 +228,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,
@@ -392,10 +408,8 @@ public void ProcessEvents()
KeyPress(this, keyPressArgs);
}
}
-
- // Steal all keydown events to avoid the annoying "bleep" sound.
- return;
}
+ break;
case NSEventType.KeyUp:
{
@@ -940,6 +954,7 @@ protected virtual void Dispose(bool disposing)
return;
Debug.Print("Disposing of CocoaNativeWindow.");
+ NSApplication.Quit -= ApplicationQuit;
CursorVisible = true;
disposed = true;
@@ -965,11 +980,6 @@ protected virtual void Dispose(bool disposing)
Dispose(false);
}
- public static IntPtr GetView(IntPtr windowHandle)
- {
- return Cocoa.SendIntPtr(windowHandle, selContentView);
- }
-
private RectangleF GetContentViewFrame()
{
return Cocoa.SendRect(windowInfo.ViewHandle, selFrame);
View
29 Source/OpenTK/Platform/MacOS/CocoaWindowInfo.cs
@@ -40,7 +40,10 @@ namespace OpenTK.Platform.MacOS
/// </summary>
sealed class CocoaWindowInfo : IWindowInfo
{
+ static readonly IntPtr selContentView = Selector.Get("contentView");
+
IntPtr nsWindowRef;
+ IntPtr nsViewRef;
bool disposed = false;
@@ -49,10 +52,22 @@ sealed class CocoaWindowInfo : IWindowInfo
/// <summary>
/// Constructs a new instance with the specified parameters.
/// </summary>
- /// <param name="nsWindowRef">A valid NSView reference.</param>
- public CocoaWindowInfo(IntPtr nsWindowRef)
+ /// <remarks>This constructor assumes that the NSWindow's contentView is the NSView we want to attach to our context.</remarks>
+ /// <param name="nsWindowRef">A valid NSWindow reference.</param>
+ public CocoaWindowInfo(IntPtr nsWindowRef) : this(nsWindowRef, Cocoa.SendIntPtr(nsWindowRef, selContentView))
+ {
+
+ }
+
+ /// <summary>
+ /// Constructs a new instance with the specified parameters.
+ /// </summary>
+ /// <param name="nsWindowRef">A valid NSWindow reference.</param>
+ /// <param name="nsViewRef">A valid NSView reference.</param>
+ public CocoaWindowInfo(IntPtr nsWindowRef, IntPtr nsViewRef)
{
this.nsWindowRef = nsWindowRef;
+ this.nsViewRef = nsViewRef;
}
#endregion
@@ -67,19 +82,13 @@ public CocoaWindowInfo(IntPtr nsWindowRef)
/// <summary>
/// Gets the view reference for this instance.
/// </summary>
- public IntPtr ViewHandle
- {
- get
- {
- return CocoaNativeWindow.GetView(nsWindowRef);
- }
- }
+ public IntPtr ViewHandle { get { return nsViewRef; } }
/// <summary>Returns a System.String that represents the current window.</summary>
/// <returns>A System.String that represents the current window.</returns>
public override string ToString()
{
- return String.Format("MacOS.CocoaWindowInfo: NSWindow {0}", nsWindowRef);
+ return String.Format("MacOS.CocoaWindowInfo: NSWindow {0}, NSView {1}", nsWindowRef, nsViewRef);
}
#endregion
View
12 Source/OpenTK/Platform/Utilities.cs
@@ -309,12 +309,24 @@ public static IWindowInfo CreateMacOSCarbonWindowInfo(IntPtr windowHandle, bool
/// Creates an IWindowInfo instance for the Mac OS X platform.
/// </summary>
/// <param name="windowHandle">The handle of the NSWindow.</param>
+ /// <remarks>Assumes that the NSWindow's contentView is the NSView we want to attach to our context.</remarks>
/// <returns>A new IWindowInfo instance.</returns>
public static IWindowInfo CreateMacOSWindowInfo(IntPtr windowHandle)
{
return new OpenTK.Platform.MacOS.CocoaWindowInfo(windowHandle);
}
+ /// <summary>
+ /// Creates an IWindowInfo instance for the Mac OS X platform.
+ /// </summary>
+ /// <param name="windowHandle">The handle of the NSWindow.</param>
+ /// <param name="viewHandle">The handle of the NSView.</param>
+ /// <returns>A new IWindowInfo instance.</returns>
+ public static IWindowInfo CreateMacOSWindowInfo(IntPtr windowHandle, IntPtr viewHandle)
+ {
+ return new OpenTK.Platform.MacOS.CocoaWindowInfo(windowHandle, viewHandle);
+ }
+
#endregion
#region CreateDummyWindowInfo
Please sign in to comment.
Something went wrong with that request. Please try again.