/
watcher.go
65 lines (55 loc) · 1.33 KB
/
watcher.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
package x11
import (
"context"
"log"
"time"
"github.com/BurntSushi/xgb"
"github.com/seeruk/barbara/event"
)
// RandrEventWatcher watches for randr events in X, allowing other parts of the application to react
// to randr events (e.g. for re-rendering bars).
type RandrEventWatcher struct {
dispatcher *event.Dispatcher
xc *xgb.Conn
}
// NewRandrEventWatcher returns a new RandrEventWatcher instance.
func NewRandrEventWatcher(dispatcher *event.Dispatcher, xc *xgb.Conn) *RandrEventWatcher {
return &RandrEventWatcher{
dispatcher: dispatcher,
xc: xc,
}
}
// Watch starts watching for randr events from the X server. It will debounce events, waiting for 1
// second of no event activity before sending a WM event in the event dispatcher.
func (w *RandrEventWatcher) Watch(ctx context.Context) {
debounceCh := make(chan struct{}, 128)
go func() {
for {
select {
case <-ctx.Done():
return
default:
}
_, err := w.xc.WaitForEvent()
if err != nil {
// TODO(elliot): What to do...
log.Fatal(err)
}
debounceCh <- struct{}{}
}
}()
go func() {
var timerCh <-chan time.Time
for {
select {
case <-ctx.Done():
return
case <-debounceCh:
timerCh = time.After(time.Second)
case <-timerCh:
// Dispatch WM event.
w.dispatcher.Dispatch(event.TypeWM)
}
}
}()
}