summaryrefslogtreecommitdiff
path: root/bspc
diff options
context:
space:
mode:
authorhhvn <dev@hhvn.uk>2023-08-08 10:46:53 +0100
committerhhvn <dev@hhvn.uk>2023-08-08 10:49:30 +0100
commit0543020038edb5de1162863e7401ea36f8a8584c (patch)
tree713f77ec14b560a341863fed05502c62e062a593 /bspc
parent2e3b351c355bd241de4aa4f2bdafd633ccef6eac (diff)
Channel-based bspwm communication
Diffstat (limited to 'bspc')
-rw-r--r--bspc/bspc.go66
1 files changed, 39 insertions, 27 deletions
diff --git a/bspc/bspc.go b/bspc/bspc.go
index 568919e..f3b7ff3 100644
--- a/bspc/bspc.go
+++ b/bspc/bspc.go
@@ -63,11 +63,19 @@ func LoadState() (*State, error) {
}
type Subscriber struct {
+ Event chan *Event
+ cleanup chan bool
cmd *exec.Cmd
pipe io.ReadCloser
scanner *bufio.Scanner
}
+type Event struct {
+ Err error
+ Name string
+ Tokens []string
+}
+
func Subscribe() (*Subscriber, error) {
cmd := exec.Command("bspc", "subscribe", "all")
@@ -80,20 +88,35 @@ func Subscribe() (*Subscriber, error) {
return nil, common.Perror("cmd.Start", err)
}
- var ret Subscriber
- ret.cmd = cmd
- ret.pipe = pipe
- ret.scanner = bufio.NewScanner(ret.pipe)
-
- return &ret, nil
+ var s Subscriber
+ s.Event = make(chan *Event)
+ s.cleanup = make(chan bool)
+ s.cmd = cmd
+ s.pipe = pipe
+ s.scanner = bufio.NewScanner(s.pipe)
+
+ go func() {
+ for {
+ select {
+ case <- s.cleanup:
+ s.cmd.Wait()
+ return
+ default:
+ if event := s.get(); event != nil {
+ s.Event <- event
+ }
+ }
+ }
+ }()
+
+ return &s, nil
}
-type Event struct {
- Name string
- Tokens []string
+func (s *Subscriber) Close() {
+ s.cleanup <- true
}
-func (s *Subscriber) GetLine() (string, error) {
+func (s *Subscriber) getLine() (string, error) {
if s.scanner.Scan() {
return s.scanner.Text(), nil
}
@@ -105,29 +128,18 @@ func (s *Subscriber) GetLine() (string, error) {
return "", nil
}
-func (s *Subscriber) Get() (*Event, error) {
+func (s *Subscriber) get() (*Event) {
var line string
var err error
for {
- line, err = s.GetLine()
+ line, err = s.getLine()
if line[0] != 'W' { break }
}
- if err != nil { return nil, err }
- if line == "" { return nil, nil }
-
- name, tokens, found := strings.Cut(line, " ")
+ if line == "" { return nil }
+ if err != nil { return &Event{err, "", nil} }
- var event Event
- event.Name = name
- event.Tokens = strings.Split(tokens, " ")
-
- // We do not found. Shut up, compiler.
- found = !found
-
- return &event, nil
-}
+ name, tokens, _ := strings.Cut(line, " ")
-func (s *Subscriber) Close() error {
- return s.cmd.Wait()
+ return &Event{nil, name, strings.Split(tokens, " ")}
}