asticode/go-astilectron
TopGit theo dõi asticode/go-astilectron trên GitHub trong nhóm Backend, đã đạt 4.9k sao. Build cross platform GUI apps with GO and HTML/JS/CSS (powered by Electron)
Tóm tắt dựng từ metadata GitHub của chính dự án — chưa có bài review TopGit. Trang sẽ tự động cập nhật khi bài review đầy đủ được xuất bản.
TopGit viết bài đầy đủ cho repo có nhiều sao nhất và được yêu cầu nhiều nhất. Trang này là snapshot trong thời gian chờ — xem README gốc ở tab READ ME.
Snapshot
Cộng tác viên hàng đầu
Xem cộng tác viên hàng đầu
Thanks to go-astilectron build cross platform GUI apps with GO and HTML/JS/CSS. It is the official GO bindings of astilectron and is powered by Electron.
Warning
This project is not maintained anymore.
Demo
To see a minimal Astilectron app, checkout out the demo.
It uses the bootstrap and the bundler.
If you're looking for a minimalistic example, run go run example/main.go -v.
Real-life examples
Here's a list of awesome projects using go-astilectron (if you're using go-astilectron and want your project to be listed here please submit a PR):
- go-astivid Video tools written in GO
- GroupMatcher Program to allocate persons to groups while trying to fulfill all the given wishes as good as possible
- Stellite GUI Miner An easy to use GUI cryptocurrency miner for Stellite
Bootstrap
For convenience purposes, a bootstrap has been implemented.
The bootstrap allows you to quickly create a one-window application.
There's no obligation to use it, but it's strongly recommended.
If you decide to use it, read thoroughly the documentation as you'll have to structure your project in a specific way.
Bundler
Still for convenience purposes, a bundler has been implemented.
The bundler allows you to bundle your app for every os/arch combinations and get a nice set of files to send your users.
Quick start
WARNING: the code below doesn't handle errors for readibility purposes. However you SHOULD!
Import go-astilectron
To import go-astilectron run:
$ go get -u github.com/asticode/go-astilectron
Start go-astilectron
// Initialize astilectron
var a, _ = astilectron.New(log.New(os.Stderr, "", 0), astilectron.Options{
AppName: "<your app name>",
AppIconDefaultPath: "<your .png icon>", // If path is relative, it must be relative to the data directory
AppIconDarwinPath: "<your .icns icon>", // Same here
BaseDirectoryPath: "<where you want the provisioner to install the dependencies>",
VersionAstilectron: "<version of Astilectron to utilize such as `0.33.0`>",
VersionElectron: "<version of Electron to utilize such as `4.0.1` | `6.1.2`>",
})
defer a.Close()
// Start astilectron
a.Start()
// Blocking pattern
a.Wait()
For everything to work properly we need to fetch 2 dependencies : astilectron and Electron. .Start() takes care of it by downloading the sources and setting them up properly.
In case you want to embed the sources in the binary to keep a unique binary you can use the NewDisembedderProvisioner function to get the proper Provisioner and attach it to go-astilectron with .SetProvisioner(p Provisioner). Or you can use the bootstrap and the bundler. Check out the demo to see how to use them.
Beware when trying to add your own app icon as you'll need 2 icons : one compatible with MacOSX (.icns) and one compatible with the rest (.png for instance).
If no BaseDirectoryPath is provided, it defaults to the executable's directory path.
The majority of methods are asynchronous which means that when executing them go-astilectron will block until it receives a specific Electron event or until the overall context is cancelled. This is the case of .Start() which will block until it receives the app.event.ready astilectron event or until the overall context is cancelled.
HTML paths
NB! All paths in HTML (and Javascript) must be relative, otherwise the files will not be found. To make this happen in React for example, just set the homepage property of your package.json to "./".
{ "homepage": "./" }
Create a window
// Create a new window
var w, _ = a.NewWindow("http://127.0.0.1:4000", &astilectron.WindowOptions{
Center: astikit.BoolPtr(true),
Height: astikit.IntPtr(600),
Width: astikit.IntPtr(600),
})
w.Create()
When creating a window you need to indicate a URL as well as options such as position, size, etc.
This is pretty straightforward except the astilectron.Ptr* methods so let me explain: GO doesn't do optional fields when json encoding unless you use pointers whereas Electron does handle optional fields. Therefore I added helper methods to convert int, bool and string into pointers and used pointers in structs sent to Electron.
Open the dev tools
When developing in JS, it's very convenient to debug your code using the browser window's dev tools:
// Open dev tools
w.OpenDevTools()
// Close dev tools
w.CloseDevTools()
Add listeners
// Add a listener on Astilectron
a.On(astilectron.EventNameAppCrash, func(e astilectron.Event) (deleteListener bool) {
log.Println("App has crashed")
return
})
// Add a listener on the window
w.On(astilectron.EventNameWindowEventResize, func(e astilectron.Event) (deleteListener bool) {
log.Println("Window resized")
return
})
Nothing much to say here either except that you can add listeners to Astilectron as well.
Play with the window
// Play with the window
w.Resize(200, 200)
time.Sleep(time.Second)
w.Maximize()
Check out the Window doc for a list of all exported methods
Send messages from GO to Javascript
Javascript
// This will wait for the astilectron namespace to be ready
document.addEventListener('astilectron-ready', function() {
// This will listen to messages sent by GO
astilectron.onMessage(function(message) {
// Process message
if (message === "hello") {
return "world";
}
});
})
GO
// This will send a message and execute a callback
// Callbacks are optional
w.SendMessage("hello", func(m *astilectron.EventMessage) {
// Unmarshal
var s string
m.Unmarshal(&s)
// Process message
log.Printf("received %s\n", s)
})
This will print received world in the GO output
Send messages from Javascript to GO
GO
// This will listen to messages sent by Javascript
w.OnMessage(func(m *astilectron.EventMessage) interface{} {
// Unmarshal
var s string
m.Unmarshal(&s)
// Process message
if s == "hello" {
return "world"
}
return nil
})
Javascript
// This will wait for the astilectron namespace to be ready
document.addEventListener('astilectron-ready', function() {
// This will send a message to GO
astilectron.sendMessage("hello", function(message) {
console.log("received " + message)
});
})
This will print "received world" in the Javascript output
Play with the window's session
// Clear window's HTTP cache
w.Session.ClearCache()
Handle several screens/displays
// If several displays, move the window to the second display
var displays = a.Displays()
if len(displays) > 1 {
time.Sleep(time.Second)
w.MoveInDisplay(displays[1], 50, 50)
}
Menus
// Init a new app menu
// You can do the same thing with a window
var m = a.NewMenu([]*astilectron.MenuItemOptions{
{
Label: astikit.StrPtr("Separator"),
SubMenu: []*astilectron.MenuItemOptions{
{Label: astikit.StrPtr("Normal 1")},
{
Label: astikit.StrPtr("Normal 2"),
OnClick: func(e astilectron.Event) (deleteListener bool) {
log.Println("Normal 2 item has been clicked")
return
},
},
{Type: astilectron.MenuItemTypeSeparator},
{Label: astikit.StrPtr("Normal 3")},
},
},
{
Label: astikit.StrPtr("Checkbox"),
SubMenu: []*astilectron.MenuItemOptions{
{Checked: astikit.BoolPtr(true), Label: astikit.StrPtr("Checkbox 1"), Type: astilectron.MenuItemTypeCheckbox},
{Label: astikit.StrPtr("Checkbox 2"), Type: astilectron.MenuItemTypeCheckbox},
{Label: astikit.StrPtr("Checkbox 3"), Type: astilectron.MenuItemTypeCheckbox},
},
},
{
Label: astikit.StrPtr("Radio"),
SubMenu: []*astilectron.MenuItemOptions{
{Checked: astikit.BoolPtr(true), Label: astikit.StrPtr("Radio 1"), Type: astilectron.MenuItemTypeRadio},
{Label: astikit.StrPtr("Radio 2"), Type: astilectron.MenuItemTypeRadio},
{Label: astikit.StrPtr("Radio 3"), Type: astilectron.MenuItemTypeRadio},
},
},
{
Label: astikit.StrPtr("Roles"),
SubMenu: []*astilectron.MenuItemOptions{
{Label: astikit.StrPtr("Minimize"), Role: astilectron.MenuItemRoleMinimize},
{Label: astikit.StrPtr("Close"), Role: astilectron.MenuItemRoleClose},
},
},
})
// Retrieve a menu item
// This will retrieve the "Checkbox 1" item
mi, _ := m.Item(1, 0)
// Add listener manually
// An OnClick listener has already been added in the options directly for another menu item
mi.On(astilectron.EventNameMenuItemEventClicked, func(e astilectron.Event) bool {
log.Printf("Menu item has been clicked. 'Checked' status is now %t\n", *e.MenuItemOptions.Checked)
return false
})
// Create the menu
m.Create()
// Manipulate a menu item
mi.SetChecked(true)
// Init a new menu item
var ni = m.NewItem(&astilectron.MenuItemOptions{
Label: astikit.StrPtr("Inserted"),
SubMenu: []*astilectron.MenuItemOptions{
{Label: astikit.StrPtr("Inserted 1")},
{Label: astikit.StrPtr("Inserted 2")},
},
})
// Insert the menu item at position "1"
m.Insert(1, ni)
// Fetch a sub menu
s, _ := m.SubMenu(0)
// Init a new menu item
ni = s.NewItem(&astilectron.MenuItemOptions{
Label: astikit.StrPtr("Appended"),
SubMenu: []*astilectron.MenuItemOptions{
{Label: astikit.StrPtr("Appended 1")},
{Label: astikit.StrPtr("Appended 2")},
},
})
// Append menu item dynamically
s.Append(ni)
// Pop up sub menu as a context menu
s.Popup(&astilectron.MenuPopupOptions{PositionOptions: astilectron.PositionOptions{X: astikit.IntPtr(50), Y: astikit.IntPtr(50)}})
// Close popup
s.ClosePopup()
// Destroy the menu
m.Destroy()
A few things to know:
- when assigning a role to a menu item,
go-astilectronwon't be able to capture its click event - on MacOS there's no such thing as a window menu, only app menus therefore my advice is to stick to one global app menu instead of creating separate window menus
- on MacOS MenuItem without SubMenu is not displayed
Tray
// New tray
var t = a.NewTray(&astilectron.TrayOptions{
Image: astikit.StrPtr("/path/to/image.png"),
Tooltip: astikit.StrPtr("Tray's tooltip"),
})
// Create tray
t.Create()
// New tray menu
var m = t.NewMenu([]*astilectron.MenuItemOptions{
{
Label: astikit.StrPtr("Root 1"),
SubMenu: []*astilectron.MenuItemOptions{
{Label: astikit.StrPtr("Item 1")},
{Label: astikit.StrPtr("Item 2")},
{Type: astilectron.MenuItemTypeSeparator},
{Label: astikit.StrPtr("Item 3")},
},
},
{
Label: astikit.StrPtr("Root 2"),
SubMenu: []*astilectron.MenuItemOptions{
{Label: astikit.StrPtr("Item 1")},
{Label: astikit.StrPtr("Item 2")},
},
},
})
// Create the menu
m.Create()
// Change tray's image
time.Sleep(time.Second)
t.SetImage("/path/to/image-2.png")
Notifications
// Create the notification
var n = a.NewNotification(&astilectron.NotificationOptions{
Body: "My Body",
HasReply: astikit.BoolPtr(true), // Only MacOSX
Icon: "/path/to/icon",
ReplyPlaceholder: "type your reply here", // Only MacOSX
Title: "My title",
})
// Add listeners
n.On(astilectron.EventNameNotificationEventClicked, func(e astilectron.Event) (deleteListener bool) {
log.Println("the notification has been clicked!")
return
})
// Only for MacOSX
n.On(astilectron.EventNameNotificationEventReplied, func(e astilectron.Event) (deleteListener bool) {
log.Printf("the user has replied to the notification: %s\n", e.Reply)
return
})
// Create notification
n.Create()
// Show notification
n.Show()
Dock (MacOSX only)
// Get the dock
var d = a.Dock()
// Hide and show the dock
d.Hide()
d.Show()
// Make the Dock bounce
id, _ := d.Bounce(astilectron.DockBounceTypeCritical)
// Cancel the bounce
d.CancelBounce(id)
// Update badge and icon
d.SetBadge("test")
d.SetIcon("/path/to/icon")
// New dock menu
var m = d.NewMenu([]*astilectron.MenuItemOptions{
{
Label: astikit.StrPtr("Root 1"),
SubMenu: []*astilectron.MenuItemOptions{
{Label: astikit.StrPtr("Item 1")},
{Label: astikit.StrPtr("Item 2")},
{Type: astilectron.MenuItemTypeSeparator},
{Label: astikit.StrPtr("Item 3")},
},
},
{
Label: astikit.StrPtr("Root 2"),
SubMenu: []*astilectron.MenuItemOptions{
{Label: astikit.StrPtr("Item 1")},
{Label: astikit.StrPtr("Item 2")},
},
},
})
// Create the menu
m.Create()
Global Shortcuts
Registering a global shortcut.
// Register a new global shortcut
isRegistered, _ := a.GlobalShortcuts().Register("CmdOrCtrl+x", func() {
fmt.Println("CmdOrCtrl+x is pressed")
})
fmt.Println("CmdOrCtrl+x is registered:", isRegistered) // true
// Check if a global shortcut is registered
isRegistered, _ = a.GlobalShortcuts().IsRegistered("Shift+Y") // false
// Unregister a global shortcut
a.GlobalShortcuts().Unregister("CmdOrCtrl+x")
// Unregister all global shortcuts
a.GlobalShortcuts().UnregisterAll()
Dialogs
Add the following line at the top of your javascript file :
const { dialog } = require('electron').remote
Use the available methods.
Basic auth
// Listen to login events
w.OnLogin(func(i astilectron.Event) (username, password string, err error) {
// Process the request and auth info
if i.Request.Method == "GET" && i.AuthInfo.Scheme == "http://" {
username = "username"
password = "password"
}
return
})
Features and roadmap
- custom branding (custom app name, app icon, etc.)
- window basic methods (create, show, close, resize, minimize, maximize, ...)
- window basic events (close, blur, focus, unresponsive, crashed, ...)
- remote messaging (messages between GO and Javascript)
- single binary distribution
- multi screens/displays
- menu methods and events (create, insert, append, popup, clicked, ...)
- bootstrap
- dialogs (open or save file, alerts, ...)
- tray
- bundler
- session
- accelerators (shortcuts)
- dock
- notifications
- loader
- file methods (drag & drop, ...)
- clipboard methods
- power monitor events (suspend, resume, ...)
- desktop capturer (audio and video)
- window advanced options (add missing ones)
- window advanced methods (add missing ones)
- window advanced events (add missing ones)
- child windows
Cheers to
go-thrust which is awesome but unfortunately not maintained anymore. It inspired this project.
Repo liên quan
Awesome Go, maintained at avelino/awesome-go, groups Go frameworks, libraries, and software into topic categories including Actor Model, Artificial Intelligence, Audio and Music, Authentication and Authorization, Blockchain, Bot Building, and Build Automation. Every linked entry gets a short description instead of a bare URL. The repository carries an MIT license and takes new entries through pull requests reviewed against its own contribution guidelines, which makes it a common bookmark for day-to-day Go development.
golang/go is the open source repository behind The Go Programming Language, holding the compiler, runtime, and standard library source that Go's official binaries are built from. The README frames Go's purpose as building software that is simple, reliable, and efficient, credits the project to thousands of contributors, and notes that this GitHub repo mirrors the canonical Git repository at go.googlesource.com/go.
Caddy is an HTTP/1-2-3 web server, written in Go, which provides automatic HTTPS by default, utilizing services like ZeroSSL and Let's Encrypt for public names or a local CA for internal ones. It supports flexible configuration through its native JSON API, a Caddyfile, or various other formats via config adapters. The project highlights a modular architecture for extensibility, runs on multiple platforms without external dependencies, and benefits from Go's memory safety features. The README indicates it has served trillions of requests and managed millions of TLS certificates, scaling to hundreds of thousands of sites in production. Caddy began development in 2014 and was an early adopter of automatic HTTPS by default.
Moby is the open-source project moby/moby on GitHub, created by Docker to package the pieces of a container system, build tools, a registry, orchestration tools, and a runtime, as separate, well-defined components developers can assemble or swap. It is written in Go, and ships under the Apache-2.0 license. Docker uses Moby as the upstream for Docker Engine, and the two supported Go modules, client and api, are how other Go programs talk to Docker Engine's API.
Trả lời nhanh
asticode/go-astilectron có bao nhiêu sao?
asticode/go-astilectron có 4.9k sao GitHub — tải lại trang để xem số mới nhất, hoặc xem trực tiếp github.com/asticode/go-astilectron. TopGit phản chiếu số sao của GitHub nhưng không cam kết đến từng phút.
asticode/go-astilectron có những chủ đề gì?
GitHub topics của asticode/go-astilectron: "cross-platform", "desktop-app", "electron", "go", "golang", "gui". TopGit xếp repo vào nhóm Backend.
asticode/go-astilectron còn đang phát triển không?
Commit gần nhất trên asticode/go-astilectron là 2.5 năm trước (theo timestamp GitHub). Repo có 342 fork — một chỉ báo về mức độ quan tâm của cộng đồng.
asticode/go-astilectron là gì?
asticode/go-astilectron (asticode/go-astilectron) là dự án Go trên GitHub. Theo mô tả gốc: Build cross platform GUI apps with GO and HTML/JS/CSS (powered by Electron)
asticode/go-astilectron so với các dự án Backend khác thế nào?
asticode/go-astilectron được TopGit xếp vào nhóm Backend, với 4.9k sao GitHub và viết bằng Go. Xem trang chủ đề Backend trên TopGit để so sánh với các dự án tương tự theo số sao và mức độ hoạt động.
asticode/go-astilectron viết bằng ngôn ngữ gì?
asticode/go-astilectron chủ yếu viết bằng Go. Trường "language" của GitHub dựa trên phần lớn byte ở nhánh mặc định.
Vì sao asticode/go-astilectron được xếp vào nhóm Backend?
TopGit xếp asticode/go-astilectron vào nhóm Backend dựa trên GitHub topics và mô tả của repo (gắn thẻ: "cross-platform", "desktop-app", "electron"). Việc phân loại dựa trên metadata thật của repo, không phải đoán theo cảm tính biên tập.
Đọc đầy đủ README ở tab phía trên.
Muốn nghe thêm một ý kiến về go-astilectron?
Hỏi một AI đọc được trang này — một cú bấm là có ngay nhận định về go-astilectron.