func (ct *CommandTray) initPopup() { var err error ct.popup, err = xwindow.Create(ct.X, ct.X.RootWin()) utils.FailMeMaybe(err) ct.pu_img.For(func(x, y int) xgraphics.BGRA { if y%ct.Height == ct.Height-1 || x == 0 || x == ct.Width-1 { return xgraphics.BGRA{128, 128, 128, 255} } return xgraphics.BGRA{64, 64, 64, 255} }) utils.FailMeMaybe(ewmh.WmDesktopSet(ct.X, ct.popup.Id, 0xffffffff)) utils.FailMeMaybe(ewmh.WmWindowTypeSet(ct.X, ct.popup.Id, []string{ "_NET_WM_WINDOW_TYPE_DOCK", })) utils.FailMeMaybe(ct.popup.Listen(xproto.EventMaskKeyPress | xproto.EventMaskStructureNotify)) ct.popup.Resize(ct.Width, ct.Height*10) ct.popup.Move(ct.Position, ct.Height) ct.pu_img.XSurfaceSet(ct.popup.Id) ct.pu_img.XDraw() ct.pu_img.XPaint(ct.popup.Id) }
func (ct *CommandTray) Init() { var err error ct.img = xgraphics.New(ct.X, image.Rect(0, 0, ct.Width, ct.Height)) ct.pu_img = xgraphics.New(ct.X, image.Rect(0, 0, ct.Width, ct.Height*10)) ct.window, err = xwindow.Create(ct.X, ct.Parent.Id) utils.FailMeMaybe(err) utils.FailMeMaybe(ct.img.XSurfaceSet(ct.window.Id)) ct.window.Move(ct.Position, 0) ct.window.Resize(ct.Width, ct.Height) ct.window.Map() }
func loadConfig(fileName string) *Config { dat, err := wini.Parse(fileName) utils.FailMeMaybe(err) cfg := &Config{} // Main thing. loadInt(dat, "Main", "Size", &cfg.BarSize) loadInt(dat, "Main", "Width", &cfg.BarWidth) loadString(dat, "Main", "Position", "", &cfg.Position) // Clock. loadSection(dat, "Clock", true, &cfg.Clock) loadString(dat, "Clock", "Format", "2006-01-02 15:04:05", &cfg.ClockFormat) // Tracker loadSection(dat, "App Tracker", false, &cfg.Tracker) // Command Tray loadSection(dat, "CommandTray", true, &cfg.Command) loadString(dat, "CommandTray", "Accel", "", &cfg.CommandAccel) // Status Bar loadSection(dat, "StatusBar", false, &cfg.StatusBar) return cfg }
func openImage(paths xdg.Paths, fileName string) image.Image { fileName, err := paths.DataFile("images/" + fileName) utils.FailMeMaybe(err) f, err := os.Open(fileName) //"/home/amanda/.local/share/icons/gobar/" + fileName) utils.FailMeMaybe(err) defer f.Close() img, err := png.Decode(f) utils.FailMeMaybe(err) return img }
func (sb *StatusBar) Init() { sb.img = xgraphics.New(sb.X, image.Rect(0, 0, sb.Width, sb.Height)) var err error sb.window, err = xwindow.Create(sb.X, sb.Parent.Id) utils.FailMeMaybe(err) sb.window.Move(sb.Position, 0) sb.window.Resize(sb.Width, sb.Height) sb.window.Map() sb.img.XSurfaceSet(sb.window.Id) utils.FailMeMaybe(sb.initTray()) sb.Draw() }
func NewShellSource(sess *dbus.Connection, x *xdg.XDG) *ShellSource { ss := &ShellSource{ sess_conn: sess, Xdg: x, } for _, dir := range []string{ "/usr/share/gnome-shell/search-providers", "/usr/local/share/gnoem-shell/search-providers", } { srcs, err := ioutil.ReadDir(dir) //utils.FailMeMaybe(err) if err != nil { continue } for _, file := range srcs { cfg, err := conf.ReadConfigFile(dir + "/" + file.Name()) utils.FailMeMaybe(err) SSP := "Shell Search Provider" objPath, err := cfg.GetString(SSP, "ObjectPath") if err != nil { continue } busName, err := cfg.GetString(SSP, "BusName") if err != nil { continue } var name, icon string name, err = cfg.GetString(SSP, "Name") if err != nil { did, err := cfg.GetString(SSP, "DesktopId") if err == nil { name, icon = getName(did) } } if icon == "" { if tmp, err := cfg.GetString(SSP, "Icon"); err == nil { icon = tmp } } searcher := gs_search.New(sess.Object(busName, dbus.ObjectPath(objPath))) searcher.Name = name searcher.Icon = icon ss.searchers = append(ss.searchers, searcher) } } return ss }
// API func (ct *CommandTray) Bind(key string) { if ct.mod != "" { return } ct.mod = key utils.FailMeMaybe(keybind.KeyPressFun(func(_ *xgbutil.XUtil, _ xevent.KeyPressEvent) { ct.Focus() }).Connect(ct.X, ct.X.RootWin(), ct.mod, true)) }
func main() { cfg := Config{} X, err := xgbutil.NewConn() utils.FailMeMaybe(err) heads, err := xinerama.PhysicalHeads(X) utils.FailMeMaybe(err) cfg.Width = heads[0].Width() cfg.ClockPos = (cfg.Width / 2) - 100 cfg.CommandWidth = (cfg.Width / 2) - 124 cfg.StatusPos = (cfg.Width / 2) + 100 // Look for ze fonts! cfg.ClockFont = "Put your font here!" cfg.CommandFont = cfg.ClockFont found := false for _, fontDir := range []string{"/usr/share/fonts/dejavu/", "/usr/share/fonts/TTF/"} { if exists(fontDir+"DejaVuSansMono-Bold.ttf") && exists(fontDir+"DejaVuSansMono.ttf") { cfg.ClockFont = fontDir + "DejaVuSansMono-Bold.ttf" cfg.CommandFont = fontDir + "DejaVuSansMono.ttf" found = true break } } if !found { fmt.Fprintln(os.Stderr, "# We could not locate your fonts directory, please edit the config\n") fmt.Fprintln(os.Stderr, "# Accordingly.\n") } templ.Execute(os.Stdout, cfg) }
func loadFloat(dat *wini.Data, name, key string, target *float64) { k := dat.GetKey(name, key) if k == nil { utils.Fail("Missing key " + key + " in section " + name) } tmp, err := k.Floats() utils.FailMeMaybe(err) if len(tmp) > 0 { *target = tmp[0] } else { utils.Fail("Missing key " + key + " in section " + name) } }
func (c *Clock) Init() { var err error c.img = xgraphics.New(c.X, image.Rect(0, 0, c.Width, c.Height)) c.window, err = xwindow.Create(c.X, c.Parent.Id) utils.FailMeMaybe(err) c.window.Resize(c.Width, c.Height) c.window.Move(c.Position, 0) c.img.XSurfaceSet(c.window.Id) c.window.Map() c.Draw() go c.tickTock() }
func (t *Tracker) Init() { var err error t.img = xgraphics.New(t.X, image.Rect(0, 0, t.Size, t.Size)) t.window, err = xwindow.Create(t.X, t.Parent.Id) utils.FailMeMaybe(err) t.window.Resize(t.Size, t.Size) t.window.Move(t.Position, 0) t.img.XSurfaceSet(t.window.Id) t.window.Map() t.stopMe = true l := startup.Listener{ X: t.X, Callbacks: t, } l.Initialize() t.Draw() }
func (sb *StatusBar) Teardown() { utils.FailMeMaybe(sb.teardownTray()) sb.window.Destroy() sb.img.Destroy() }
func main() { // Signal Handling. sigChan := make(chan os.Signal) signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT) paths := basedir.Paths{ XDGSuffix: "gobar", GoImportPath: "github.com/AmandaCameron/gobar/data", } file, err := paths.ConfigFile("config.wini") utils.FailMeMaybe(err) cfg := loadConfig(file) //os.Getenv("HOME") + "/.config/gobar/config.wini") // Load Images. images.Init(paths) // Setup the X Connection X, err := xgbutil.NewConn() utils.FailMeMaybe(err) win, err := xwindow.Create(X, X.RootWin()) utils.FailMeMaybe(err) win.Resize(cfg.BarWidth, cfg.BarSize) // Setup the EWMH Stuff utils.FailMeMaybe(ewmh.RestackWindow(X, win.Id)) var strut *ewmh.WmStrutPartial if cfg.Position == "Top" { strut = &ewmh.WmStrutPartial{ Top: uint(cfg.BarSize), TopStartX: 0, TopEndX: uint(cfg.BarWidth), } win.Move(0, 0) } else if cfg.Position == "Bottom" { strut = &ewmh.WmStrutPartial{ Bottom: uint(cfg.BarSize), BottomStartX: 0, BottomEndX: uint(cfg.BarWidth), } win.Move(0, 600-cfg.BarSize) } else { println("Invalid Position:", cfg.Position) os.Exit(1) } utils.FailMeMaybe(ewmh.WmStrutPartialSet(X, win.Id, strut)) utils.FailMeMaybe(ewmh.WmWindowTypeSet(X, win.Id, []string{ "_NET_WM_WINDOW_TYPE_DOCK", })) // Put us everywhere. utils.FailMeMaybe(ewmh.WmDesktopSet(X, win.Id, 0xFFFFFFFF)) win.Map() keybind.Initialize(X) // Get the DE settings, if we can. xs, err := xsettings.New(X) if err != nil { // Maybe this should be an error, maybe not? xs = nil } // Draw the background bg := xgraphics.BGRA{ R: 64, G: 64, B: 64, A: 255, } img := xgraphics.New(X, image.Rect(0, 0, cfg.BarWidth, cfg.BarSize)) img.For(func(x, y int) xgraphics.BGRA { return bg }) utils.FailMeMaybe(img.XSurfaceSet(win.Id)) img.XDraw() img.XPaint(win.Id) // Connect to DBus sys, err := dbus.Connect(dbus.SystemBus) utils.FailMeMaybe(err) // The session bus, too. sess, err := dbus.Connect(dbus.SessionBus) utils.FailMeMaybe(err) // Blah x := xdg.New() // TODO: How should this fail? I imagine defaulting to gnome is the wrong thing to do, // but I'm not really sure what it should do. if xs != nil { theme, err := xs.GetString("Net/IconThemeName") if err == nil { x.SetTheme(theme) } } var dev *nm.Device var batt *upower.Device up := upower.New(sys) cli := nm.New(sys) if devs, err := cli.GetDevices(); err == nil { for _, d := range devs { if d.Type() == nm.Wireless { dev = d break } } } if pdevs, err := up.GetDevices(); err == nil { for _, d := range pdevs { if d.Type() == upower.Battery { batt = d break } } } // Clock clck := &Clock{ X: X, Position: cfg.Clock.Position, Width: cfg.Clock.Width, Height: cfg.BarSize, Parent: win, Format: cfg.ClockFormat, Background: xgraphics.BGRA{R: 48, G: 48, B: 48, A: 255}, Foreground: xgraphics.BGRA{R: 255, G: 255, B: 255, A: 255}, Font: utils.OpenFont(cfg.Clock.Font.Name), FontSize: cfg.Clock.Font.Size, } clck.Init() // App Launch Tracker tracker := &Tracker{ X: X, Position: cfg.Tracker.Position, Size: cfg.BarSize, Background: bg, Parent: win, } tracker.Init() // Command Tray ct := &commandtray.CommandTray{ X: X, Width: cfg.Command.Width, Height: cfg.BarSize, Position: cfg.Command.Position, Parent: win, Font: utils.OpenFont(cfg.Command.Font.Name), FontSize: cfg.Command.Font.Size, } commandtray.Register(commandtray.AppSource{ Xdg: x, X: X, AppTracker: tracker, }) if sess != nil { commandtray.Register(commandtray.GnomeSessionSource{ Obj: sess.Object("org.gnome.SessionManager", "/org/gnome/SessionManager"), Xdg: x, }) commandtray.Register(commandtray.NewShellSource(sess, x)) commandtray.Register(&commandtray.AppMenuSource{ Conn: sess, }) } // Done, maybe? ct.Init() ct.Bind(cfg.CommandAccel) ct.Draw() // Status Bar sb := &statbar.StatusBar{ X: X, Width: cfg.StatusBar.Width, Position: cfg.StatusBar.Position, Height: cfg.BarSize, Parent: win, } sb.Init() if batt != nil { sb.Add(&statbar.SbPower{batt}) } if dev != nil { sb.Add(&statbar.SbNmWifi{dev}) commandtray.Register(commandtray.NmSource{dev}) } sb.Draw() // My My this anikin guy... go func() { for { select { case <-sigChan: sb.Teardown() time.Sleep(1 * time.Second) // Anybody else? xevent.Quit(X) } } }() xevent.Main(X) }