summaryrefslogtreecommitdiff
path: root/darwintest/runtimetest.go
blob: 1b0b825a5c4cb7b407d0b88433954e64d88a4a6b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// 27 february 2014
package main

import (
	"fmt"
	"time"
)

// #cgo LDFLAGS: -lobjc -framework Foundation -framework AppKit
// #include <stdlib.h>
// #include "objc_darwin.h"
// Class NilClass = Nil; /* for newtypes.go */
// id Nilid = nil;
import "C"

var (
	_NSApplication = objc_getClass("NSApplication")
	_NSNotificationCenter = objc_getClass("NSNotificationCenter")

	_sharedApplication = sel_getUid("sharedApplication")
	_defaultCenter = sel_getUid("defaultCenter")
	_run = sel_getUid("run")
)

var NSApp C.id
var defNC C.id
var delegate C.id
var notesel C.SEL

func init() {
	// need an NSApplication first - see https://github.com/TooTallNate/NodObjC/issues/21
	NSApp = C.objc_msgSend_noargs(_NSApplication, _sharedApplication)

	defNC = C.objc_msgSend_noargs(_NSNotificationCenter, _defaultCenter)

	selW := sel_getUid("windowShouldClose:")
	selB := sel_getUid("buttonClicked:")
	selN := sel_getUid("gotNotification:")
	mk("hello", selW, selB, selN)
	delegate = objc_alloc(objc_getClass("hello"))

	notesel = selN
}

const (
	NSBorderlessWindowMask = 0
	NSTitledWindowMask = 1 << 0
	NSClosableWindowMask = 1 << 1
	NSMiniaturizableWindowMask = 1 << 2
	NSResizableWindowMask = 1 << 3
	NSTexturedBackgroundWindowMask = 1 << 8
)

const (
//	NSBackingStoreRetained = 0			// "You should not use this mode."
//	NSBackingStoreNonretained = 1		// "You should not use this mode."
	NSBackingStoreBuffered = 2
)

const (
	NSRoundedBezelStyle = 1
	// TODO copy in the rest?
)

var (
	_NSAutoreleasePool = objc_getClass("NSAutoreleasePool")

	_performSelectorOnMainThread =
		sel_getUid("performSelectorOnMainThread:withObject:waitUntilDone:")
)

func notify(source string) {
	// we need to make an NSAutoreleasePool, otherwise we get leak warnings on stderr
	pool := objc_new(_NSAutoreleasePool)
	src := toNSString(source)
	C.objc_msgSend_sel_id_bool(
		delegate,
		_performSelectorOnMainThread,
		notesel,
		src,
		C.BOOL(C.YES))			// wait so we can properly drain the autorelease pool; on other platforms we wind up waiting anyway (since the main thread can only handle one thing at a time) so
	objc_release(pool)
}

var (
	_NSWindow = objc_getClass("NSWindow")
	_NSButton = objc_getClass("NSButton")

	_initWithContentRect = sel_getUid("initWithContentRect:styleMask:backing:defer:")
	_setDelegate = sel_getUid("setDelegate:")
	_makeKeyAndOrderFront = sel_getUid("makeKeyAndOrderFront:")
	_contentView = sel_getUid("contentView")
	_initWithFrame = sel_getUid("initWithFrame:")
	_setTarget = sel_getUid("setTarget:")
	_setAction = sel_getUid("setAction:")
	_setBezelStyle = sel_getUid("setBezelStyle:")
	_addSubview = sel_getUid("addSubview:")
)

func main() {
	style := uintptr(NSTitledWindowMask | NSClosableWindowMask)
	backing := uintptr(NSBackingStoreBuffered)
	deferx := C.BOOL(C.YES)
	window := objc_alloc(_NSWindow)
	window = objc_msgSend_rect_uint_uint_bool(window,
		_initWithContentRect,
		100, 100, 320, 240,
		style, backing, deferx)
	C.objc_msgSend_id(window, _makeKeyAndOrderFront, window)
	C.objc_msgSend_id(window, _setDelegate, delegate)
	windowView := C.objc_msgSend_noargs(window, _contentView)

	button := objc_alloc(_NSButton)
	button = objc_msgSend_rect(button,
		_initWithFrame,
		20, 20, 200, 200)
	C.objc_msgSend_id(button, _setTarget, delegate)
	C.objc_msgSend_sel(button,
		_setAction,
		sel_getUid("buttonClicked:"))
	objc_msgSend_uint(button, _setBezelStyle, NSRoundedBezelStyle)
	C.objc_msgSend_id(windowView, _addSubview, button)

	go func() {
		for {
			<-time.After(5 * time.Second)
			fmt.Println("five seconds passed; sending notification...")
			notify("timer")
		}
	}()

	C.objc_msgSend_noargs(NSApp, _run)
}