-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathglobalhotkey.go
92 lines (77 loc) · 1.69 KB
/
globalhotkey.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
//go:build windows
// +build windows
package walk
import (
"sync"
"sync/atomic"
"syscall"
)
// Windows hotkey modifiers
const (
modAlt = 0x0001
modControl = 0x0002
modShift = 0x0004
modWin = 0x0008
modNoRepeat = 0x4000
)
var (
// Library
user32 = syscall.NewLazyDLL("user32.dll")
// Functions
registerHotKey = user32.NewProc("RegisterHotKey")
unregisterHotKey = user32.NewProc("UnregisterHotKey")
)
var (
nextHotkeyID uint32
hotkeys sync.Map // map[uint32]*GlobalHotKey
)
// GlobalHotKey represents a registered global hotkey
type GlobalHotKey struct {
id uint32
shortcut Shortcut
window *WindowBase
handler func()
}
// RegisterGlobalHotKey registers a global hotkey with Windows
func RegisterGlobalHotKey(window *WindowBase, shortcut Shortcut, handler func()) (*GlobalHotKey, error) {
id := atomic.AddUint32(&nextHotkeyID, 1)
modifiers := uint32(0)
if shortcut.Modifiers&ModShift != 0 {
modifiers |= modShift
}
if shortcut.Modifiers&ModControl != 0 {
modifiers |= modControl
}
if shortcut.Modifiers&ModAlt != 0 {
modifiers |= modAlt
}
ret, _, _ := registerHotKey.Call(
uintptr(window.hWnd),
uintptr(id),
uintptr(modifiers),
uintptr(shortcut.Key),
)
if ret == 0 {
return nil, newError("RegisterHotKey failed")
}
hotkey := &GlobalHotKey{
id: id,
shortcut: shortcut,
window: window,
handler: handler,
}
hotkeys.Store(id, hotkey)
return hotkey, nil
}
// Unregister unregisters the global hotkey
func (h *GlobalHotKey) Unregister() error {
ret, _, _ := unregisterHotKey.Call(
uintptr(h.window.hWnd),
uintptr(h.id),
)
if ret == 0 {
return newError("UnregisterHotKey failed")
}
hotkeys.Delete(h.id)
return nil
}