5bar5/blocks.go

413 lines
8.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"log"
"os"
"os/exec"
"os/user"
"path"
"time"
"github.com/BurntSushi/xgb/xproto"
"github.com/BurntSushi/xgbutil"
"github.com/BurntSushi/xgbutil/ewmh"
"github.com/BurntSushi/xgbutil/icccm"
"github.com/BurntSushi/xgbutil/xevent"
"github.com/BurntSushi/xgbutil/xgraphics"
"github.com/BurntSushi/xgbutil/xprop"
"github.com/BurntSushi/xgbutil/xwindow"
// "github.com/fhs/gompd/mpd"
)
func (bar *Bar) initBlocks() {
bar.blocks.Set("window", &Block{
txt: "?",
w: activeWinSize,
align: 'c',
xoff: 0,
bg: xgraphics.BGRA{B: 65, G: 0, R: 0, A: 0xFF},
fg: xgraphics.BGRA{B: 255, G: 255, R: 255, A: 0xFF},
update: func() {
block := bar.block("window")
// Redraw block function.
t := func(id xproto.Window) {
// Set new block text.
txt, err := ewmh.WmNameGet(X, id)
if err != nil || len(txt) == 0 {
txt, err = icccm.WmNameGet(X, id)
if err != nil || len(txt) == 0 {
txt = "?"
}
}
txt = trim(txt, 34)
// Return if the text is the same.
if txt == block.txt {
return
}
block.txt = txt
// Redraw block.
bar.redraw <- block
}
// Variable where we store the (previous) xwindow.
var xid *xwindow.Window
// Get window ID function.
f := func() {
// Get active window.
id, err := ewmh.ActiveWindowGet(X)
if err != nil {
log.Println(err)
return
}
if id == 0 {
return
}
// Stop listening to the previous window.
if xid != nil {
xid.Detach()
}
// Create xwindow from active window.
xid = xwindow.New(X, id)
// Listen to this window for window name changes.
xid.Listen(xproto.EventMaskPropertyChange)
xevent.PropertyNotifyFun(func(_ *xgbutil.XUtil, ev xevent.
PropertyNotifyEvent) {
// Only listen to `_NET_WM_NAME` events.
atom, err := xprop.Atm(X, "_NET_WM_NAME")
if err != nil {
log.Println(err)
return
}
if ev.Atom != atom {
return
}
t(id)
}).Connect(X, id)
t(id)
}
// Listen for window change event, execute `f()` accordingly.
xevent.PropertyNotifyFun(func(_ *xgbutil.XUtil, ev xevent.
PropertyNotifyEvent) {
// Only listen to `_NET_ACTIVE_WINDOW` events.
//atom, err := xprop.Atm(X, "_NET_ACTIVE_WINDOW")
//if err != nil {
// log.Println(err)
// return
//}
//if ev.Atom != atom {
// return
//}
f()
}).Connect(X, X.RootWin())
// Execute `f()` one time initially.
f()
},
})
bar.blocks.Set("workspace-1", &Block{
txt: "1",
w: workspaceWidth,
align: 'l',
xoff: 12,
bg: xgraphics.BGRA{B: 0, G: 0, R: 0, A: 0xFF},
fg: xgraphics.BGRA{B: 255, G: 255, R: 255, A: 0xFF},
update: func() {},
actions: map[xproto.Button]func() error{
1: func() error {
return ewmh.CurrentDesktopReq(X, 0)
},
4: func() error {
return ewmh.CurrentDesktopReq(X, bar.store["prev"].(int))
},
5: func() error {
return ewmh.CurrentDesktopReq(X, bar.store["next"].(int))
},
},
})
bar.blocks.Set("workspace-2", &Block{
txt: "2",
w: workspaceWidth,
align: 'l',
xoff: 12,
bg: xgraphics.BGRA{B: 0, G: 0, R: 0, A: 0xFF},
fg: xgraphics.BGRA{B: 255, G: 255, R: 255, A: 0xFF},
update: func() {},
actions: map[xproto.Button]func() error{
1: func() error {
return ewmh.CurrentDesktopReq(X, 1)
},
4: func() error {
return ewmh.CurrentDesktopReq(X, bar.store["prev"].(int))
},
5: func() error {
return ewmh.CurrentDesktopReq(X, bar.store["next"].(int))
},
},
})
bar.blocks.Set("workspace-3", &Block{
txt: "3",
w: workspaceWidth,
align: 'l',
xoff: 12,
bg: xgraphics.BGRA{B: 0, G: 0, R: 0, A: 0xFF},
fg: xgraphics.BGRA{B: 255, G: 255, R: 255, A: 0xFF},
update: func() {},
actions: map[xproto.Button]func() error{
1: func() error {
return ewmh.CurrentDesktopReq(X, 2)
},
4: func() error {
return ewmh.CurrentDesktopReq(X, bar.store["prev"].(int))
},
5: func() error {
return ewmh.CurrentDesktopReq(X, bar.store["next"].(int))
},
},
})
bar.blocks.Set("workspace", &Block{
script: true,
update: func() {
one := bar.block("workspace-1")
two := bar.block("workspace-2")
three := bar.block("workspace-3")
f := func() {
// Get the current active desktop.
wsp, err := ewmh.CurrentDesktopGet(X)
if err != nil {
log.Println(err)
return
}
// KAYOS FIX THIS MAKE IT A CONFIG
var chosenbg xgraphics.BGRA = xgraphics.BGRA{B: 255, G: 255, R: 255, A: 0xFF}
var chosenfg xgraphics.BGRA = xgraphics.BGRA{B: 0, G: 0, R: 0, A: 0xFF}
// Set new block colors and the previous/next workspaces.
switch wsp {
case 0:
one.bg = chosenbg
one.fg = chosenfg
two.bg = xgraphics.BGRA{B: 0, G: 0, R: 0, A: 0xFF}
three.bg = xgraphics.BGRA{B: 0, G: 0, R: 0, A: 0xFF}
bar.store["prev"] = 2
bar.store["next"] = 1
case 1:
one.bg = xgraphics.BGRA{B: 0, G: 0, R: 0, A: 0xFF}
two.bg = chosenbg
two.fg = chosenfg
three.bg = xgraphics.BGRA{B: 0, G: 0, R: 0, A: 0xFF}
bar.store["prev"] = 0
bar.store["next"] = 2
case 2:
one.bg = xgraphics.BGRA{B: 0, G: 0, R: 0, A: 0xFF}
two.bg = xgraphics.BGRA{B: 0, G: 0, R: 0, A: 0xFF}
three.bg =chosenbg
three.fg =chosenfg
bar.store["prev"] = 1
bar.store["next"] = 0
}
// Redraw block.
bar.redraw <- one
bar.redraw <- two
bar.redraw <- three
}
// Listen for workspace change event, execute `f()` accordingly.
xevent.PropertyNotifyFun(func(_ *xgbutil.XUtil, ev xevent.
PropertyNotifyEvent) {
// Only listen to `_NET_ACTIVE_WINDOW` events.
atom, err := xprop.Atm(X, "_NET_CURRENT_DESKTOP")
if err != nil {
log.Println(err)
return
}
if ev.Atom != atom {
return
}
f()
}).Connect(X, X.RootWin())
// Execute `f()` one time initially.
f()
},
})
bar.blocks.Set("clock", &Block{
txt: "?",
w: 799,
align: 'a',
xoff: 0,
bg: xgraphics.BGRA{B: 0, G: 0, R: 0, A: 0xFF},
fg: xgraphics.BGRA{B: 255, G: 247, R: 91, A: 0xFF},
update: func() {
for {
block := bar.block("clock")
// Set new block text.
block.txt = time.Now().Format("Monday, January 2th 03:04 PM")
// Redraw block.
bar.redraw <- block
// Update every 45 seconds.
time.Sleep(45 * time.Second)
}
},
/* actions: map[xproto.Button]func() error{
1: func() error {
return bar.drawPopup("clock")
},
},*/
})
/* bar.blocks.Set("music", &Block{
txt: " Ƅ ",
w: 660,
align: 'r',
xoff: -12,
bg: xgraphics.BGRA{B: 91, G: 79, R: 60, A: 0xFF},
fg: xgraphics.BGRA{B: 204, G: 204, R: 204, A: 0xFF},
update: func() {
block := bar.block("music")
popup := bar.popup("music")
// Connect to MPD.
var err error
bar.store["mpd"], err = mpd.Dial("tcp", ":6600")
if err != nil {
log.Fatalln(err)
}
// Keep connection alive by pinging ever 45 seconds.
go func() {
for {
time.Sleep(time.Second * 45)
if err := bar.store["mpd"].(*mpd.Client).
Ping(); err != nil {
bar.store["mpd"], err = mpd.Dial("tcp", ":6600")
if err != nil {
log.Fatalln(err)
}
}
}
}()
// Watch MPD for events.
w, err := mpd.NewWatcher("tcp", ":6600", "", "player")
if err != nil {
log.Fatalln(err)
}
for {
cur, err := bar.store["mpd"].(*mpd.Client).CurrentSong()
if err != nil {
log.Println(err)
return
}
sts, err := bar.store["mpd"].(*mpd.Client).Status()
if err != nil {
log.Println(err)
return
}
// Set new block text.
var s string
if sts["state"] == "pause" {
s = "[paused] "
}
block.txt = " Ƅ " + s + cur["Artist"] + " - " + cur["Title"]
// Redraw block.
bar.redraw <- block
// Update popup if open.
if popup.open {
popup.update()
}
// Wait for next event.
<-w.Event
}
},*/
/* actions: map[xproto.Button]func() error{
1: func() error {
return bar.drawPopup("music")
},
3: func() error {
s, err := bar.store["mpd"].(*mpd.Client).Status()
if err != nil {
return err
}
return bar.store["mpd"].(*mpd.Client).
Pause(s["state"] != "pause")
},
4: func() error {
return bar.store["mpd"].(*mpd.Client).Previous()
},
5: func() error {
return bar.store["mpd"].(*mpd.Client).Next()
},
},
})*/
bar.blocks.Set("todo", &Block{
txt: "ƅ",
w: bar.h,
align: 'c',
xoff: 1,
bg: xgraphics.BGRA{B: 0, G: 0, R: 0, A: 0xFF},
fg: xgraphics.BGRA{B: 255, G: 255, R: 255, A: 0xFF},
update: func() {},
actions: map[xproto.Button]func() error{
1: func() error {
u, err := user.Current()
if err != nil {
return err
}
cmd := exec.Command("st", "nano", "-savecursor", "false", path.
Join(u.HomeDir, ".todo"))
cmd.Stdout = os.Stdout
return cmd.Start()
},
},
})
}