From 0543020038edb5de1162863e7401ea36f8a8584c Mon Sep 17 00:00:00 2001 From: hhvn Date: Tue, 8 Aug 2023 10:46:53 +0100 Subject: Channel-based bspwm communication --- bspc/bspc.go | 66 +++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 27 deletions(-) (limited to 'bspc') 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, " ")} } -- cgit v1.2.3