static NSApplication() { Cocoa.Initialize(); // Register a Quit method to be called on cmd-q IntPtr nsapp = Class.Get("NSApplication"); Class.RegisterMethod(nsapp, OnQuitHandler, "quit", "v@:"); // Fetch the application handle Handle = Cocoa.SendIntPtr(nsapp, Selector.Get("sharedApplication")); // Setup the application Cocoa.SendBool(Handle, Selector.Get("setActivationPolicy:"), (int)NSApplicationActivationPolicy.Regular); Cocoa.SendVoid(Handle, Selector.Get("discardEventsMatchingMask:beforeEvent:"), uint.MaxValue, IntPtr.Zero); Cocoa.SendVoid(Handle, Selector.Get("activateIgnoringOtherApps:"), true); if (Cocoa.SendIntPtr(Handle, Selector.Get("mainMenu")) == IntPtr.Zero) { // Create the menu bar var menubar = Cocoa.SendIntPtr(Class.Get("NSMenu"), Selector.Alloc); var menuItem = Cocoa.SendIntPtr(Class.Get("NSMenuItem"), Selector.Alloc); // Add menu item to bar, and bar to application 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(Class.Get("NSMenu"), Selector.Alloc); var quitMenuItem = Cocoa.SendIntPtr(Cocoa.SendIntPtr(Class.Get("NSMenuItem"), Selector.Alloc), Selector.Get("initWithTitle:action:keyEquivalent:"), Cocoa.ToNSString("Quit"), selQuit, Cocoa.ToNSString("q")); 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]). // Note: if a main menu exists, then this method has already been called and // calling it again will result in a crash. For this reason, we only call it // when we create our own main menu. Cocoa.SendVoid(Handle, Selector.Get("finishLaunching")); } // Disable momentum scrolling and long-press key pop-ups IntPtr settings = Cocoa.SendIntPtr(Class.NSDictionary, Selector.Alloc); //IntPtr momentum_scrolling = Cocoa.SendIntPtr(Class.NSNumber, Selector.Get("numberWithBool:"), false); IntPtr press_and_hold = Cocoa.SendIntPtr(Class.NSNumber, Selector.Get("numberWithBool:"), false); // Initialize and register the settings dictionary settings = Cocoa.SendIntPtr(settings, Selector.Get("initWithObjectsAndKeys:"), //momentum_scrolling, Cocoa.ToNSString("AppleMomentumScrollSupported"), press_and_hold, Cocoa.ToNSString("ApplePressAndHoldEnabled"), IntPtr.Zero); Cocoa.SendVoid( Cocoa.SendIntPtr(Class.NSUserDefaults, Selector.Get("standardUserDefaults")), Selector.Get("registerDefaults:"), settings); Cocoa.SendVoid(settings, Selector.Release); }
internal static void Initialize() { // Create the NSAutoreleasePool AutoreleasePool = Cocoa.SendIntPtr(Cocoa.SendIntPtr(Class.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(nsapp, Selector.Get("sharedApplication")); // Setup the application Cocoa.SendBool(Handle, Selector.Get("setActivationPolicy:"), (int)NSApplicationActivationPolicy.Regular); Cocoa.SendVoid(Handle, Selector.Get("activateIgnoringOtherApps:"), true); // Create the menu bar var menubar = Cocoa.SendIntPtr(Cocoa.SendIntPtr(Class.Get("NSMenu"), Selector.Alloc), Selector.Autorelease); var menuItem = Cocoa.SendIntPtr(Cocoa.SendIntPtr(Class.Get("NSMenuItem"), Selector.Alloc), Selector.Autorelease); // Add menu item to bar, and bar to application 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")); // Disable momentum scrolling and long-press key pop-ups IntPtr settings = Cocoa.SendIntPtr(Class.NSDictionary, Selector.Alloc); IntPtr momentum_scrolling = Cocoa.SendIntPtr(Class.NSNumber, Selector.Get("numberWithBool:"), false); IntPtr press_and_hold = Cocoa.SendIntPtr(Class.NSNumber, Selector.Get("numberWithBool:"), false); // Initialize and register the settings dictionary settings = Cocoa.SendIntPtr(settings, Selector.Get("initWithObjectsAndKeys:"), //momentum_scrolling, Cocoa.ToNSString("AppleMomentumScrollSupported"), press_and_hold, Cocoa.ToNSString("ApplePressAndHoldEnabled"), IntPtr.Zero); Cocoa.SendVoid( Cocoa.SendIntPtr(Class.NSUserDefaults, Selector.Get("standardUserDefaults")), Selector.Get("registerDefaults:"), settings); Cocoa.SendVoid(settings, Selector.Release); }
public override void ProcessEvents() { base.ProcessEvents(); while (true) { var e = Cocoa.SendIntPtr(NSApplication.Handle, selNextEventMatchingMask, uint.MaxValue, IntPtr.Zero, NSDefaultRunLoopMode, true); if (e == IntPtr.Zero) { break; } var type = (NSEventType)Cocoa.SendInt(e, selType); switch (type) { case NSEventType.KeyDown: { MacOSKeyCode keyCode = (MacOSKeyCode)Cocoa.SendUshort(e, selKeyCode); var isARepeat = Cocoa.SendBool(e, selIsARepeat); Key key = MacOSKeyMap.GetKey(keyCode); OnKeyDown(key, isARepeat); var s = Cocoa.FromNSString(Cocoa.SendIntPtr(e, selCharactersIgnoringModifiers)); foreach (var c in s) { int intVal = (int)c; if (!Char.IsControl(c) && (intVal < 63232 || intVal > 63235)) { // For some reason, arrow keys (mapped 63232-63235) // are seen as non-control characters, so get rid of those. OnKeyPress(c); } } } break; case NSEventType.KeyUp: { MacOSKeyCode keyCode = (MacOSKeyCode)Cocoa.SendUshort(e, selKeyCode); Key key = MacOSKeyMap.GetKey(keyCode); OnKeyUp(key); } break; case NSEventType.FlagsChanged: { var modifierFlags = (NSEventModifierMask)Cocoa.SendUint(e, selModifierFlags); UpdateModifierFlags(GetModifiers(modifierFlags)); } break; case NSEventType.MouseEntered: { var eventTrackingArea = Cocoa.SendIntPtr(e, selTrackingArea); var trackingAreaOwner = Cocoa.SendIntPtr(eventTrackingArea, selOwner); if (trackingAreaOwner == windowInfo.ViewHandle) { if (selectedCursor != MouseCursor.Default) { //SetCursor(selectedCursor); } OnMouseEnter(EventArgs.Empty); } } break; case NSEventType.MouseExited: { var eventTrackingArea = Cocoa.SendIntPtr(e, selTrackingArea); var trackingAreaOwner = Cocoa.SendIntPtr(eventTrackingArea, selOwner); if (trackingAreaOwner == windowInfo.ViewHandle) { if (selectedCursor != MouseCursor.Default) { //SetCursor(MouseCursor.Default); } OnMouseLeave(EventArgs.Empty); } } break; case NSEventType.LeftMouseDragged: case NSEventType.RightMouseDragged: case NSEventType.OtherMouseDragged: case NSEventType.MouseMoved: { Point p = new Point(MouseState.X, MouseState.Y); if (CursorVisible) { // Use absolute coordinates var pf = Cocoa.SendPoint(e, selLocationInWindowOwner); // Convert from points to pixel coordinates var rf = Cocoa.SendRect(windowInfo.Handle, selConvertRectToBacking, new RectangleF(pf.X, pf.Y, 0, 0)); // See CocoaDrawingGuide under "Converting from Window to View Coordinates" p = new Point( MathHelper.Clamp((int)Math.Round(rf.X), 0, Width), MathHelper.Clamp((int)Math.Round(Height - rf.Y), 0, Height)); } else { // Mouse has been disassociated, // use relative coordinates var dx = Cocoa.SendFloat(e, selDeltaX); var dy = Cocoa.SendFloat(e, selDeltaY); p = new Point( MathHelper.Clamp((int)Math.Round(p.X + dx), 0, Width), MathHelper.Clamp((int)Math.Round(p.Y + dy), 0, Height)); } // Only raise events when the mouse has actually moved if (MouseState.X != p.X || MouseState.Y != p.Y) { OnMouseMove(p.X, p.Y); } } break; case NSEventType.CursorUpdate: break; case NSEventType.ScrollWheel: { float dx, dy; if (Cocoa.SendBool(e, selHasPreciseScrollingDeltas)) { dx = Cocoa.SendFloat(e, selScrollingDeltaX) * MacOSFactory.ScrollFactor; dy = Cocoa.SendFloat(e, selScrollingDeltaY) * MacOSFactory.ScrollFactor; } else { dx = Cocoa.SendFloat(e, selDeltaX); dy = Cocoa.SendFloat(e, selDeltaY); } // Only raise wheel events when the user has actually scrolled if (dx != 0 || dy != 0) { OnMouseWheel(dx, dy); } } break; case NSEventType.LeftMouseDown: case NSEventType.RightMouseDown: case NSEventType.OtherMouseDown: { var buttonNumber = Cocoa.SendInt(e, selButtonNumber); OnMouseDown(GetMouseButton(buttonNumber)); } break; case NSEventType.LeftMouseUp: case NSEventType.RightMouseUp: case NSEventType.OtherMouseUp: { var buttonNumber = Cocoa.SendInt(e, selButtonNumber); OnMouseUp(GetMouseButton(buttonNumber)); } break; } Cocoa.SendVoid(NSApplication.Handle, selSendEvent, e); } // Handle closing if (shouldClose) { shouldClose = false; // PerformClose is equivalent to pressing the close-button, which // does not work in a borderless window. Handle this special case. if (GetStyleMask() == NSWindowStyle.Borderless) { if (WindowShouldClose(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero)) { Cocoa.SendVoid(windowInfo.Handle, selClose); } } else { Cocoa.SendVoid(windowInfo.Handle, selPerformClose, windowInfo.Handle); } } }