-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathdock_darwin.go
More file actions
98 lines (83 loc) · 2.13 KB
/
Copy pathdock_darwin.go
File metadata and controls
98 lines (83 loc) · 2.13 KB
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
//go:build darwin
package gova
/*
#cgo CFLAGS: -x objective-c -fobjc-arc
#cgo LDFLAGS: -framework AppKit -framework Foundation
#include <stdlib.h>
#import "dock_darwin.h"
*/
import "C"
import (
"sync"
"sync/atomic"
"unsafe"
)
type darwinDock struct{}
func newPlatformDock() dockImpl { return darwinDock{} }
func (darwinDock) SetBadge(text string) {
cstr := C.CString(text)
defer C.free(unsafe.Pointer(cstr))
C.govaDockSetBadge(cstr)
}
func (darwinDock) SetProgress(frac float64) { C.govaDockSetProgress(C.double(frac)) }
func (darwinDock) Bounce() { C.govaDockBounce() }
func (darwinDock) SetMenu(items []DockMenuItem) {
count := len(items)
if count == 0 {
C.govaDockSetMenu(nil, nil, 0)
return
}
cLabels := make([]*C.char, count)
cIDs := make([]C.ulonglong, count)
for i, it := range items {
cLabels[i] = C.CString(it.Label)
if it.Action != nil && it.Label != "" {
cIDs[i] = C.ulonglong(registerDockHandler(it.Action))
}
}
defer func() {
for _, p := range cLabels {
C.free(unsafe.Pointer(p))
}
}()
C.govaDockSetMenu(
(**C.char)(unsafe.Pointer(&cLabels[0])),
(*C.ulonglong)(unsafe.Pointer(&cIDs[0])),
C.int(count),
)
}
func (darwinDock) Close() {}
// setMacAppIcon pushes the given PNG bytes to NSApp as the dock icon.
// Harmless when data is empty.
func setMacAppIcon(data []byte) {
if len(data) == 0 {
return
}
C.govaSetAppIcon(unsafe.Pointer(&data[0]), C.int(len(data)))
}
// Handler registry. Menu items cannot carry Go closures across the cgo
// boundary, so we keep them in a Go-side map keyed by a monotonic uint64 ID.
// The ObjC menu item stashes the ID in its NSMenuItem.tag; when the user
// clicks, ObjC calls govaDockMenuFire(id), which looks up and invokes the
// closure.
var (
dockHandlerSeq atomic.Uint64
dockHandlerMu sync.Mutex
dockHandlers = map[uint64]func(){}
)
func registerDockHandler(fn func()) uint64 {
id := dockHandlerSeq.Add(1)
dockHandlerMu.Lock()
dockHandlers[id] = fn
dockHandlerMu.Unlock()
return id
}
//export govaDockMenuFire
func govaDockMenuFire(id C.ulonglong) {
dockHandlerMu.Lock()
fn := dockHandlers[uint64(id)]
dockHandlerMu.Unlock()
if fn != nil {
fn()
}
}