hbspbar

[WIP] bspwm status bar
git clone https://hhvn.uk/hbspbar
git clone git://hhvn.uk/hbspbar
Log | Files | Refs

commit 76dc78859b31cd15c8327e64b7684fbc2063a0b4
parent c20f2aa6185c8ac1f7f309c469ea43acd8e8719c
Author: hhvn <dev@hhvn.uk>
Date:   Tue, 31 Oct 2023 11:36:24 +0000

Successfully destroys and recreates windows upon bspwm reload

Diffstat:
Mbar/bar.go | 39++++++++++++++++++++++++++++-----------
Mbspc/bspc.go | 4++++
Mmain.go | 32++++++++++++++++++++++----------
3 files changed, 54 insertions(+), 21 deletions(-)

diff --git a/bar/bar.go b/bar/bar.go @@ -42,8 +42,9 @@ var conf = struct { "/usr/share/fonts/TTF/DejaVuSansMono.ttf", 11.0, 1 } -var bars *list.List -var font *truetype.Font +var bars *list.List +var font *truetype.Font +var stoploop chan bool type bar struct { X *xgb.Conn @@ -162,6 +163,7 @@ func (b *bar) draw() { func (b *bar) destroy() { b.Mon.TopPadding(0) + xproto.DestroyWindow(b.X, b.w) } type eventwrap struct { @@ -198,8 +200,9 @@ func Init(state *bspc.State) (*Handle, error) { h.NewState = make(chan *bspc.State) h.Err = make(chan error) - events := make(chan *eventwrap) - xstop := make(chan bool, 1) + events := make(chan *eventwrap) + stoploop = make(chan bool, 1) + xstop := make(chan bool, 1) go func() { for { ev, err := x.WaitForEvent() @@ -229,15 +232,16 @@ func Init(state *bspc.State) (*Handle, error) { continue } - switch e.Ev.(type) { - case xproto.DestroyNotifyEvent: - h.Err <- fmt.Errorf("Window destroyed") - return - default: - } + // switch e.Ev.(type) { + // case xproto.DestroyNotifyEvent: + // h.Err <- fmt.Errorf("Window destroyed") + // return + // default: + // } case id := <- h.Destroy: destroy(id) case id := <- h.Create: + if getbar(id) != nil { break } if err := create(x, xu, screen, state.GetMon(id)); err != nil { h.Err <- fmt.Errorf("Couldn't create window: %s\n", err) return @@ -248,6 +252,8 @@ func Init(state *bspc.State) (*Handle, error) { v.Mon = state.GetMon(v.Mon.ID) go v.draw() } + case <- stoploop: + return } } }() @@ -255,6 +261,16 @@ func Init(state *bspc.State) (*Handle, error) { return &h, nil } +func getbar(monid int) (*bar) { + for e := bars.Front(); e != nil; e = e.Next() { + v := e.Value.(*bar) + + if v.Mon.ID == monid { return v } + } + + return nil +} + func create(x *xgb.Conn, xu *xgbutil.XUtil, scr *xproto.ScreenInfo, m *bspc.Monitor) (error) { var b bar @@ -284,7 +300,7 @@ func destroy(monid int) (bool) { /* A monid of -1 means that we're doing the bar.Cleanup schermoodle today */ - if monid == -1 || monid > 0 && v.Mon.ID == int(monid) { + if monid == -1 || monid > 0 && v.Mon.ID == monid { v.destroy() bars.Remove(e) if monid != -1 { return true } @@ -297,4 +313,5 @@ func destroy(monid int) (bool) { func Cleanup() { destroy(-1) + stoploop <- true } diff --git a/bspc/bspc.go b/bspc/bspc.go @@ -186,6 +186,10 @@ func (s *Subscriber) get() (*Event, error) { var err error for { line, err = s.getLine() + // if line == "W" { + // // Send this pseudo event so we know to reload the state + // return &Event{"reload", make([]string, 0)}, nil + // } if len(line) > 0 && line[0] != 'W' { break } } diff --git a/main.go b/main.go @@ -15,6 +15,8 @@ var reloadEvents = []string{ "monitor_rename", "monitor_swap", "monitor_focus", + "monitor_remove", + "monitor_geometry", // only event we get for monitors on restart "desktop_add", "desktop_rename", "desktop_remove", @@ -56,8 +58,11 @@ func handleEvents(events *bspc.Subscriber, bar *bar.Handle) (chan error, chan bo id, err := common.Intify(event.Tokens[0]) if err == nil { switch (event.Name) { - case "monitor_add": bar.Create <- id - case "monitor_remove": bar.Destroy <- id + case "monitor_add": + case "monitor_geometry": + bar.Create <- id + case "monitor_remove": + bar.Destroy <- id } } } @@ -106,15 +111,7 @@ func main() { everr, evreload := handleEvents(events, barhandle) for { - select { - case <- evreload: - state, err = reloadState(state) - if err != nil { - common.Error("Couldn't reload bspwm state: %s\n", err) - } - - barhandle.NewState <- state case err := <- everr: common.Error("Couldn't read event: %s\n", err) return @@ -124,6 +121,21 @@ func main() { case err := <- barhandle.Err: common.Error("%s\n", err) return + case <- evreload: + state, err = reloadState(state) + if err != nil { + common.Error("Couldn't reload bspwm state: %s\n", err) + } + + // Check if there's been an error before sending the + // new state (or else the program gets stuck) + select { + case err := <- barhandle.Err: + common.Error("%s\n", err) + return + default: + } + barhandle.NewState <- state } } }