forked from linuxdeepin/dde-daemon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
xrecord_event_handler.go
132 lines (118 loc) · 3.32 KB
/
xrecord_event_handler.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
/*
* Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package shortcuts
import (
"strings"
x "github.com/linuxdeepin/go-x11-client"
"github.com/linuxdeepin/go-x11-client/util/keysyms"
)
type XRecordEventHandler struct {
keySymbols *keysyms.KeySymbols
pressedMods uint16
historyPressedMods uint16
nonModKeyPressed bool
modKeyReleasedCb func(uint8, uint16)
allModKeysReleasedCb func()
}
func NewXRecordEventHandler(keySymbols *keysyms.KeySymbols) *XRecordEventHandler {
return &XRecordEventHandler{
keySymbols: keySymbols,
}
}
//func (h *XRecordEventHandler) logPressedMods(title string) {
// logger.Debug(title, "pressedMods:", Modifiers(h.pressedMods))
//}
func (h *XRecordEventHandler) handleButtonEvent(pressed bool) {
if h.pressedMods > 0 {
h.nonModKeyPressed = true
}
}
func (h *XRecordEventHandler) handleKeyEvent(pressed bool, keycode uint8, state uint16) {
keystr, _ := h.keySymbols.LookupString(x.Keycode(keycode), state)
//var pr string
//if pressed {
// pr = "PRESS"
//} else {
// pr = "RELEASE"
//}
//logger.Debugf("%s keycode: [%d|%s], state: %v\n", pr, keycode, keystr, Modifiers(state))
if pressed {
mod, ok := key2Mod(keystr)
if ok {
h.pressedMods |= mod
h.historyPressedMods |= mod
} else {
//logger.Debug("non-mod key pressed")
if h.pressedMods > 0 {
h.nonModKeyPressed = true
}
}
//h.logPressedMods("pressed")
} else {
// release
//h.logPressedMods("before release")
mod, ok := key2Mod(keystr)
if !ok {
return
}
if h.pressedMods == h.historyPressedMods && !h.nonModKeyPressed {
if h.modKeyReleasedCb != nil {
logger.Debugf("modKeyReleased keycode %d historyPressedMods: %s",
keycode, Modifiers(h.historyPressedMods))
h.modKeyReleasedCb(keycode, h.historyPressedMods)
}
}
h.pressedMods &^= mod
//h.logPressedMods("after release")
if h.pressedMods == 0 {
h.historyPressedMods = 0
h.nonModKeyPressed = false
if h.allModKeysReleasedCb != nil {
//logger.Debug("allModKeysReleased")
h.allModKeysReleasedCb()
}
}
}
}
func key2Mod(key string) (uint16, bool) {
key = strings.ToLower(key)
// caps_lock and num_lock
if key == "caps_lock" {
return keysyms.ModMaskCapsLock, true
} else if key == "num_lock" {
return keysyms.ModMaskNumLock, true
}
// control/alt/meta/shift/super _ l/r
i := strings.IndexByte(key, '_')
if i == -1 {
return 0, false
}
match := key[0:i]
switch match {
case "shift":
return keysyms.ModMaskShift, true
case "control":
return keysyms.ModMaskControl, true
case "super":
return keysyms.ModMaskSuper, true
case "alt", "meta":
return keysyms.ModMaskAlt, true
}
return 0, false
}