package shortcutui /* #cgo pkg-config: gtk+-3.0 #include int shortcut_ui_open(const char *title, const char **groups, const char **labels, const char **keys, int count); */ import "C" import ( "encoding/json" "errors" "io" "runtime" "unsafe" ) type Row struct { Group string `json:"group"` Label string `json:"label"` Keys string `json:"keys"` } type List struct { Title string `json:"title"` Rows []Row `json:"rows"` } // Run displays one read-only, keyboard accessible shortcut list in a child process. func Run(reader io.Reader) error { var list List if err := json.NewDecoder(io.LimitReader(reader, 1<<20)).Decode(&list); err != nil { return err } if len(list.Rows) == 0 || len(list.Rows) > 512 { return errors.New("invalid shortcut list") } runtime.LockOSThread() defer runtime.UnlockOSThread() title := C.CString(list.Title) defer C.free(unsafe.Pointer(title)) groups := make([]*C.char, len(list.Rows)) labels := make([]*C.char, len(list.Rows)) keys := make([]*C.char, len(list.Rows)) for i, row := range list.Rows { groups[i], labels[i], keys[i] = C.CString(row.Group), C.CString(row.Label), C.CString(row.Keys) defer C.free(unsafe.Pointer(groups[i])) defer C.free(unsafe.Pointer(labels[i])) defer C.free(unsafe.Pointer(keys[i])) } if C.shortcut_ui_open(title, (**C.char)(unsafe.Pointer(&groups[0])), (**C.char)(unsafe.Pointer(&labels[0])), (**C.char)(unsafe.Pointer(&keys[0])), C.int(len(list.Rows))) == 0 { return errors.New("could not open shortcut list window") } return nil }