gioui.org/ui@v0.0.0-20190926171558-ce74bc0cbaea/app/os_macos.m (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 // +build darwin,!ios 4 5 @import AppKit; 6 7 #include "os_macos.h" 8 #include "_cgo_export.h" 9 10 @interface GioDelegate : NSObject<NSApplicationDelegate, NSWindowDelegate> 11 @property (strong,nonatomic) NSWindow *window; 12 @end 13 14 @implementation GioDelegate 15 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 16 [[NSRunningApplication currentApplication] activateWithOptions:(NSApplicationActivateAllWindows | NSApplicationActivateIgnoringOtherApps)]; 17 [self.window makeKeyAndOrderFront:self]; 18 gio_onShow((__bridge CFTypeRef)self.window.contentView); 19 } 20 - (void)applicationDidHide:(NSNotification *)aNotification { 21 gio_onHide((__bridge CFTypeRef)self.window.contentView); 22 } 23 - (void)applicationWillUnhide:(NSNotification *)notification { 24 gio_onShow((__bridge CFTypeRef)self.window.contentView); 25 } 26 - (void)windowWillMiniaturize:(NSNotification *)notification { 27 gio_onHide((__bridge CFTypeRef)self.window.contentView); 28 } 29 - (void)windowDidDeminiaturize:(NSNotification *)notification { 30 gio_onShow((__bridge CFTypeRef)self.window.contentView); 31 } 32 - (void)windowDidChangeScreen:(NSNotification *)notification { 33 CGDirectDisplayID dispID = [[[self.window screen] deviceDescription][@"NSScreenNumber"] unsignedIntValue]; 34 CFTypeRef view = (__bridge CFTypeRef)self.window.contentView; 35 gio_updateDisplayLink(view, dispID); 36 } 37 - (void)windowDidBecomeKey:(NSNotification *)notification { 38 gio_onFocus((__bridge CFTypeRef)self.window.contentView, YES); 39 } 40 - (void)windowDidResignKey:(NSNotification *)notification { 41 gio_onFocus((__bridge CFTypeRef)self.window.contentView, NO); 42 } 43 - (void)windowWillClose:(NSNotification *)notification { 44 gio_onTerminate((__bridge CFTypeRef)self.window.contentView); 45 self.window.delegate = nil; 46 [NSApp terminate:nil]; 47 } 48 @end 49 50 CGFloat gio_viewHeight(CFTypeRef viewRef) { 51 NSView *view = (__bridge NSView *)viewRef; 52 return [view bounds].size.height; 53 } 54 55 CGFloat gio_viewWidth(CFTypeRef viewRef) { 56 NSView *view = (__bridge NSView *)viewRef; 57 return [view bounds].size.width; 58 } 59 60 // Points pr. dp. 61 static CGFloat getPointsPerDP(NSScreen *screen) { 62 NSDictionary *description = [screen deviceDescription]; 63 NSSize displayPixelSize = [[description objectForKey:NSDeviceSize] sizeValue]; 64 CGSize displayPhysicalSize = CGDisplayScreenSize([[description objectForKey:@"NSScreenNumber"] unsignedIntValue]); 65 return (25.4/160)*displayPixelSize.width / displayPhysicalSize.width; 66 } 67 68 // Pixels pr dp. 69 CGFloat gio_getPixelsPerDP(void) { 70 NSScreen *screen = [NSScreen mainScreen]; 71 return getPointsPerDP(screen); 72 } 73 74 CGFloat gio_getBackingScale() { 75 NSScreen *screen = [NSScreen mainScreen]; 76 return [screen backingScaleFactor]; 77 } 78 79 CGFloat gio_getViewBackingScale(CFTypeRef viewRef) { 80 NSView *view = (__bridge NSView *)viewRef; 81 return [view.window backingScaleFactor]; 82 } 83 84 void gio_main(CFTypeRef viewRef, const char *title, CGFloat width, CGFloat height) { 85 @autoreleasepool { 86 NSView *view = (NSView *)CFBridgingRelease(viewRef); 87 [NSApplication sharedApplication]; 88 [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; 89 90 NSMenuItem *mainMenu = [NSMenuItem new]; 91 92 NSMenu *menu = [NSMenu new]; 93 NSMenuItem *hideMenuItem = [[NSMenuItem alloc] initWithTitle:@"Hide" 94 action:@selector(hide:) 95 keyEquivalent:@"h"]; 96 [menu addItem:hideMenuItem]; 97 NSMenuItem *quitMenuItem = [[NSMenuItem alloc] initWithTitle:@"Quit" 98 action:@selector(terminate:) 99 keyEquivalent:@"q"]; 100 [menu addItem:quitMenuItem]; 101 [mainMenu setSubmenu:menu]; 102 NSMenu *menuBar = [NSMenu new]; 103 [menuBar addItem:mainMenu]; 104 [NSApp setMainMenu:menuBar]; 105 106 NSRect rect = NSMakeRect(0, 0, width, height); 107 NSWindowStyleMask styleMask = NSWindowStyleMaskTitled | 108 NSWindowStyleMaskResizable | 109 NSWindowStyleMaskMiniaturizable | 110 NSWindowStyleMaskClosable; 111 NSWindow* window = [[NSWindow alloc] initWithContentRect:rect 112 styleMask:styleMask 113 backing:NSBackingStoreBuffered 114 defer:NO]; 115 window.title = [NSString stringWithUTF8String: title]; 116 [window cascadeTopLeftFromPoint:NSMakePoint(20,20)]; 117 [window setAcceptsMouseMovedEvents:YES]; 118 119 gio_onCreate((__bridge CFTypeRef)view); 120 GioDelegate *del = [[GioDelegate alloc] init]; 121 del.window = window; 122 [window setDelegate:del]; 123 [NSApp setDelegate:del]; 124 [window setContentView:view]; 125 [window makeFirstResponder:view]; 126 127 128 [NSApp run]; 129 } 130 }