summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bspc/bspc.go66
-rw-r--r--common/common.go13
-rw-r--r--main.go72
3 files changed, 110 insertions, 41 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, " ")}
}
diff --git a/common/common.go b/common/common.go
index 00ac8e6..20c2c0a 100644
--- a/common/common.go
+++ b/common/common.go
@@ -3,6 +3,7 @@ package common
import (
"os"
"fmt"
+ "strconv"
)
func Perror(function string, err error) error {
@@ -10,5 +11,15 @@ func Perror(function string, err error) error {
}
func Error(format string, a ... any) (int, error) {
- return fmt.Fprintf(os.Stderr, format, a)
+ fmt.Fprintf(os.Stderr, "error: ")
+ if (len(a) == 0) {
+ return fmt.Fprintf(os.Stderr, format)
+ } else {
+ return fmt.Fprintf(os.Stderr, format, a)
+ }
+}
+
+func Intify(s string) (int, error) {
+ i, err := strconv.ParseInt(s, 0, 0)
+ return int(i), err
}
diff --git a/main.go b/main.go
index 36dba0e..a9e23c2 100644
--- a/main.go
+++ b/main.go
@@ -1,7 +1,7 @@
package main
import (
- "fmt"
+ "strings"
"hhvn.uk/hbspbar/common"
"hhvn.uk/hbspbar/bspc"
@@ -13,32 +13,78 @@ import (
*/
)
+var reloadEvents = []string{
+ "monitor_rename",
+ "monitor_swap",
+ "monitor_focus",
+ "desktop_add",
+ "desktop_rename",
+ "desktop_remove",
+ "desktop_swap",
+ "desktop_transfer",
+ "desktop_focus",
+ "desktop_activate",
+ "desktop_layout",
+ "node_add",
+ "node_remove",
+ "node_swap",
+ "node_transfer" }
+
+func reloadState(current *bspc.State) (*bspc.State, error) {
+ state, err := bspc.LoadState()
+
+ if err != nil {
+ return current, err
+ } else {
+ return state, nil
+ }
+}
+
+func handleEvent(events *bspc.Subscriber) (bool) {
+ var event *bspc.Event
+
+ select {
+ case event = <-events.Event:
+ break
+ default:
+ return false
+ }
+
+ if event.Err != nil {
+ common.Error("Couldn't read event: %s\n", event.Err)
+ return false
+ }
+
+ for i := 0; i < len(reloadEvents); i++ {
+ if event.Name == reloadEvents[i] {
+ return true
+ }
+ }
+
+ return false
+}
+
func main() {
state, err := bspc.LoadState()
if (err != nil) {
- common.Error("Couldn't load bspwm state: %s", err)
+ common.Error("Couldn't load bspwm state: %s\n", err)
return
}
events, err := bspc.Subscribe()
if (err != nil) {
- common.Error("Couldn't subscribe to bspwm: %s", err)
+ common.Error("Couldn't subscribe to bspwm: %s\n", err)
return
}
defer events.Close()
- fmt.Println(state.Monitors[0].ID)
for {
- event, err := events.Get()
-
- if err != nil {
- common.Error("Couldn't read event: %s", err)
- return
- }
-
- if event != nil {
- fmt.Printf("Event: %v %v\n", event.Name, event.Tokens)
+ if reload := handleEvent(events); reload {
+ state, err = reloadState(state)
+ if err != nil {
+ common.Error("Couldn't reload bspwm state: %s\n", err)
+ }
}
}
}