Skip to content

Commit c2fe955

Browse files
authored
Merge pull request #14 from ArtemT/press-twice
Feature: Add an option to switch layout by double keystroke
2 parents 38e6f31 + 03e4013 commit c2fe955

File tree

1 file changed

+35
-10
lines changed

1 file changed

+35
-10
lines changed

shift-shift.go

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,15 @@ type Message struct {
3333

3434
func main() {
3535
var (
36-
listDevices = flag.Bool("list", false, "list all devices listened by evdev")
37-
printMode = flag.Bool("print", false, "print pressed keys")
38-
quietMode = flag.Bool("quiet", false, "be silent")
39-
deviceMatch = flag.String("match", "keyboard", "regexp used to match keyboard device")
40-
keysymFirst = flag.String("first", "LEFTSHIFT", "key used for switcing on first xkb group")
41-
keysymSecond = flag.String("second", "RIGHTSHIFT", "key used for switcing on second xkb group")
42-
scanOnce = flag.Bool("scan-once", false, "scan for devices only at startup (less power consumption)")
36+
listDevices = flag.Bool("list", false, "list all devices listened by evdev")
37+
printMode = flag.Bool("print", false, "print pressed keys")
38+
quietMode = flag.Bool("quiet", false, "be silent")
39+
deviceMatch = flag.String("match", "keyboard", "regexp used to match keyboard device")
40+
keysymFirst = flag.String("first", "LEFTSHIFT", "key used for switching on first xkb group")
41+
keysymSecond = flag.String("second", "RIGHTSHIFT", "key used for switching on second xkb group")
42+
scanOnce = flag.Bool("scan-once", false, "scan for devices only at startup (less power consumption)")
43+
dblKeystroke = flag.Bool("double-keystroke", false, "require pressing the same key twice to switch the layout")
44+
dblKeyTimeout = flag.Int("double-keystroke-timeout", 500, "second keystroke timeout in milliseconds")
4345
)
4446

4547
flag.Parse()
@@ -86,6 +88,7 @@ func main() {
8688
display, keyFirst, keySecond,
8789
*printMode, *quietMode,
8890
reDeviceMatch, *scanOnce,
91+
*dblKeystroke, *dblKeyTimeout,
8992
)
9093

9194
<-terminate
@@ -213,13 +216,17 @@ func listenKeyboards(
213216
display *C.Display,
214217
keyFirst uint16, keySecond uint16,
215218
printMode, quietMode bool, deviceMatch *regexp.Regexp,
216-
scanOnce bool,
219+
scanOnce bool, dblKeystroke bool, dblKeyTimeout int,
217220
) {
218221
var groupFirst, groupSecond bool
222+
var t *time.Timer
219223

220224
inbox := make(chan Message, 8)
221225
kbdLost := make(chan bool, 8)
222226
kbdLost <- true // init
227+
if dblKeystroke {
228+
t = time.NewTimer(time.Duration(dblKeyTimeout) * time.Millisecond)
229+
}
223230

224231
go scanDevices(inbox, deviceMatch, quietMode, scanOnce)
225232

@@ -242,9 +249,17 @@ func listenKeyboards(
242249
case 1: // key down
243250
switch ev.Code {
244251
case keyFirst:
245-
groupFirst = true
252+
if dblKeystroke {
253+
t, groupFirst = checkTimeout(t, dblKeyTimeout)
254+
} else {
255+
groupFirst = true
256+
}
246257
case keySecond:
247-
groupSecond = true
258+
if dblKeystroke {
259+
t, groupSecond = checkTimeout(t, dblKeyTimeout)
260+
} else {
261+
groupSecond = true
262+
}
248263
default: // other keys
249264
groupFirst = false
250265
groupSecond = false
@@ -292,3 +307,13 @@ func listenEvents(
292307
replyTo <- Message{Device: kbd, Events: events}
293308
}
294309
}
310+
311+
// Checks if the key was pressed before the timer was expired
312+
// Resets expired timer
313+
func checkTimeout(t *time.Timer, timeout int) (*time.Timer, bool) {
314+
if t.Stop() {
315+
return t, true
316+
}
317+
t.Reset(time.Duration(timeout) * time.Millisecond)
318+
return t, false
319+
}

0 commit comments

Comments
 (0)