summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bar.go (renamed from bar/bar.go)138
-rw-r--r--main.go54
2 files changed, 87 insertions, 105 deletions
diff --git a/bar/bar.go b/bar.go
index e7d66ff..6c3c981 100644
--- a/bar/bar.go
+++ b/bar.go
@@ -1,20 +1,17 @@
-package bar // import "hhvn.uk/hbspbar/bar"
+package main
import (
- "fmt"
"image"
"errors"
"image/color"
"hhvn.uk/hbspbar/config"
- "hhvn.uk/hbspbar/common"
"hhvn.uk/hbspbar/status"
"hhvn.uk/hbspbar/bspc"
"hhvn.uk/hbspbar/drw"
)
-
-var bars map[int]*bar
+var bars map[int]*bar = make(map[int]*bar)
type bar struct {
id int
@@ -22,20 +19,10 @@ type bar struct {
i *image.RGBA
}
-func create(state *bspc.State, id int) (error) {
- var b bar
-
- if err := b.init(id, state); err != nil {
- return err
- }
-
- if bars == nil {
- bars = make(map[int]*bar)
- }
-
- bars[b.id] = &b
- return nil
-}
+var (
+ ErrNoState = errors.New("attempted to create a bar with uninitialized state")
+ ErrNoSuchBar = errors.New("attempted to destroy non-existant bar")
+)
func (b *bar) init(id int, state *bspc.State) error {
b.id = id
@@ -76,17 +63,17 @@ func (b *bar) drawRect(x, y, w, h int, c color.Color, fill bool) {
drw.DrawRect(b.i, x, y, w, h, c, fill)
}
-func (b bar) draw(state *bspc.State, blocks []*status.Block) {
+func (b bar) draw(state *bspc.State, blocks []*status.Block) error {
var bg color.Color
var filled bool
if blocks == nil {
- return
+ return nil
}
mon, err := b.getmon(state)
if err != nil {
- return
+ return err
}
// Dimensions of drawing space
@@ -163,77 +150,50 @@ func (b bar) draw(state *bspc.State, blocks []*status.Block) {
}
b.w.Paint(b.i)
+
+ return nil
}
-var Create = make(chan int)
-var Destroy = make(chan int)
-var NewState = make(chan *bspc.State)
-var Err = make(chan error)
-
-// Store the state for when bar.Cleanup() is called
-// This is a bit hacky but I don't really see any alternative
-var finalstate *bspc.State = nil
-
-func init() {
- var state *bspc.State = nil
- var blocks []*status.Block = nil
-
- go func() {
- defer func() {
- close(Create)
- close(Destroy)
- close(NewState)
- close(Err)
- }()
-
- for {
- select {
- case e := <- drw.Events:
- if e.Ev == nil && e.Err == nil {
- Err <- fmt.Errorf("X connection clossed")
- return
- }
-
- if e.Err != nil {
- common.Perror("X.WaitForEvents", e.Err)
- continue
- }
-
- // switch e.Ev.(type) {
- // case xproto.DestroyNotifyEvent:
- // Err <- fmt.Errorf("Window destroyed")
- // return
- // default:
- // }
- case id := <- Destroy:
- bars[id].destroy(state)
- delete(bars, id)
- case id := <- Create:
- if state == nil {
- Err <- errors.New("attempted to create a bar with uninitialized state")
- return
- }
- if _, ok := bars[id]; ok { break }
- if err := create(state, id); err != nil {
- Err <- fmt.Errorf("Couldn't create window: %s\n", err)
- return
- }
- case blocks = <- status.NewBlocks:
- for _, b := range bars {
- b.draw(state, blocks)
- }
- case state = <- NewState:
- finalstate = state
- for _, b := range bars {
- b.draw(state, blocks)
- }
- }
- }
- }()
+func Create(state *bspc.State, id int) (error) {
+ var b bar
+
+ if state == nil {
+ return ErrNoState
+ }
+
+ if _, ok := bars[id]; ok {
+ // Already created, whatever.
+ return nil
+ }
+
+ if err := b.init(id, state); err != nil {
+ return err
+ }
+
+ bars[b.id] = &b
+ return nil
+}
+
+func Redraw(state *bspc.State, blocks []*status.Block) {
+ for _, b := range bars {
+ b.draw(state, blocks)
+ }
+}
+
+func Destroy(state *bspc.State, id int) error {
+ b, ok := bars[id]
+ if !ok {
+ return ErrNoSuchBar
+ }
+
+ b.destroy(state)
+ delete(bars, id)
+
+ return nil
}
-func Cleanup() {
- if finalstate != nil {
+func Cleanup(state *bspc.State) {
+ if state != nil {
for _, b := range bars {
b.destroy(finalstate)
}
diff --git a/main.go b/main.go
index cac7c6c..4bef201 100644
--- a/main.go
+++ b/main.go
@@ -6,12 +6,16 @@ import (
"strings"
"syscall"
- "hhvn.uk/hbspbar/bar"
"hhvn.uk/hbspbar/bspc"
"hhvn.uk/hbspbar/common"
"hhvn.uk/hbspbar/drw"
+ "hhvn.uk/hbspbar/status"
)
+// Store the state for when bar.Cleanup() is called
+// This is a bit hacky but I don't really see any alternative
+var finalstate *bspc.State = nil
+
func main() {
signals := make(chan os.Signal, 1)
signal.Notify(signals,
@@ -19,8 +23,6 @@ func main() {
syscall.SIGHUP,
syscall.SIGTERM)
- defer bar.Cleanup()
-
if drw.InitErr != nil {
common.Error("Couldn't initialize X: %s\n", drw.InitErr)
return
@@ -33,22 +35,37 @@ func main() {
defer bspc.Cleanup()
state := <- bspc.NewState
- bar.NewState <- state
for _, m := range state.Monitors {
- bar.Create <- m.ID
+ Create(state, m.ID)
}
- for {
+ var blocks []*status.Block = nil
+
+ mainloop: for {
select {
case s := <-signals:
common.Error("%s\n", s)
- return
- case err := <-bar.Err:
- common.Error("%s\n", err)
- return
+ break mainloop
+ case e := <- drw.Events:
+ if e.Ev == nil && e.Err == nil {
+ common.Error("X connection clossed\n")
+ break mainloop
+ }
+
+ if e.Err != nil {
+ common.Perror("X.WaitForEvents", e.Err)
+ continue
+ }
+
+ // switch e.Ev.(type) {
+ // case xproto.DestroyNotifyEvent:
+ // Err <- fmt.Errorf("Window destroyed")
+ // return
+ // default:
+ // }
case err := <-bspc.EvErr:
common.Error("Couldn't read event: %s\n", err)
- return
+ break mainloop
case event := <-bspc.Event:
if strings.HasPrefix(event.Name, "monitor_") {
id, err := common.Intify(event.Tokens[0])
@@ -56,17 +73,22 @@ func main() {
switch event.Name {
case "monitor_add":
case "monitor_geometry":
- bar.Create <- id
+ Create(state, id)
case "monitor_remove":
- bar.Destroy <- id
+ Destroy(state, id)
}
}
}
case err := <-bspc.StErr:
common.Error("Couldn't load bspwm state: %s\n", err)
- return
- case s := <-bspc.NewState:
- bar.NewState <- s
+ break mainloop
+ case blocks = <- status.NewBlocks:
+ Redraw(state, blocks)
+ case state = <- bspc.NewState:
+ finalstate = state
+ Redraw(state, blocks)
}
}
+
+ Cleanup(finalstate)
}