Get rid of dirty sleep hack

This commit is contained in:
Camille Scholtz 2018-12-26 21:24:04 +01:00
parent e4b37decfa
commit e9c66c7bba
6 changed files with 67 additions and 45 deletions

@ -56,8 +56,6 @@ example `block.bg = "#FF0000"` or `block.txt = "Hello World!"` and executing
## TODO
* Create some kind of easy to use init function for blocks (instead of
the `if !init` stuff I use at the moment).
* Add popups.

23
bar.go

@ -42,6 +42,10 @@ type Bar struct {
// A channel where the block should be send to to once its ready to be
// redrawn.
redraw chan *Block
// A channel where a boolean should be send once a block has initizalized,
// notifying that the next block can intialize.
ready chan bool
}
func initBar(x, y, w, h int, fp string) (*Bar, error) {
@ -202,3 +206,22 @@ func (bar *Bar) draw(block *Block) error {
return nil
}
func (bar *Bar) initBlocks(blocks []func()) {
bar.ready = make(chan bool)
for _, f := range blocks {
go f()
<-bar.ready
}
close(bar.ready)
}
func (bar *Bar) listen() {
for {
if err := bar.draw(<-bar.redraw); err != nil {
panic(err)
}
}
}

@ -63,6 +63,9 @@ func (bar *Bar) initBlock(name, txt string, w int, align rune, xoff int, bg,
// Store the block in map.
bar.block.Store(name, block)
// Draw block.
bar.redraw <- block
return block
}
@ -72,7 +75,6 @@ func (block *Block) diff(txt string) bool {
if block.txt == txt {
return false
}
block.txt = txt
return true
}

@ -20,7 +20,9 @@ import (
func (bar *Bar) clockFun() {
// Initialize block.
block := bar.initBlock("clock", "?", 800, 'a', 0, "#445967", "#CCCCCC")
bar.redraw <- block
// Notify that the next block can be initialized.
bar.ready <- true
for {
// Compose block text.
@ -39,7 +41,9 @@ func (bar *Bar) clockFun() {
func (bar *Bar) musicFun() {
// Initialize block.
block := bar.initBlock("music", "» ", 660, 'r', -12, "#3C4F5B", "#CCCCCC")
bar.redraw <- block
// Notify that the next block can be initialized.
bar.ready <- true
// Connect to MPD.
c, err := mpd.Dial("tcp", ":6600")
@ -62,20 +66,20 @@ func (bar *Bar) musicFun() {
}()
// Show popup on clicking the left mouse button.
/*block.actions["button1"] = func() {
block.actions["button1"] = func() {
if block.popup == nil {
var err error
block.popup, err = bar.initPopup(1920-304-29, 29, 304, 148,
"#3C4F5B", "#CCCCCC")
if err != nil {
log.Print(err)
panic(err)
}
//popup.draw()
} else {
block.popup = block.popup.destroy()
}
}*/
}
// Toggle play/pause on clicking the right mouse button.
block.actions["button3"] = func() {
@ -138,7 +142,9 @@ func (bar *Bar) musicFun() {
func (bar *Bar) todoFun() {
// Initialize block.
block := bar.initBlock("todo", "¢", 29, 'c', 0, "#5394C9", "#FFFFFF")
bar.redraw <- block
// Notify that the next block can be initialized.
bar.ready <- true
// Find `.todo` file.
hd, err := homedir.Dir()
@ -192,10 +198,11 @@ func (bar *Bar) todoFun() {
func (bar *Bar) windowFun() {
// Initialize blocks.
blockIcon := bar.initBlock("window", "º", 21, 'l', 12, "#37BF8D", "#FFFFFF")
bar.initBlock("window", "º", 21, 'l', 12, "#37BF8D", "#FFFFFF")
block := bar.initBlock("window", "?", 200, 'c', 0, "#37BF8D", "#FFFFFF")
bar.redraw <- blockIcon
bar.redraw <- block
// Notify that the next block can be initialized.
bar.ready <- true
// TODO: This doesn't check for window title changes.
xevent.PropertyNotifyFun(func(_ *xgbutil.XUtil, ev xevent.
@ -245,9 +252,9 @@ func (bar *Bar) workspaceFun() {
"#FFFFFF")
blockSRC := bar.initBlock("src", "¾ src", 70, 'l', 10, "#5394C9",
"#FFFFFF")
bar.redraw <- blockWWW
bar.redraw <- blockIRC
bar.redraw <- blockSRC
// Notify that the next block can be initialized.
bar.ready <- true
// Change active workspace on clicking on one of the blocks.
blockWWW.actions["button1"] = func() {

25
main.go

@ -2,7 +2,6 @@ package main
import (
"path"
"time"
homedir "github.com/mitchellh/go-homedir"
)
@ -19,20 +18,14 @@ func main() {
}
// Run bar block functions.
runBlock(bar.windowFun)
runBlock(bar.workspaceFun)
runBlock(bar.clockFun)
runBlock(bar.musicFun)
runBlock(bar.todoFun)
go bar.initBlocks([]func(){
bar.windowFun,
bar.workspaceFun,
bar.clockFun,
bar.musicFun,
bar.todoFun,
})
for {
if err := bar.draw(<-bar.redraw); err != nil {
panic(err)
}
}
}
func runBlock(f func()) {
go f()
time.Sleep(time.Millisecond * 10)
// Listen for redraw events.
bar.listen()
}

@ -26,24 +26,23 @@ type Popup struct {
redraw chan *Popup
}
func (bar *Bar) initPopup(x, y, w, h int, bg, fg string) (*Popup,
error) {
func (bar *Bar) initPopup(x, y, w, h int, bg, fg string) (*Popup, error) {
popup := new(Popup)
var err error
// Create a window for the bar. This window listens to button
// press events in order to respond to them.
// Create a window for the bar. This window listens to button press events
// in order to respond to them.
popup.win, err = xwindow.Generate(bar.xu)
if err != nil {
return nil, err
}
popup.win.Create(bar.xu.RootWin(), x, y, w, h, xproto.CwBackPixel|
xproto.CwEventMask, 0x000000, xproto.EventMaskButtonPress)
popup.win.Create(bar.xu.RootWin(), x, y, w, h, xproto.CwBackPixel|xproto.
CwEventMask, 0x000000, xproto.EventMaskButtonPress)
// EWMH stuff.
// TODO: `WmStateSet` and `WmDesktopSet` are basically here to
// keep OpenBox happy, can I somehow remove them and just use
// `_NET_WM_WINDOW_TYPE_DOCK` like I can with WindowChef?
// TODO: `WmStateSet` and `WmDesktopSet` are basically here to keep OpenBox
// happy, can I somehow remove them and just use `_NET_WM_WINDOW_TYPE_DOCK`
// like I can with WindowChef?
if err := ewmh.WmWindowTypeSet(bar.xu, popup.win.Id, []string{
"_NET_WM_WINDOW_TYPE_DOCK"}); err != nil {
return nil, err
@ -52,12 +51,10 @@ func (bar *Bar) initPopup(x, y, w, h int, bg, fg string) (*Popup,
"_NET_WM_STATE_STICKY"}); err != nil {
return nil, err
}
if err := ewmh.WmDesktopSet(bar.xu, popup.win.Id, ^uint(
0)); err != nil {
if err := ewmh.WmDesktopSet(bar.xu, popup.win.Id, ^uint(0)); err != nil {
return nil, err
}
if err := ewmh.WmNameSet(bar.xu, popup.win.Id, "melonbar"); err !=
nil {
if err := ewmh.WmNameSet(bar.xu, popup.win.Id, "melonbar"); err != nil {
return nil, err
}
@ -69,7 +66,9 @@ func (bar *Bar) initPopup(x, y, w, h int, bg, fg string) (*Popup,
// Create the bar image.
popup.img = xgraphics.New(bar.xu, image.Rect(0, 0, w, h))
popup.img.XSurfaceSet(popup.win.Id)
if err := popup.img.XSurfaceSet(popup.win.Id); err != nil {
panic(err)
}
popup.img.XDraw()
popup.w = w