Make openbox compatible
This commit is contained in:
parent
0e0e4f0f55
commit
2bfbc2bc4a
@ -25,8 +25,8 @@ On top of each block function you should run `bar.initBlock()`, this
|
|||||||
is where most of the configuration happens. Here is a short
|
is where most of the configuration happens. Here is a short
|
||||||
explanation of each parameter from left to right:
|
explanation of each parameter from left to right:
|
||||||
|
|
||||||
* The name of the block, this is and gets used as the name
|
* The name of the block, this is gets used as the name of the block
|
||||||
of the block map key. (`string`)
|
map key. (`string`)
|
||||||
* The initial string the block should display. (`string`)
|
* The initial string the block should display. (`string`)
|
||||||
* The width of the block. (`int`)
|
* The width of the block. (`int`)
|
||||||
* The aligment of the text, this can be `'l'` for left aligment, `'c'`
|
* The aligment of the text, this can be `'l'` for left aligment, `'c'`
|
||||||
|
54
bar.go
54
bar.go
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
@ -10,6 +11,7 @@ import (
|
|||||||
"github.com/BurntSushi/xgb/xproto"
|
"github.com/BurntSushi/xgb/xproto"
|
||||||
"github.com/BurntSushi/xgbutil"
|
"github.com/BurntSushi/xgbutil"
|
||||||
"github.com/BurntSushi/xgbutil/ewmh"
|
"github.com/BurntSushi/xgbutil/ewmh"
|
||||||
|
"github.com/BurntSushi/xgbutil/xevent"
|
||||||
"github.com/BurntSushi/xgbutil/xgraphics"
|
"github.com/BurntSushi/xgbutil/xgraphics"
|
||||||
"github.com/BurntSushi/xgbutil/xwindow"
|
"github.com/BurntSushi/xgbutil/xwindow"
|
||||||
)
|
)
|
||||||
@ -72,27 +74,46 @@ func initBar(x, y, w, h int, font string, fontSize float64) (*Bar,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
go xevent.Main(bar.xu)
|
||||||
|
|
||||||
// Listen to the root window for events.
|
// Listen to the root window for property change event, used to
|
||||||
xwindow.New(bar.xu, bar.xu.RootWin()).Listen(
|
// check if the user changed the focused window or active
|
||||||
xproto.EventMaskPropertyChange)
|
// workspace.
|
||||||
|
if err := xwindow.New(bar.xu, bar.xu.RootWin()).Listen(
|
||||||
|
xproto.EventMaskPropertyChange); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// Create a window.
|
// Create a window.
|
||||||
bar.win, err = xwindow.Generate(bar.xu)
|
bar.win, err = xwindow.Generate(bar.xu)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
bar.win.Create(bar.xu.RootWin(), x, y, w, h, xproto.CwBackPixel,
|
bar.win.Create(bar.xu.RootWin(), x, y, w, h, xproto.CwBackPixel|
|
||||||
0x000000)
|
xproto.CwEventMask, 0x000000, xproto.EventMaskPropertyChange)
|
||||||
|
|
||||||
|
// TODO: `WmStateSet` and `WmDesktopSet` are basically here to
|
||||||
|
// keep OpenBox happy, can I somehow remove them and just use
|
||||||
|
// `_NET_WM_WINDOW_TYPE_DOCK`?
|
||||||
// EWMH stuff.
|
// EWMH stuff.
|
||||||
if err := ewmh.WmWindowTypeSet(bar.xu, bar.win.Id, []string{
|
if err := ewmh.WmWindowTypeSet(bar.xu, bar.win.Id, []string{
|
||||||
"_NET_WM_WINDOW_TYPE_DOCK"}); err != nil {
|
"_NET_WM_WINDOW_TYPE_DOCK"}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err := ewmh.WmStateSet(bar.xu, bar.win.Id, []string{
|
||||||
|
"_NET_WM_STATE_STICKY"}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := ewmh.WmDesktopSet(bar.xu, bar.win.Id, ^uint(0)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := ewmh.WmNameSet(bar.xu, bar.win.Id, "melonbar"); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// Map window.
|
// Map window.
|
||||||
bar.win.Map()
|
bar.win.Map()
|
||||||
|
bar.win.Move(x, y)
|
||||||
|
|
||||||
// Create bar image.
|
// Create bar image.
|
||||||
bar.img = xgraphics.New(bar.xu, image.Rect(0, 0, w, h))
|
bar.img = xgraphics.New(bar.xu, image.Rect(0, 0, w, h))
|
||||||
@ -178,14 +199,9 @@ func (bar *Bar) draw(name string) error {
|
|||||||
i, _ := bar.block.Load(name)
|
i, _ := bar.block.Load(name)
|
||||||
block := i.(*Block)
|
block := i.(*Block)
|
||||||
|
|
||||||
// Color the backround.
|
|
||||||
tw, _ := xgraphics.Extents(bar.font, bar.fontSize, block.txt)
|
|
||||||
block.img.For(func(x, y int) xgraphics.BGRA {
|
|
||||||
return block.bg
|
|
||||||
})
|
|
||||||
|
|
||||||
// Calculate the required x coordinate for the different
|
// Calculate the required x coordinate for the different
|
||||||
// aligments.
|
// aligments.
|
||||||
|
tw, _ := xgraphics.Extents(bar.font, bar.fontSize, block.txt)
|
||||||
var x int
|
var x int
|
||||||
switch block.align {
|
switch block.align {
|
||||||
case 'l':
|
case 'l':
|
||||||
@ -194,8 +210,24 @@ func (bar *Bar) draw(name string) error {
|
|||||||
x = block.x + ((block.w / 2) - (tw / 2)) + block.xoff
|
x = block.x + ((block.w / 2) - (tw / 2)) + block.xoff
|
||||||
case 'r':
|
case 'r':
|
||||||
x = (block.x + block.w) - tw + block.xoff
|
x = (block.x + block.w) - tw + block.xoff
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("draw %#U: Not a valid aligment rune",
|
||||||
|
block.align)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Color the backround.
|
||||||
|
block.img.For(func(cx, cy int) xgraphics.BGRA {
|
||||||
|
// Hack for music block background.
|
||||||
|
if name == "music" {
|
||||||
|
if cx < x+block.xoff {
|
||||||
|
return hexToBGRA("#445967")
|
||||||
|
}
|
||||||
|
return block.bg
|
||||||
|
}
|
||||||
|
|
||||||
|
return block.bg
|
||||||
|
})
|
||||||
|
|
||||||
// TODO: Center vertically automatically.
|
// TODO: Center vertically automatically.
|
||||||
// Draw the text.
|
// Draw the text.
|
||||||
if _, _, err := block.img.Text(x, 6, block.fg, bar.fontSize,
|
if _, _, err := block.img.Text(x, 6, block.fg, bar.fontSize,
|
||||||
|
76
blocks.go
76
blocks.go
@ -7,8 +7,10 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/BurntSushi/xgb/xproto"
|
"github.com/BurntSushi/xgbutil"
|
||||||
"github.com/BurntSushi/xgbutil/ewmh"
|
"github.com/BurntSushi/xgbutil/ewmh"
|
||||||
|
"github.com/BurntSushi/xgbutil/icccm"
|
||||||
|
"github.com/BurntSushi/xgbutil/xevent"
|
||||||
"github.com/BurntSushi/xgbutil/xprop"
|
"github.com/BurntSushi/xgbutil/xprop"
|
||||||
owm "github.com/briandowns/openweathermap"
|
owm "github.com/briandowns/openweathermap"
|
||||||
"github.com/fhs/gompd/mpd"
|
"github.com/fhs/gompd/mpd"
|
||||||
@ -170,39 +172,33 @@ func (bar *Bar) weatherFun() {
|
|||||||
func (bar *Bar) windowFun() {
|
func (bar *Bar) windowFun() {
|
||||||
bar.initBlock("window", "?", 220, 'c', 0, "#37BF8D", "#FFFFFF")
|
bar.initBlock("window", "?", 220, 'c', 0, "#37BF8D", "#FFFFFF")
|
||||||
|
|
||||||
init := true
|
// TODO: I'm not sure how I can use init here?
|
||||||
for {
|
xevent.PropertyNotifyFun(func(xu *xgbutil.XUtil,
|
||||||
if !init {
|
ev xevent.PropertyNotifyEvent) {
|
||||||
ev, xgbErr := bar.xu.Conn().WaitForEvent()
|
atom, err := xprop.Atm(bar.xu, "_NET_ACTIVE_WINDOW")
|
||||||
if xgbErr != nil {
|
if ev.Atom != atom {
|
||||||
log.Print(xgbErr)
|
return
|
||||||
continue
|
}
|
||||||
}
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
atom, err := xprop.Atm(bar.xu, "_NET_ACTIVE_WINDOW")
|
return
|
||||||
if ev.(xproto.PropertyNotifyEvent).Atom != atom {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
log.Print(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
init = false
|
|
||||||
|
|
||||||
id, err := ewmh.ActiveWindowGet(bar.xu)
|
id, err := ewmh.ActiveWindowGet(bar.xu)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
win, err := ewmh.WmNameGet(bar.xu, id)
|
win, err := ewmh.WmNameGet(bar.xu, id)
|
||||||
if err != nil {
|
if err != nil || len(win) == 0 {
|
||||||
log.Print(err)
|
win, err = icccm.WmNameGet(bar.xu, id)
|
||||||
continue
|
if err != nil || len(win) == 0 {
|
||||||
|
win = "?"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bar.updateBlockTxt("window", win)
|
bar.updateBlockTxt("window", win)
|
||||||
}
|
}).Connect(bar.xu, bar.xu.RootWin())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bar *Bar) workspaceFun() {
|
func (bar *Bar) workspaceFun() {
|
||||||
@ -210,30 +206,22 @@ func (bar *Bar) workspaceFun() {
|
|||||||
bar.initBlock("irc", "irc", 67, 'c', 0, "#5394C9", "#FFFFFF")
|
bar.initBlock("irc", "irc", 67, 'c', 0, "#5394C9", "#FFFFFF")
|
||||||
bar.initBlock("src", "src", 70, 'c', 0, "#5394C9", "#FFFFFF")
|
bar.initBlock("src", "src", 70, 'c', 0, "#5394C9", "#FFFFFF")
|
||||||
|
|
||||||
init := true
|
// TODO: I'm not sure how I can use init here?
|
||||||
for {
|
xevent.PropertyNotifyFun(func(xu *xgbutil.XUtil,
|
||||||
if !init {
|
ev xevent.PropertyNotifyEvent) {
|
||||||
ev, xgbErr := bar.xu.Conn().WaitForEvent()
|
atom, err := xprop.Atm(bar.xu, "_NET_CURRENT_DESKTOP")
|
||||||
if xgbErr != nil {
|
if ev.Atom != atom {
|
||||||
log.Print(xgbErr)
|
return
|
||||||
continue
|
}
|
||||||
}
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
atom, err := xprop.Atm(bar.xu, "WINDOWCHEF_ACTIVE_GROUPS")
|
return
|
||||||
if ev.(xproto.PropertyNotifyEvent).Atom != atom {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
log.Print(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
init = false
|
|
||||||
|
|
||||||
wsp, err := ewmh.CurrentDesktopGet(bar.xu)
|
wsp, err := ewmh.CurrentDesktopGet(bar.xu)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
switch wsp {
|
switch wsp {
|
||||||
@ -250,5 +238,5 @@ func (bar *Bar) workspaceFun() {
|
|||||||
bar.updateBlockBg("irc", "#5394C9")
|
bar.updateBlockBg("irc", "#5394C9")
|
||||||
bar.updateBlockBg("src", "#72A7D3")
|
bar.updateBlockBg("src", "#72A7D3")
|
||||||
}
|
}
|
||||||
}
|
}).Connect(bar.xu, bar.xu.RootWin())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user