forked from BurntSushi/wingo
/
command_key.go
78 lines (69 loc) · 2.23 KB
/
command_key.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
/*
command_key.go is responsible for setting up *all* key bindings found
in the key.wini config file.
It isn't quite the same as command_mouse.go because they operate under
two different assumptions: key bindings are global in nature (i.e.,
they are bound to the root window) while mouse bindings are window
specific in nature (i.e., bound to each specific window).
This actually makes command_key.go simpler than command_mouse.go, because
we don't need to provide an interface for each client to bind keys
separately. We can just bind them to the root window and let the commands
infer state and act appropriately.
*/
package main
import (
"github.com/BurntSushi/xgbutil"
"github.com/BurntSushi/xgbutil/keybind"
"github.com/BurntSushi/xgbutil/xevent"
"github.com/BurntSushi/wingo/logger"
)
type keyCommand struct {
cmd string
args []string
down bool // 'up' when false
keyStr string
}
func attachAllKeys() {
for _, kcmds := range wingo.conf.key {
for _, kcmd := range kcmds {
kcmd.attach(commandFun(kcmd.keyStr, kcmd.cmd, kcmd.args...))
}
}
}
func (kcmd keyCommand) attach(run func()) {
if run == nil {
return
}
if kcmd.cmd == "PromptCyclePrev" || kcmd.cmd == "PromptCycleNext" {
// We've got to parse the key string first and make sure
// there are some modifiers; otherwise this utterly fails!
mods, _, _ := keybind.ParseString(X, kcmd.keyStr)
if mods == 0 {
logger.Warning.Printf("Sorry but the key binding '%s' for the %s "+
"command is invalid. It must have a modifier "+
"to work properly. i.e., Mod1-tab where 'Mod1' "+
"is the modifier.", kcmd.keyStr, kcmd.cmd)
return
}
keybind.KeyPressFun(
func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) {
run()
}).Connect(X, wingo.root.Id, kcmd.keyStr, true)
keybind.KeyPressFun(
func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) {
run()
}).Connect(X, X.Dummy(), kcmd.keyStr, true)
} else {
if kcmd.down {
keybind.KeyPressFun(
func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) {
run()
}).Connect(X, wingo.root.Id, kcmd.keyStr, true)
} else {
keybind.KeyReleaseFun(
func(X *xgbutil.XUtil, ev xevent.KeyReleaseEvent) {
run()
}).Connect(X, wingo.root.Id, kcmd.keyStr, true)
}
}
}