commit bc9ea1846fb9b64479190b878a14498bb692c192
parent 2a8069eb9606af55f76ac43e187ca83a7dd6957f
Author: hhvn <dev@hhvn.uk>
Date: Thu, 16 Nov 2023 20:45:11 +0000
Create x package
Diffstat:
M | bar/bar.go | | | 127 | ++++++++++++++++++++++++++----------------------------------------------------- |
D | bar/x.go | | | 79 | ------------------------------------------------------------------------------- |
M | main.go | | | 10 | ++++++---- |
A | x/x.go | | | 100 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
4 files changed, 148 insertions(+), 168 deletions(-)
diff --git a/bar/bar.go b/bar/bar.go
@@ -3,10 +3,13 @@ package bar // import "hhvn.uk/hbspbar/bar"
import (
"fmt"
"sync"
+ "image"
"errors"
+ "hhvn.uk/hbspbar/config"
"hhvn.uk/hbspbar/common"
"hhvn.uk/hbspbar/bspc"
+ X "hhvn.uk/hbspbar/x"
"github.com/jezek/xgb"
"github.com/jezek/xgb/xproto"
@@ -15,113 +18,94 @@ import (
"github.com/jezek/xgbutil/icccm"
"github.com/jezek/xgbutil/ewmh"
"github.com/jezek/xgbutil/xgraphics"
-
- "github.com/BurntSushi/freetype-go/freetype/truetype"
)
-var conf = struct {
- H uint
- Bg uint32
- Bg2 uint32
- Bg3 uint32
- Fg uint32
- FgDark uint32
- Sel uint32
- Urg uint32
- Font string
- FontSize float64
- FontYPad int
-} { 17,
- 0xff050a10,
- 0xff0c1726,
- 0xff14283c,
- 0xffeeeeee,
- 0xff444444,
- 0xff1b364b,
- 0xff90222b,
- "/usr/share/fonts/TTF/DejaVuSansMono.ttf",
- 11.0, 1 }
var bars map[int]*bar
-var font *truetype.Font
var stoploop chan bool
type bar struct {
- X *xgb.Conn
- Xu *xgbutil.XUtil
- Scr *xproto.ScreenInfo
Mon *bspc.Monitor
w xproto.Window
i *xgraphics.Image
- tw, th int
- tbpad int
drawing sync.Mutex
}
func (b *bar) init() error {
var err error
- go b.Mon.TopPadding(conf.H)
+ go b.Mon.TopPadding(config.H)
- b.w, err = xproto.NewWindowId(b.X)
+ b.w, err = xproto.NewWindowId(X.X)
if err != nil {
return common.Perror("xproto.NewWindowId", err)
}
geom := b.Mon.Rectangle
- xproto.CreateWindow(b.X, b.Scr.RootDepth, b.w, b.Scr.Root,
- int16(geom.X), int16(geom.Y), uint16(geom.Width), uint16(conf.H), 0,
- xproto.WindowClassInputOutput, b.Scr.RootVisual,
+ xproto.CreateWindow(X.X, X.Screen.RootDepth, b.w, X.Screen.Root,
+ int16(geom.X), int16(geom.Y), uint16(geom.Width), uint16(config.H), 0,
+ xproto.WindowClassInputOutput, X.Screen.RootVisual,
xproto.CwBackPixel|xproto.CwEventMask, []uint32{
- conf.Bg,
+ config.Bg,
xproto.EventMaskStructureNotify })
class := icccm.WmClass{"hbspbar", "hbspbar"}
- icccm.WmClassSet(b.Xu, b.w, &class)
+ icccm.WmClassSet(X.XU, b.w, &class)
- ewmh.WmWindowTypeSet(b.Xu, b.w, []string{"_NET_WM_WINDOW_TYPE_DOCK"})
- ewmh.WmStateSet(b.Xu, b.w, []string{"_NET_WM_STATE_STICKY", "_NET_WM_STATE_ABOVE"})
+ ewmh.WmWindowTypeSet(X.XU, b.w, []string{"_NET_WM_WINDOW_TYPE_DOCK"})
+ ewmh.WmStateSet(X.XU, b.w, []string{"_NET_WM_STATE_STICKY", "_NET_WM_STATE_ABOVE"})
- err = xproto.MapWindowChecked(b.X, b.w).Check()
+ err = xproto.MapWindowChecked(X.X, b.w).Check()
if err != nil {
return common.Perror("xproto.MapWindow", err)
}
- b.drawReInit()
- b.tw, b.th, _ = b.i.Text(0, 0, int2BGRA(conf.Fg), conf.FontSize, font, "X")
- b.tbpad = (int(conf.H) - b.th) / 2
+ b.reInit()
return nil
}
+func (b *bar) reInit() {
+ X.GraphicReInit(&b.i, image.Rect(0, 0,
+ int(b.Mon.Rectangle.Width), int(config.H)))
+}
+
+func (b *bar) drawText(x int, col uint32, text string) (int, error) {
+ return X.DrawText(b.i, x, col, text)
+}
+
+func (b *bar) drawRect(x, y, w, h int, c uint32, fill bool) {
+ X.DrawRect(b.i, x, y, w, h, c, fill)
+}
+
func (b *bar) draw() {
var bg uint32
var filled bool
b.drawing.Lock()
- b.drawReInit()
+ b.reInit()
// Dimensions of drawing space
cx := 0
w := int(b.Mon.Rectangle.Width)
- h := int(conf.H)
+ h := int(config.H)
// Draw background
- b.drawRect(0, 0, w, h, conf.Bg, true)
+ b.drawRect(0, 0, w, h, config.Bg, true)
// Monitor
montext := b.Mon.Name
- monw := 6 + b.textWidth(montext) + 8
+ monw := 6 + X.TextWidth(montext) + 8
if b.Mon.Focused {
- bg = conf.Sel
+ bg = config.Sel
} else {
- bg = conf.Bg2
+ bg = config.Bg2
}
b.drawRect(cx, 0, monw, h, bg, true)
- b.drawText(cx + 6, conf.Fg, montext)
+ b.drawText(cx + 6, config.Fg, montext)
cx += monw
// Desktops
@@ -130,7 +114,7 @@ func (b *bar) draw() {
dw := 4 + (4 + boxw + 2 + 3) * ds + 5
for i := 0; i < ds; i++ {
- dw += b.textWidth(b.Mon.Desktops[i].Name)
+ dw += X.TextWidth(b.Mon.Desktops[i].Name)
}
cx += 4
@@ -140,16 +124,16 @@ func (b *bar) draw() {
cx += 5
if d.Focused {
- bg = conf.Sel
+ bg = config.Sel
} else {
- bg = conf.FgDark
+ bg = config.FgDark
}
filled = d.Root != nil
b.drawRect(cx, 3, boxw, h - 7, bg, filled)
cx += boxw + 2
- ax, _ := b.drawText(cx, conf.Fg, d.Name)
+ ax, _ := b.drawText(cx, config.Fg, d.Name)
cx += ax + 2
}
cx += 5
@@ -165,7 +149,7 @@ func (b *bar) destroy() {
if (b.Mon != nil) {
b.Mon.TopPadding(0)
}
- xproto.DestroyWindow(b.X, b.w)
+ xproto.DestroyWindow(X.X, b.w)
}
type eventwrap struct {
@@ -181,33 +165,9 @@ type handle struct {
Err chan error
}
-var InitErr error
var Handle handle
func init() {
- InitErr = nil
-
- x, err := xgb.NewConn()
- if err != nil {
- InitErr = err
- return
- }
-
- xu, err := xgbutil.NewConnXgb(x)
- if err != nil {
- InitErr = err
- return
- }
-
- font, err = getFont(conf.Font)
- if err != nil {
- InitErr = err
- return
- }
-
- setup := xproto.Setup(x)
- screen := setup.DefaultScreen(x)
-
var state *bspc.State
state = nil
@@ -221,7 +181,7 @@ func init() {
xstop := make(chan bool, 1)
go func() { for {
- ev, err := x.WaitForEvent()
+ ev, err := X.X.WaitForEvent()
w := eventwrap{ev, err}
select {
@@ -250,7 +210,7 @@ func init() {
}
if e.Err != nil {
- common.Perror("x.WaitForEvents", err)
+ common.Perror("X.WaitForEvents", e.Err)
continue
}
@@ -269,7 +229,7 @@ func init() {
return
}
if _, ok := bars[id]; ok { break }
- if err := create(x, xu, screen, state.GetMon(id)); err != nil {
+ if err := create(X.X, X.XU, X.Screen, state.GetMon(id)); err != nil {
Handle.Err <- fmt.Errorf("Couldn't create window: %s\n", err)
return
}
@@ -291,9 +251,6 @@ func create(x *xgb.Conn, xu *xgbutil.XUtil,
scr *xproto.ScreenInfo, m *bspc.Monitor) (error) {
var b bar
- b.X = x
- b.Xu = xu
- b.Scr = scr
b.Mon = m
b.i = nil
diff --git a/bar/x.go b/bar/x.go
@@ -1,79 +0,0 @@
-package bar // import "hhvn.uk/hbspbar/bar"
-
-import (
- "os"
- "image"
-
- "hhvn.uk/hbspbar/common"
-
- "github.com/jezek/xgbutil/xgraphics"
- "github.com/BurntSushi/freetype-go/freetype/truetype"
-)
-
-func getFont(path string) (*truetype.Font, error) {
- read, err := os.Open(path)
- if err != nil {
- return nil, common.Perror("os.Open", err)
- }
-
- font, err := xgraphics.ParseFont(read)
- if err != nil {
- return nil, common.Perror("xgraphics.ParseFont", err)
- }
-
- return font, nil
-}
-
-func int2BGRA(argb uint32) (xgraphics.BGRA) {
- return xgraphics.BGRA{
- B: uint8( argb & 0x000000ff),
- G: uint8((argb & 0x0000ff00) >> 8),
- R: uint8((argb & 0x00ff0000) >> 16),
- A: uint8((argb & 0xff000000) >> 24) }
-}
-
-func (b *bar) rect() image.Rectangle {
- return image.Rect( 0, 0,
- int(b.Mon.Rectangle.Width), int(conf.H))
-}
-
-func (b *bar) drawReInit() {
- if b.i != nil {
- b.i.Destroy()
- }
-
- b.i = xgraphics.New(b.Xu, b.rect())
-}
-
-func (b *bar) drawText(x int, col uint32, text string) (int, error) {
- nx, _, err := b.i.Text(x, conf.FontYPad,
- int2BGRA(col), conf.FontSize, font, text)
- return nx - x, err
-}
-
-func (b *bar) textWidth(str string) int {
- return len(str) * b.tw
-}
-
-func pointInRect(px, py, x, y, w, h int) bool {
- if px >= x && px <= x + w && py >= x && py <= y + h {
- return true
- } else {
- return false
- }
-}
-
-func (b *bar) drawRect(x, y, w, h int, c uint32, fill bool) {
- col := int2BGRA(c)
-
- var ix, iy int
-
- for ix = x; ix < x + w; ix++ {
- for iy = y; iy < y + h; iy++ {
- if fill || ix == x || ix == x + w - 1 ||
- iy == y || iy == y + h - 1 {
- b.i.Set(ix, iy, col)
- }
- }
- }
-}
diff --git a/main.go b/main.go
@@ -7,8 +7,9 @@ import (
"os/signal"
"hhvn.uk/hbspbar/common"
- "hhvn.uk/hbspbar/bspc"
+ "hhvn.uk/hbspbar/x"
"hhvn.uk/hbspbar/bar"
+ "hhvn.uk/hbspbar/bspc"
)
func main() {
@@ -18,11 +19,12 @@ func main() {
syscall.SIGHUP,
syscall.SIGTERM)
- if bar.InitErr != nil {
- common.Error("Couldn't initialize X: %s\n", bar.InitErr)
+ defer bar.Cleanup()
+
+ if x.InitErr != nil {
+ common.Error("Couldn't initialize X: %s\n", x.InitErr)
return
}
- defer bar.Cleanup()
if bspc.InitErr != nil {
common.Error("Couldn't subscribe to bspwm: %s\n", bspc.InitErr)
diff --git a/x/x.go b/x/x.go
@@ -0,0 +1,100 @@
+package x // import "hhvn.uk/hbspbar/x"
+
+import (
+ "os"
+ "image"
+
+ "hhvn.uk/hbspbar/config"
+ "hhvn.uk/hbspbar/common"
+
+ "github.com/jezek/xgb"
+ "github.com/jezek/xgb/xproto"
+ "github.com/jezek/xgbutil"
+ "github.com/jezek/xgbutil/xgraphics"
+ "github.com/BurntSushi/freetype-go/freetype/truetype"
+)
+
+var InitErr error
+var X *xgb.Conn
+var XU *xgbutil.XUtil
+var Screen *xproto.ScreenInfo
+
+var font *truetype.Font
+var tw, th int
+var tbpad int
+
+func init() {
+ var err error
+
+ X, err = xgb.NewConn()
+ if err != nil {
+ InitErr = err
+ return
+ }
+
+ XU, err = xgbutil.NewConnXgb(X)
+ if err != nil {
+ InitErr = err
+ return
+ }
+
+ setup := xproto.Setup(X)
+ Screen = setup.DefaultScreen(X)
+
+ read, err := os.Open(config.Font)
+ if err != nil {
+ InitErr = common.Perror("os.Open", err)
+ return
+ }
+
+ font, err = xgraphics.ParseFont(read)
+ if err != nil {
+ InitErr = common.Perror("xgraphics.ParseFont", err)
+ return
+ }
+
+ test := xgraphics.New(XU, image.Rect(0, 0, int(config.FontSize * 10), int(config.FontSize * 10)))
+ tw, th, _ = test.Text(0, 0, int2BGRA(config.Fg), config.FontSize, font, "X")
+ tbpad = (int(config.H) - th) / 2
+}
+
+func int2BGRA(argb uint32) (xgraphics.BGRA) {
+ return xgraphics.BGRA{
+ B: uint8( argb & 0x000000ff),
+ G: uint8((argb & 0x0000ff00) >> 8),
+ R: uint8((argb & 0x00ff0000) >> 16),
+ A: uint8((argb & 0xff000000) >> 24) }
+}
+
+func GraphicReInit(i **xgraphics.Image, r image.Rectangle) {
+ if *i != nil {
+ (*i).Destroy()
+ }
+
+ *i = xgraphics.New(XU, r)
+}
+
+func DrawText(i *xgraphics.Image, x int, col uint32, text string) (int, error) {
+ nx, _, err := i.Text(x, config.FontYPad,
+ int2BGRA(col), config.FontSize, font, text)
+ return nx - x, err
+}
+
+func TextWidth(text string) (int) {
+ return tw * len(text)
+}
+
+func DrawRect(i *xgraphics.Image, x, y, w, h int, c uint32, fill bool) {
+ col := int2BGRA(c)
+
+ var ix, iy int
+
+ for ix = x; ix < x + w; ix++ {
+ for iy = y; iy < y + h; iy++ {
+ if fill || ix == x || ix == x + w - 1 ||
+ iy == y || iy == y + h - 1 {
+ i.Set(ix, iy, col)
+ }
+ }
+ }
+}