/
App_darwin.go
137 lines (117 loc) · 2.7 KB
/
App_darwin.go
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
134
135
136
137
// +build darwin
package frame
/*
#cgo CFLAGS: -DWEBVIEW_COCOA=1 -x objective-c
#cgo LDFLAGS: -framework Cocoa -framework WebKit
#ifndef WEBVIEW_COCOA
#define WEBVIEW_COCOA
#endif
#import "c_darwin.h"
*/
import "C"
import (
"fmt"
"runtime"
"sync"
"sync/atomic"
"time"
)
type (
// App is main application object
App struct {
mainMenu *Menu
appMenu *Menu
openedWns sync.WaitGroup
shown chan bool
}
)
var (
mutexNew sync.Mutex
winds = []*Window{}
lock sync.Mutex
appChan = make(chan *App)
idItr int64
)
// WaitAllWindowClose locker
func (a *App) WaitAllWindowClose() {
<-a.shown
a.openedWns.Wait()
}
// WaitWindowClose locker
func (a *App) WaitWindowClose(win *Window) {
<-a.shown
shown := false
for {
if !win.state.Hidden {
shown = true
}
if win.state.Hidden && shown {
break
}
}
}
// SetIconFromFile sets dock icon
func (a *App) SetIconFromFile(filename string) {
C.setAppIconFromFile(C.CString(filename))
}
// MakeApp is make and run one instance of application (At the moment, it is possible to create only one instance)
func MakeApp(appName string) *App {
lock.Lock()
go func() {
runtime.LockOSThread()
C.makeApp(C.CString(appName))
runtime.UnlockOSThread()
}()
app := <-appChan
fmt.Println("App started")
return app
}
// NewWindow returns window with webview
func (a *App) NewWindow(title string, sizes ...int) *Window {
mutexNew.Lock()
defer mutexNew.Unlock()
id := atomic.AddInt64(&idItr, 1)
width := 500
height := 400
if len(sizes) > 0 {
width = sizes[0]
}
if len(sizes) > 1 {
height = sizes[1]
}
cRet := cRequest(func(reqid uint64) {
C.makeWindow(C.CString(title), C.int(width), C.int(height), C.ulonglong(reqid), C.int(int(id)))
})
ret, ok := cRet.(C.WindowObj)
if !ok {
panic("Object is not C.WindowObj!")
}
win := &Window{
id: id,
resizeble: true,
window: ret,
state: State{Hidden: true},
app: a,
MainMenu: a.mainMenu,
}
go func() {
time.Sleep(time.Second / 2)
for {
time.Sleep(time.Second / 10)
state := win.state
state.Maximized = goBool(C.isZoomed(C.WindowObj(win.window))) && win.resizeble
state.Iconified = goBool(C.isMiniaturized(C.WindowObj(win.window)))
state.Hidden = !goBool(C.isVisible(C.WindowObj(win.window))) && !goBool(C.isMiniaturized(C.WindowObj(win.window)))
state.Fullscreen = goBool(C.isFullscreen(C.WindowObj(win.window)))
if state.Iconified {
state.Focused = false
}
if state.Hidden != win.state.Hidden || (!state.Hidden && (state.Maximized != win.state.Maximized ||
state.Fullscreen != win.state.Fullscreen || state.Iconified != win.state.Iconified)) {
go stateSender(win, state)
}
}
}()
winds = append(winds, win)
return win
}