Desktop application launcher
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
2.9 KiB

package main
import (
"flag"
"fmt"
"log"
"os"
"path"
"runtime/pprof"
"sync"
"code.rocketnine.space/tslocum/gmenu/pkg/gmenu"
"github.com/gotk3/gotk3/glib"
"github.com/gotk3/gotk3/gtk"
)
// Config stores configuration variables.
type Config struct {
gmenu.Config
Width, Height int
Resizable bool
Fullscreen bool
HideAppIcons bool
CPUProfile string
}
const appID = "space.rocketnine.gmenu"
var (
config = &Config{}
listBox *gtk.ListBox
inputView *gtk.TextView
loaded = make(chan bool)
profileCPU *os.File
container *gtk.Box
once sync.Once
)
func init() {
gmenu.SharedInit(&config.Config)
flag.IntVar(&config.Width, "width", 600, "window width")
flag.IntVar(&config.Height, "height", 200, "window height")
flag.BoolVar(&config.Resizable, "resizable", false, "allow window to be resized")
flag.BoolVar(&config.Fullscreen, "fullscreen", false, "start fullscreen")
flag.BoolVar(&config.HideAppIcons, "no-icons", false, "hide application icons")
flag.StringVar(&config.CPUProfile, "cpuprofile", "", "write cpu profile")
}
func load() {
if config.PrintVersion {
fmt.Printf(gmenu.VersionInfo, "gtkmenu", gmenu.Version)
return
}
homeDir, err := os.UserHomeDir()
if err != nil {
log.Fatalf("failed to determine user home dir: %s", err)
}
iconCacheDir = path.Join(homeDir, ".cache", "gmenu", "icons")
if _, err := os.Stat(iconCacheDir); os.IsNotExist(err) {
os.MkdirAll(iconCacheDir, 0744) // TODO: Warn and disable cache on error
}
gmenu.LoadEntries(&config.Config)
for i, l := range gmenu.Names {
gmenu.FilteredEntries = append(gmenu.FilteredEntries, &gmenu.ListEntry{Label: l, Entry: gmenu.Entries[i]})
}
gmenu.Entries = append(gmenu.Entries, nil)
gmenu.Names = append(gmenu.Names, "")
gmenu.FilteredEntries = append(gmenu.FilteredEntries, &gmenu.ListEntry{Label: "", Entry: nil})
go gmenu.HandleInput(func(input string) {
f := func() {
updateList(input)
}
glib.IdleAddPriority(glib.PRIORITY_HIGH_IDLE, f)
})
loaded <- true
}
func onActivate(application *gtk.Application) {
once.Do(func() {
w := initWindow(application)
container = newBox(gtk.ORIENTATION_VERTICAL)
w.Add(container)
<-loaded
initList(container)
w.ShowAll()
if config.CPUProfile != "" {
pprof.StopCPUProfile()
profileCPU.Close()
return
}
})
}
func main() {
flag.Parse()
if config.CPUProfile != "" {
var err error
profileCPU, err = os.Create(config.CPUProfile)
if err != nil {
log.Fatalf("failed to create cpu profile %s: %s", config.CPUProfile, err)
}
err = pprof.StartCPUProfile(profileCPU)
if err != nil {
log.Fatal("failed to start profiling cpu:", err)
}
}
go load()
application, err := gtk.ApplicationNew(appID, glib.APPLICATION_FLAGS_NONE)
if err != nil {
log.Fatal("failed to create application:", err)
}
application.Connect("activate", func() { onActivate(application) })
os.Exit(application.Run(flag.Args()))
}