commit 77c48c8a8074cfb48f346b77760eb3d58a2716dc
parent 0a5f0070526a2c32e7b7f65a50ecd993babfedfa
Author: hhvn <dev@hhvn.uk>
Date: Sat, 27 Jan 2024 16:32:30 +0000
Clean up bspc/
Diffstat:
M | bspc/bspc.go | | | 91 | ++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- |
M | main.go | | | 15 | ++++++++------- |
2 files changed, 63 insertions(+), 43 deletions(-)
diff --git a/bspc/bspc.go b/bspc/bspc.go
@@ -4,6 +4,7 @@ import (
"io"
"fmt"
"time"
+ "sync"
"bufio"
"errors"
"strings"
@@ -84,6 +85,31 @@ var reloadEvents = []string{
"node_swap",
"node_transfer" }
+var cmdlist []*exec.Cmd
+var cmdlock sync.Mutex
+
+func cmdRegister(c *exec.Cmd) int {
+ cmdlock.Lock()
+ defer cmdlock.Unlock()
+
+ for i, v := range cmdlist {
+ if v == nil {
+ cmdlist[i] = c
+ return i
+ }
+ }
+
+ cmdlist = append(cmdlist, c)
+ i := len(cmdlist) - 1
+ return i
+}
+
+func cmdDelete(i int) {
+ cmdlock.Lock()
+ defer cmdlock.Unlock()
+ cmdlist[i] = nil
+}
+
func getState() (*State, error) {
cmd := exec.Command("bspc", "wm", "-d")
@@ -122,27 +148,20 @@ func getState() (*State, error) {
return &state, nil
}
-type subscriber struct {
- State *State
- StateUpdate chan bool
- StErr chan error
- Event chan *Event
- EvErr chan error
- cmd *exec.Cmd
- pipe io.ReadCloser
- scanner *bufio.Scanner
-}
-
-type Event struct {
+type event struct {
Name string
Tokens []string
}
-var InitErr error
-var Handle subscriber
+var InitErr error
+var NewState = make(chan *State, 1) // Buffered to prevent blocking on first send
+var StErr = make(chan error)
+var Event = make(chan *event)
+var EvErr = make(chan error)
func init() {
cmd := exec.Command("bspc", "subscribe", "all")
+ cmdRegister(cmd)
pipe, err := cmd.StdoutPipe()
if err != nil {
@@ -161,35 +180,29 @@ func init() {
return
}
- Handle.State = istate
- Handle.StateUpdate = make(chan bool)
- Handle.StErr = make(chan error)
- Handle.Event = make(chan *Event)
- Handle.EvErr = make(chan error)
- Handle.cmd = cmd
- Handle.pipe = pipe
- Handle.scanner = bufio.NewScanner(Handle.pipe)
+ NewState <- istate
+
+ scanner := bufio.NewScanner(pipe)
go func() { for {
- event, err := get()
+ event, err := get(scanner)
if event != nil {
for i := 0; i < len(reloadEvents); i++ {
if event.Name == reloadEvents[i] {
state, serr := getState()
if serr != nil {
- Handle.StErr <- serr
+ StErr <- serr
return
}
- Handle.State = state
- Handle.StateUpdate <- true
+ NewState <- state
}
}
- Handle.Event <- event
+ Event <- event
}
if err != nil {
- Handle.EvErr <- err
+ EvErr <- err
return
}
}}()
@@ -198,6 +211,7 @@ func init() {
func Cmd(args ...string) {
cmd := exec.Command("bspc", args...)
+ cmdi := cmdRegister(cmd)
pipe, _ := cmd.StderrPipe()
scan := bufio.NewScanner(pipe)
startt := time.Now()
@@ -214,29 +228,34 @@ func Cmd(args ...string) {
}
cmd.Wait()
+ cmdDelete(cmdi)
}
func Cleanup() {
- Handle.cmd.Process.Kill()
+ for _, c := range cmdlist {
+ if c != nil {
+ c.Process.Kill()
+ }
+ }
}
-func getLine() (string, error) {
- if Handle.scanner.Scan() {
- return Handle.scanner.Text(), nil
+func getLine(s *bufio.Scanner) (string, error) {
+ if s.Scan() {
+ return s.Text(), nil
}
- if err := Handle.scanner.Err(); err != nil {
+ if err := s.Err(); err != nil {
return "", common.Perror("scanner.Err", err)
}
return "", nil
}
-func get() (*Event, error) {
+func get(s *bufio.Scanner) (*event, error) {
var line string
var err error
for {
- line, err = getLine()
+ line, err = getLine(s)
if len(line) > 0 && line[0] != 'W' { break }
}
@@ -245,5 +264,5 @@ func get() (*Event, error) {
name, tokens, _ := strings.Cut(line, " ")
- return &Event{name, strings.Split(tokens, " ")}, nil
+ return &event{name, strings.Split(tokens, " ")}, nil
}
diff --git a/main.go b/main.go
@@ -32,8 +32,9 @@ func main() {
}
defer bspc.Cleanup()
- bar.NewState <- bspc.Handle.State
- for _, m := range bspc.Handle.State.Monitors {
+ state := <- bspc.NewState
+ bar.NewState <- state
+ for _, m := range state.Monitors {
bar.Create <- m.ID
}
@@ -45,10 +46,10 @@ func main() {
case err := <-bar.Err:
common.Error("%s\n", err)
return
- case err := <-bspc.Handle.EvErr:
+ case err := <-bspc.EvErr:
common.Error("Couldn't read event: %s\n", err)
return
- case event := <-bspc.Handle.Event:
+ case event := <-bspc.Event:
if strings.HasPrefix(event.Name, "monitor_") {
id, err := common.Intify(event.Tokens[0])
if err == nil {
@@ -61,11 +62,11 @@ func main() {
}
}
}
- case err := <-bspc.Handle.StErr:
+ case err := <-bspc.StErr:
common.Error("Couldn't load bspwm state: %s\n", err)
return
- case <-bspc.Handle.StateUpdate:
- bar.NewState <- bspc.Handle.State
+ case s := <-bspc.NewState:
+ bar.NewState <- s
}
}
}