Skip to content

Commit bc3c4ea

Browse files
committed
fix(keyboard): better handling of context cancellation
1 parent f8e5ac2 commit bc3c4ea

1 file changed

Lines changed: 34 additions & 37 deletions

File tree

keyboard.go

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -143,21 +143,19 @@ func findAllInputDevices() []string {
143143

144144
// SnoopAllKeyboards will snoop or listen for all key events on all currently connected keyboards. Keyboards are passed in through a channel, see OpenKeyboardDevices for an example of opening all connected keyboards
145145
func SnoopAllKeyboards(ctx context.Context, kbds <-chan *KeyboardDevice) <-chan KeyEvent {
146-
keys := make(chan KeyEvent)
147-
var wg sync.WaitGroup
146+
keys := make(chan KeyEvent, 1)
147+
done := make(chan struct{})
148148
for kbd := range kbds {
149149
log.Debug().Caller().
150150
Msgf("Tracking keys on device %s.", kbd.fd.Name())
151-
wg.Add(1)
152-
go func(ctx context.Context, k *KeyboardDevice, keyCh chan KeyEvent) {
153-
defer wg.Done()
154-
kbdSnoop(ctx, k, keyCh)
155-
}(ctx, kbd, keys)
151+
go func(k *KeyboardDevice, keyCh chan KeyEvent, doneCh chan struct{}) {
152+
kbdSnoop(k, keyCh, doneCh)
153+
}(kbd, keys, done)
156154
}
157155
go func() {
156+
defer close(keys)
157+
defer close(done)
158158
<-ctx.Done()
159-
close(keys)
160-
wg.Wait()
161159
}()
162160
return keys
163161
}
@@ -166,46 +164,45 @@ func SnoopAllKeyboards(ctx context.Context, kbds <-chan *KeyboardDevice) <-chan
166164
// device.
167165
func SnoopKeyboard(ctx context.Context, kbd *KeyboardDevice) <-chan KeyEvent {
168166
keys := make(chan KeyEvent)
169-
var wg sync.WaitGroup
170-
wg.Add(1)
167+
done := make(chan struct{})
171168
go func() {
172-
defer wg.Done()
173-
kbdSnoop(ctx, kbd, keys)
169+
kbdSnoop(kbd, keys, done)
174170
}()
175171
go func() {
172+
defer close(keys)
173+
defer close(done)
176174
<-ctx.Done()
177-
close(keys)
178-
wg.Wait()
179175
}()
180176
return keys
181177
}
182178

183-
func kbdSnoop(ctx context.Context, kbd *KeyboardDevice, keys chan KeyEvent) {
179+
func kbdSnoop(kbd *KeyboardDevice, keys chan KeyEvent, done chan struct{}) {
184180
norm := C.enum_libevdev_read_flag(C.LIBEVDEV_READ_FLAG_NORMAL)
185181
for {
182+
var ev C.struct_input_event
183+
if err := C.libevdev_next_event(kbd.dev, C.uint(norm), &ev); err != 0 {
184+
log.Error().Msg("libevdev_next_event returned an error.")
185+
}
186+
e := NewKeyEvent(ev)
187+
if e.Value != 2 {
188+
switch e.EventName {
189+
case "KEY_CAPSLOCK":
190+
kbd.modifiers.ToggleCapsLock()
191+
case "KEY_LEFTSHIFT", "KEY_RIGHTSHIFT":
192+
kbd.modifiers.ToggleShift()
193+
case "KEY_LEFTCTRL", "KEY_RIGHTCTRL":
194+
kbd.modifiers.ToggleCtrl()
195+
case "KEY_LEFTALT", "KEY_RIGHTALT":
196+
kbd.modifiers.ToggleAlt()
197+
case "KEY_LEFTMETA", "KEY_RIGHTMETA":
198+
kbd.modifiers.ToggleMeta()
199+
}
200+
}
201+
e.updateRune(kbd.modifiers)
186202
select {
187-
case <-ctx.Done():
203+
case <-done:
188204
return
189-
default:
190-
var ev C.struct_input_event
191-
C.libevdev_next_event(kbd.dev, C.uint(norm), &ev)
192-
e := NewKeyEvent(ev)
193-
if e.Value != 2 {
194-
switch e.EventName {
195-
case "KEY_CAPSLOCK":
196-
kbd.modifiers.ToggleCapsLock()
197-
case "KEY_LEFTSHIFT", "KEY_RIGHTSHIFT":
198-
kbd.modifiers.ToggleShift()
199-
case "KEY_LEFTCTRL", "KEY_RIGHTCTRL":
200-
kbd.modifiers.ToggleCtrl()
201-
case "KEY_LEFTALT", "KEY_RIGHTALT":
202-
kbd.modifiers.ToggleAlt()
203-
case "KEY_LEFTMETA", "KEY_RIGHTMETA":
204-
kbd.modifiers.ToggleMeta()
205-
}
206-
}
207-
e.updateRune(kbd.modifiers)
208-
keys <- *e
205+
case keys <- *e:
209206
}
210207
}
211208
}

0 commit comments

Comments
 (0)