hbspbar

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

commit 6a1ca4bae672d7b6edc50c9a31b0404467714edb
parent 6117c8a98a39cd8bc1ca6b2436b6dab8873053f9
Author: hhvn <dev@hhvn.uk>
Date:   Sat, 18 Nov 2023 15:02:35 +0000

Move all xgb using functions to drw

Diffstat:
Mbar/bar.go | 75++++++++-------------------------------------------------------------------
Mbspc/bspc.go | 2+-
Mdrw/x.go | 81++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mmain.go | 2+-
4 files changed, 84 insertions(+), 76 deletions(-)

diff --git a/bar/bar.go b/bar/bar.go @@ -10,23 +10,14 @@ import ( "hhvn.uk/hbspbar/common" "hhvn.uk/hbspbar/bspc" "hhvn.uk/hbspbar/drw" - - "github.com/jezek/xgb" - "github.com/jezek/xgb/xproto" - - "github.com/jezek/xgbutil" - "github.com/jezek/xgbutil/icccm" - "github.com/jezek/xgbutil/ewmh" - "github.com/jezek/xgbutil/xgraphics" ) var bars map[int]*bar -var stoploop chan bool type bar struct { Mon *bspc.Monitor - w xproto.Window + w *drw.Window i *image.RGBA drawing sync.Mutex } @@ -36,29 +27,10 @@ func (b *bar) init() error { go b.Mon.TopPadding(config.H) - b.w, err = xproto.NewWindowId(drw.X) - if err != nil { - return common.Perror("xproto.NewWindowId", err) - } - geom := b.Mon.Rectangle - xproto.CreateWindow(drw.X, drw.Screen.RootDepth, b.w, drw.Screen.Root, - int16(geom.X), int16(geom.Y), uint16(geom.Width), uint16(config.H), 0, - xproto.WindowClassInputOutput, drw.Screen.RootVisual, - xproto.CwBackPixel|xproto.CwEventMask, []uint32{ - config.Bg, - xproto.EventMaskStructureNotify }) - - class := icccm.WmClass{"hbspbar", "hbspbar"} - icccm.WmClassSet(drw.XU, b.w, &class) - - ewmh.WmWindowTypeSet(drw.XU, b.w, []string{"_NET_WM_WINDOW_TYPE_DOCK"}) - ewmh.WmStateSet(drw.XU, b.w, []string{"_NET_WM_STATE_STICKY", "_NET_WM_STATE_ABOVE"}) - - err = xproto.MapWindowChecked(drw.X, b.w).Check() - if err != nil { - return common.Perror("xproto.MapWindow", err) - } + + b.w, err = drw.WindowCreate(geom.X, geom.Y, geom.Width, config.H) + if err != nil { return err } b.i = image.NewRGBA(b.rect()) @@ -136,11 +108,7 @@ func (b *bar) draw() { } cx += 5 - xgr := xgraphics.NewConvert(drw.XU, b.i) - - xgr.XSurfaceSet(b.w) - xgr.XDraw() - xgr.XPaint(b.w) + b.w.Paint(b.i) b.drawing.Unlock() } @@ -149,12 +117,6 @@ func (b *bar) destroy() { if (b.Mon != nil) { b.Mon.TopPadding(0) } - xproto.DestroyWindow(drw.X, b.w) -} - -type eventwrap struct { - Ev xgb.Event - Err error } // External interface @@ -176,25 +138,8 @@ func init() { Handle.NewState = make(chan *bspc.State) Handle.Err = make(chan error) - events := make(chan *eventwrap) - stoploop = make(chan bool, 1) - xstop := make(chan bool, 1) - - go func() { for { - ev, err := drw.X.WaitForEvent() - w := eventwrap{ev, err} - - select { - case <- xstop: - return - default: - events <- &w - } - }}() - go func() { defer func() { - xstop <- true close(Handle.Create) close(Handle.Destroy) close(Handle.NewState) @@ -203,7 +148,7 @@ func init() { for { select { - case e := <- events: + case e := <- drw.Events: if e.Ev == nil && e.Err == nil { Handle.Err <- fmt.Errorf("X connection clossed") return @@ -229,7 +174,7 @@ func init() { return } if _, ok := bars[id]; ok { break } - if err := create(drw.X, drw.XU, drw.Screen, state.GetMon(id)); err != nil { + if err := create(state.GetMon(id)); err != nil { Handle.Err <- fmt.Errorf("Couldn't create window: %s\n", err) return } @@ -240,15 +185,12 @@ func init() { go b.draw() } } - case <- stoploop: - return } } }() } -func create(x *xgb.Conn, xu *xgbutil.XUtil, - scr *xproto.ScreenInfo, m *bspc.Monitor) (error) { +func create(m *bspc.Monitor) (error) { var b bar b.Mon = m @@ -272,5 +214,4 @@ func Cleanup() { for _, b := range bars { b.destroy() } - stoploop <- true } diff --git a/bspc/bspc.go b/bspc/bspc.go @@ -207,7 +207,7 @@ func init() { }}() } -func Close() { +func Cleanup() { Handle.cmd.Process.Kill() } diff --git a/drw/x.go b/drw/x.go @@ -2,6 +2,7 @@ package drw // import "hhvn.uk/hbspbar/drw" import ( "os" + "image" "image/color" "hhvn.uk/hbspbar/config" @@ -10,36 +11,44 @@ import ( "github.com/jezek/xgb" "github.com/jezek/xgb/xproto" "github.com/jezek/xgbutil" + "github.com/jezek/xgbutil/icccm" + "github.com/jezek/xgbutil/ewmh" "github.com/jezek/xgbutil/xgraphics" "github.com/BurntSushi/freetype-go/freetype" "github.com/BurntSushi/freetype-go/freetype/truetype" ) +type eventwrap struct { + Ev xgb.Event + Err error +} + var InitErr error -var X *xgb.Conn -var XU *xgbutil.XUtil -var Screen *xproto.ScreenInfo +var Events chan *eventwrap +var xc *xgb.Conn +var xu *xgbutil.XUtil +var screen *xproto.ScreenInfo var font *truetype.Font var ft *freetype.Context func init() { var err error - X, err = xgb.NewConn() + xc, err = xgb.NewConn() if err != nil { InitErr = err return } - XU, err = xgbutil.NewConnXgb(X) + xu, err = xgbutil.NewConnXgb(xc) if err != nil { InitErr = err return } - setup := xproto.Setup(X) - Screen = setup.DefaultScreen(X) + setup := xproto.Setup(xc) + screen = setup.DefaultScreen(xc) read, err := os.Open(config.Font) if err != nil { @@ -57,6 +66,18 @@ func init() { ft.SetDPI(72) ft.SetFont(font) ft.SetFontSize(config.FontSize) + + Events := make(chan *eventwrap) + + go func() { for { + ev, err := xc.WaitForEvent() + w := eventwrap{ev, err} + + select { + default: + Events <- &w + } + }}() } func int2rgb(argb uint32) (color.RGBA) { @@ -66,3 +87,49 @@ func int2rgb(argb uint32) (color.RGBA) { R: uint8((argb & 0x00ff0000) >> 16), A: uint8((argb & 0xff000000) >> 24) } } + +type Window struct { + id xproto.Window +} + +func WindowCreate(x, y, w, h uint) (*Window, error) { + var win Window + var err error + + win.id, err = xproto.NewWindowId(xc) + if err != nil { + return nil, common.Perror("xproto.NewWindowId", err) + } + + xproto.CreateWindow(xc, screen.RootDepth, win.id, screen.Root, + int16(x), int16(y), uint16(w), uint16(h), 0, + xproto.WindowClassInputOutput, screen.RootVisual, + xproto.CwBackPixel|xproto.CwEventMask, []uint32{ + config.Bg, + xproto.EventMaskStructureNotify }) + + class := icccm.WmClass{"hbspbar", "hbspbar"} + icccm.WmClassSet(xu, win.id, &class) + + ewmh.WmWindowTypeSet(xu, win.id, []string{"_NET_WM_WINDOW_TYPE_DOCK"}) + ewmh.WmStateSet(xu, win.id, []string{"_NET_WM_STATE_STICKY", "_NET_WM_STATE_ABOVE"}) + + err = xproto.MapWindowChecked(xc, win.id).Check() + if err != nil { + return nil, common.Perror("xproto.MapWindow", err) + } + + return &win, nil +} + +func (w *Window) Paint(i image.Image) { + xgr := xgraphics.NewConvert(xu, i) + + xgr.XSurfaceSet(w.id) + xgr.XDraw() + xgr.XPaint(w.id) +} + +func (w *Window) Destroy() { + xproto.DestroyWindow(xc, w.id) +} diff --git a/main.go b/main.go @@ -30,7 +30,7 @@ func main() { common.Error("Couldn't subscribe to bspwm: %s\n", bspc.InitErr) return } - defer bspc.Close() + defer bspc.Cleanup() bar.Handle.NewState <- bspc.Handle.State for _, m := range bspc.Handle.State.Monitors {