Git Product home page Git Product logo

go-astilectron's Introduction

GoReportCard GoDoc Test Coveralls

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-astilectron won'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.

go-astilectron's People

Contributors

asticode avatar benebsiny avatar bennetty avatar billymurrayolive avatar carsonslovoka avatar craigsc avatar deepch avatar donovansolms avatar fregie avatar happy-ferret avatar heavyhorst avatar iangallolive avatar jeremydonahue avatar joe-improbable avatar kfrico avatar liasica avatar lunny avatar maddie avatar naatan avatar paolobelluticm avatar raboof avatar roromix avatar sam-kamerer avatar sereeena avatar tehsphinx avatar true-zero avatar vidmed avatar wickedst avatar worlpaker avatar zerokiseki avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-astilectron's Issues

Build error?

% go get -u github.com/asticode/go-astilectron

github.com/asticode/go-astilog

workspace/src/github.com/asticode/go-astilog/logger.go:42: not enough arguments in call to logrus.IsTerminal
have ()
want (io.Writer)
workspace/src/github.com/asticode/go-astilog/out_syslog.go:16: not enough arguments in call to logrus.IsTerminal
have ()
want (io.Writer)

old electron version

Version 1.6.5 of Electron is quite old. Could it be upgraded to the latest version or is it not compatible with astilectron-go?

Question about several window

This is the very first time for me to make a GUI so these questions may be really basic:

  1. Is my understanding correct: astilectron is a app (which refers to the GUI I made) and it may contain several windows?
  2. What is the difference between a window and a display?
  3. Does this binding allow multiple windows on at the same time?
  4. If it allows and I have multiple windows on, is it okey if I send a message from one window to go while go sends message to a different window (the main window)?
    Thank you so much for your help!

Remove menu

Hi,
great job, but it seems that there is no way to remove the menu or simply set it to empty.
if I try with
var m = a.NewMenu([]*astilectron.MenuItemOptions{})
or
var m = a.NewMenu(nil)

I receive:
Uncaught Exception: TypeError: Cannot read property 'length' of undefined at menuCreate (/home/fede/goprojects/src/testElectron2/assets/vendor/astilectron/main.js:157:38) at Interface.<anonymous> (/home/fede/goprojects/src/testElectron2/assets/vendor/astilectron/main.js:42:39) at emitOne (events.js:96:13) at Interface.emit (events.js:188:7) at Interface._onLine (readline.js:247:10) at Interface.<anonymous> (readline.js:384:12) at Array.forEach (native) at Interface._normalWrite (readline.js:383:11) at Socket.ondata (readline.js:107:10) at emitOne (events.js:96:13)

but I remember that in electron is possibile remove the Menu with something like that

window.setMenu(null);

It would be nice doing the same thing with this library too.
Or did I miss something?

Thank you in advance.

Introduce a simpler way of adding Menu Listeners

Hi,
in a menu, almost every item requires an onClick listener. Is it possible to add this straight to the MenuItemOptions struct, since building a menu by hand and adding all the listeners is pretty costly.
BTW: Great project, thanks a lot!

GOARCH=386 support

Hi,

I recently got a project going where I'm able to nicely build a single binary program using go-astilectron, for 64bit linux & windows. I then got to work trying to build for GOARCH=386 (I have the toolchain built) and get a successful build with GOARCH=386 build -a, but when I try to run it I get an marshaling error when I guess astilectron is starting up.

Error I get is:
{"level": "error","msg":"json:cannot unmarshal number 2528732444 into Go struct field DisplayOptions.id of type int while unmarshaling {\"name\":\"app.event.ready\", ... snip ... \"displays\":{\"all\":[{\"id\":2528732444,\"bounds\" ... another snip ... }

Exactly the same code, but built with GOARCH=amd64, is working wonderfully.

Is 32bit supported at all?

This is an amazing project, thank you for all your hard work so far!

Implement a cross-platform splash screen

In My application, have decided to make the dependencies available in a specific folder once they are unzipped and configured by the default provisioner for the first time. The issue is that, the application gives a user a bad user experience especially the first time they run the application. The default provisioner takes quite sometime while running for the first time. Can we have a splash screen that appears while the default provisioner sets up the required dependencies configurations?

Tray menu overwrites application menu

Hi!

I just started using go-astilectron. I had a look at the demo and realized that when adding TrayMenuOptions they seem to overwrite the menu options.

I then used the Run() as a sample and eliminated the bootstrap package from my test but the issue is the same.

Am I doing something wrong?

Note: I am working on MacOSX 10.12.6.

event.preventDefault() for go events

I am currently trying to implement a dialog to ask if the application should really be closed. (My App is a little management interface for a local server which should not be closed accidentally, since it shuts down the sever then.)

In Electron one would use event.preventDefault() to stop the app from closing. Is there another way to achieve this behaviour or could this be implemented? Basically this is about "feedback to JS" on executing events.

Loading a second template into the primary window

I am trying to load a second template.
So far I used the js function:

 window.open("/templates/secondsTemplate");

That will open a new window, my goal is to open it in the same window.

I am using the bootstrap, therefore I do not have access to the window variable in go.
Anyway, I couldn't find anything in the code that would load a new template. My guess is that this is done from the js side.

Any suggestions?

Add screenshot with code exemples

Everything is in the title, all of this looks nice but it would be better for advanced feature such as Trays and Menus,

otherwise, another great project 👍

Problems installing

When I run go get -u github.com/asticode/go-astilectron, I get an error:

package github.com/mattn/go-colorable: directory "c:\\[MyPath]\\GoLang\\src\\github.com\\mattn\\go-colorable" is not using a known version control system

Using windows.

syslog does not exist on all build environments

When automating the build in my gitlab ci container (based on golang 1.8 container: https://hub.docker.com/r/tehsphinx/gitlab-ci-xgo/) I got this error.

The asticode/go-astilog panics if syslog cannot be used. Can we have a fallback here? Instead of panicking just use stdout instead?

$ astilectron-bundler
panic: new syslog failed: Unix syslog delivery error

goroutine 1 [running]:
github.com/asticode/go-astilog.DefaultOut(0x0, 0x0, 0x0, 0x69fea0, 0xc420011600)
	/go/src/github.com/asticode/go-astilog/out_syslog.go:20 +0xfc
github.com/asticode/go-astilog.New(0x0, 0x0, 0x0, 0x0, 0x0)
	/go/src/github.com/asticode/go-astilog/logger.go:44 +0x1b6
github.com/asticode/go-astilog.FlagInit()
	/go/src/github.com/asticode/go-astilog/std.go:8 +0x47
main.main()
	/go/src/github.com/asticode/go-astilectron-bundler/astilectron-bundler/main.go:29 +0xa5

running the menu example with bootstrap example

I've tried unsuccessfully to invoke a menu using /example/8.bootstrap, and would like suggestions.

I've used the AdaptWindow, and AdaptAstilectron functions via /example/8.bootstrap, in the bootstrap.run options. In the case of AdaptAstilectron, it works, and then it's quickly replaced when the bootstrap loads and in the case AdaptWindow, it ignores the creation of the menu altogether, with the exception of loading a popup menu onto the canvas.

Basic example not working in windows 10

I running go1.8.3 windows/amd64 on Windows 10, I use the code from the example and the windows appears blank without any error, the same example in MacOS works perfectly

How can I use http server

I want to use an http framework to accelerate the development process. Could I do it with astilectron, as for example go-nw.

Please show the example

What are the 2 folders created on startup?

Am using the latest demo project from osx.

When I run the eye on windows of the demo it creates 2 folders on startup.
Is this by design ?

Does not do that on osx.app

Btw the tray works on windows.

Command not found

I tried the demo and downloaded packages as required by step 1 and step2. However, when I run step 3 "$ astilectron-bundler -v", I got an error saying that "bundler: command not found". I'm really new to programming and have no idea why this happened. Do I need to install anything other than your packages?

One full example outside of this repo

I think it would be good if you could provide one full example in a separate repo which uses this repo.

Basic needs:

  1. Cross platform single binary building (but working - #13)
  2. real single binary as in -css, templates, html static files, icons, images or whatever included-
  3. Full-Featured (everything that is currently implemented) included and working in the example.
    maybe a simple crud with a sqlite-db, just so people have something they understand and can use right away. maybe copy some
  4. Updated & tested

If you have something that is ready to use for people I think this could be the one go-ui project.
It will grow and people will participate. You are so close, it would be really great.

Usually go ui projects die at some point and stay unfinished, but I think this one could be it.

murlocswarm only works on sierra, no windows (i'm using this at the moment)
anlabs/ui - author currently not really motivated (according to him), limited on native ui
alexflint/gallium - osx only, no windows, last update march
nelsam/gxui - one guy picking up and abandoned google go gui opengl repo
golang-ui/nuklear - c bindings , opengl - :-(

Tray click event

Just started working with go-astilectron and ran into a case where I wanted to click/double-click the tray icon (win platform). Doesn't look like those events are sent up to go-land.

application 'crashes' on window close

Not sure if this is macOS only or not - I don't have any other information available.

When clicking the close button on a window (in the asticode/go-astilectron-demo application), the following sequence of events happens:

DEBU[0021] Astilectron says: {"name":"window.event.closed","targetID":"1"}
DEBU[0021] App has crashed
DEBU[0021] Stopping...
DEBU[0021] Closing...

In this case, the "crash" has no real negative affects since the application only has the one window anyway. However for my use case I need the main application to continue running after one window has closed, and this seems to be preventing that.

Can't use synchronousEvent inside a listener

Currently I am playing with minimize, maximize, resize events of a window. I realized that they are not triggered when minimizing (etc.) the window on my mac. (Put some debugs in the code to be sure but they are definitely not triggered.)

Not sure if this is a general issue with JS side events not correctly relayed to go or not.

Use AppIcon from Assets generated by go-bindata

Is it possible to do use assets linked with the binary assets generated by go-bindata for app icon logo?
Currently I have to give a file path but I would like it to use the asset file generated by go-bindata.

So, for example:

var a *astilectron.Astilectron
	if a, err = astilectron.New(astilectron.Options{
		AppName:            "App v0.1",
		AppIconDefaultPath: "vendor/logo.png",
		AppIconDarwinPath:  "vendor/logo.icns",
		BaseDirectoryPath:  "./",
	}); err != nil {
		astilog.Fatal(errors.Wrap(err, "creating new astilectron failed"))
	}
	a.SetProvisioner(astilectron.NewDisembedderProvisioner(Asset, "vendor/astilectron-v"+astilectron.VersionAstilectron+".zip", "vendor/electron-v"+astilectron.VersionElectron+".zip"))

But here vendor is a directory, but if we can pass the Asset Directly instead of path, or any other way then it would be great to have app icon embedded in a single file especially when you are building a single file distribution application.

RaspberryPi: Display ID should use int64 and invalid (non-arm/armv7) electron package downloaded

Hi everyone,

Running into two small issues when using Astilectron on a Raspberry Pi (cross-compiled using GOOS=linux and GOARCH=arm)

First, the wrong electron package is downloaded. I haven't debugged it yet, but the default x64 package is downloaded instead of the arm (or even better, the armv7l) one.

Second, the display ID when using the full KMS driver on Raspberry Pi 3 B is larger than 64 bits and causes a JSON unmarshalling exception:

ERRO[0003] json: cannot unmarshal number 1267736906825728 into Go struct field DisplayOptions.id of type int while unmarshaling {"name":"app.event.ready","targetID":"main","displays":{"all":[{"id":1267736906825728,"bounds":{"x":0,"y":0,"width":600,"height":1024},"workArea":{"x":0,"y":0,"width":600,"height":1024},"size":{"width":600,"height":1024},"workAreaSize":{"width":600,"height":1024},"scaleFactor":1,"rotation":270,"touchSupport":"unknown"}],"primary":{"id":1267736906825728,"bounds":{"x":0,"y":0,"width":600,"height":1024},"workArea":{"x":0,"y":0,"width":600,"height":1024},"size":{"width":600,"height":1024},"workAreaSize":{"width":600,"height":1024},"scaleFactor":1,"rotation":270,"touchSupport":"unknown"}}} 

Replacing int pointers in display/display_pool with int64 pointers seems to fix the issue. I'll make a pull request if changing that has no other side effect.

AppIconDefaultPath

Could you check whether your icon changed after removal and re download vendor

2017-07-10 14 34 46

code

package main

import (
        "flag"

        astilectron "github.com/asticode/go-astilectron"
        astilog "github.com/asticode/go-astilog"
        "github.com/pkg/errors"
)

func main() {
        // Parse flags
        flag.Parse()

        // Set up logger
        astilog.SetLogger(astilog.New(astilog.FlagConfig()))

        // Get base dir path
        var err error
        var p = "/Users/deepweb/Desktop/work/test2/src/github.com/asticode/go-astilectron/examples"

        // Create astilectron
        var a *astilectron.Astilectron
        if a, err = astilectron.New(astilectron.Options{
                AppName:            "Astilectron",
                AppIconDefaultPath: p + "/gopher.png",
                AppIconDarwinPath:  p + "/gopher.icns",
                BaseDirectoryPath:  p,
        }); err != nil {
                astilog.Fatal(errors.Wrap(err, "creating new astilectron failed"))
        }
        defer a.Close()
        a.HandleSignals()

        // Start
        if err = a.Start(); err != nil {
                astilog.Fatal(errors.Wrap(err, "starting failed"))
        }

        // Create window
        var w *astilectron.Window
        if w, err = a.NewWindow(p+"/index.html", &astilectron.WindowOptions{
                Center: astilectron.PtrBool(true),
                Height: astilectron.PtrInt(600),
                Width:  astilectron.PtrInt(600),
        }); err != nil {
                astilog.Fatal(errors.Wrap(err, "new window failed"))
        }
        if err = w.Create(); err != nil {
                astilog.Fatal(errors.Wrap(err, "creating window failed"))
        }

        // Blocking pattern
        a.Wait()
}

ls /Users/deepweb/Desktop/work/test2/src/github.com/asticode/go-astilectron/examples

bash-3.2$ ls /Users/deepweb/Desktop/work/test2/src/github.com/asticode/go-astilectron/examples
1.basic_window			3.webserver_app			5.single_binary_distribution	7.menus				gopher.icns			index.html
2.basic_window_events		4.remote_messaging		6.screens_and_displays		8.bootstrap			gopher.png			vendor
bash-3.2$ 

I think a few days ago there was no such problem.

How can I use jQuery?

I try to use jQuery.
<script type="text/javascript" src="../jquery-3.2.1.min.js"></script>
but it doesn't work.
How can I use it on this library?

Listen() function in JavaScript

astilectron.listen(function(message) {
// This will send a message back to GO
astilectron.send("I'm good bro")
})
I don't quite understand this part. Does that mean astilectron.listen() will return a "message"?

BTW, is there any reference (like a GoDoc) so that I can check the detailed information of functions in JavaScript?

Can't end an app

While I create a window for a url like "https://wx.qq.com" .if I close the app but the program doesn't end up.
I try to find out the reason.Then I find the program bolcked in a.Wait().
so If I modify the function a.Stop()

func (a *Astilectron) Stop() {
	astilog.Debug("Stopping...")
	a.canceller.Cancel()
	close(a.channelQuit)
	//	if a.channelQuit != nil {
	//		close(a.channelQuit)
	//		a.channelQuit = nil
	//	}
}

a.Wait()

func (a *Astilectron) Wait() {
	//for {
	astilog.Debug("wait for quit")
	// select {
	// case <-a.channelQuit:
	// 	return
	// }
	select {
	case _, ok := <-a.channelQuit:
		if !ok {
			a.channelQuit = nil
		}
		return
	}
	//}
}

It will not blolck and end up right now.But I don't clearly understand why the website is blocked.Maybe the channel need to close ,not set value nil.

Windows support?

I can't seem to build the examples because paths.go uses os.Executable() which does not work on Windows. Is this known behavior? Thanks.

$ go run examples/3.webserver_app/main.go
# github.com/asticode/go-astilectron
.\paths.go:64: undefined: os.Executable

paths.go:65 undefined os.Executable

I'm getting an error when getting the repo (I have electron installed)

$ go get -u github.com/asticode/go-astilectron
# github.com/asticode/go-astilectron
../github.com/asticode/go-astilectron/paths.go:65: undefined: os.Executable

$ go version
go version go1.8.3 darwin/amd64

Bug : I cant run it

Hi,
First I'd like to thank you a lot for this project, i was using go-thrust.

This happens when i'm trying to run example 1 (or any example actually)

C:\Users\xxx\go\src\github.com\asticode\go-astilectron\examples\1.basic_window>go run main.go -v
2017/05/06 08:53:03 ←[37mDEBU←[0m Starting... ←[32mapp_name←[0m= ←[32mfile←[0m=std.go:122017/05/06 08:53:03 ←[37mDEBU←[0m Provisioning... ←[32mapp_name←[0m= ←[32mfile←[0m=std.go:12
2017/05/06 08:53:03 ←[34mFATA←[0m starting failed: provisioning failed: retrieving provisioning status failed: opening file
C:\Users\xxx\go\src\github.com\asticode\go-astilectron\examples\1.basic_window"C:\Users\xxx\go"\src\github.com\asticode\go-astilectron\examples\vendor\status.json
failed: open C:\Users\xxx\go\src\github.com\asticode\go-astilectron\examples\1.basic_window"C:\Users\xxx\go"\src\github.com\asticode\go-astilectron\examples\vendor\status.json:
La syntaxe du nom de fichier, de répertoire ou de volume est incorrecte. ←[32mapp_name←[0m= ←[32mfile←[0m=std.go:20
exit status 1

And when i'm trying to run some code looking like this :

func displayloading(){
for{
timer1 := time.NewTimer(time.Second * 5)
<-timer1.C
fmt.Println("loading ...")
}
}
func window_init() {
go displayloading()
go runwebserver()
var a *astilectron.Astilectron
a, _ = astilectron.New(astilectron.Options{})

defer a.Close()
a.HandleSignals()
a.Start()
ws, _ := a.NewWindow("http://127.0.0.1:"+port+"/"+folder+"/"+index, &astilectron.WindowOptions{
Center: astilectron.PtrBool(true),
Height: astilectron.PtrInt(600),
Width: astilectron.PtrInt(800),
})

ws.Create()
a.Wait()
}

"Loading ..." appears 4 times and then nothing never happens

My user doesnt have administrator rights, I think that this may be the reason why.

Do you have any ideas of how to fix this ?
Here's my spec :
go version go1.7.5 windows/amd64
Windows 7, 64bit.

Thanks again.

examples error

github.com/asticode/go-astilectron/examples/5.single_binary_distribution

bash-3.2$ go run *.go

command-line-arguments

./main.go:34: undefined: Asset
bash-3.2$

Loader doesn't work on MacOSX :(

2017-05-16 11:02:19.823 go-astivid[4307:76205] *** Assertion failure in +[NSUndoManager _endTopLevelGroupings], /Library/Caches/com.apple.xbs/Sources/Foundation/Foundation-1349.64/Misc.subproj/NSUndoManager.m:363
2017-05-16 11:02:19.823 go-astivid[4307:76205] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+[NSUndoManager(NSInternal) _endTopLevelGroupings] is only safe to invoke on the main thread.'
*** First throw call stack:
(
        0   CoreFoundation                      0x00007fffd421337b __exceptionPreprocess + 171
        1   libobjc.A.dylib                     0x00007fffe900748d objc_exception_throw + 48
        2   CoreFoundation                      0x00007fffd4218082 +[NSException raise:format:arguments:] + 98
        3   Foundation                          0x00007fffd5c5fce0 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
        4   Foundation                          0x00007fffd5bea3b3 +[NSUndoManager(NSPrivate) _endTopLevelGroupings] + 170
        5   AppKit                              0x00007fffd1c7a8bd -[NSApplication run] + 1200
        6   go-astivid                          0x0000000004386d3d uiMain + 29
        7   go-astivid                          0x0000000004056470 runtime.asmcgocall + 112
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Related issues:

Suggestion to basic initializing screen

Hi,

I search for a way to create a initializing screen, without depends on other reps. You dont need other libs. You can call per-platform their ui libraries. I search some references to you:

1 - Windows (win api):

Example creating window in c++:
https://github.com/LeZuse/minimal-win32-app/blob/master/main.cpp

Now in Go:
https://github.com/lxn/walk/blob/master/window.go

2 - Linux (x11):
https://github.com/golang/exp/blob/master/shiny/driver/x11driver/window.go

3 - MacOS (cocoa):
https://github.com/alediaferia/gogoa/blob/master/window.go

You dont need implement everything, but if we have a window with an image and a label showing what is happing and show the error (if have), we dont need more nothing, the rest if the main window in electron.

Thanks.

Can i use the resize in bootstrap

I create

MessageHandler: func(w *astilectron.Window, m bootstrap.MessageIn) {
			if err := w.Resize(200, 200); err != nil {
				log.Println(err)
			}
		},

and

<script>
    function clickelemet() {
            astilectron.send({name: "say", payload: {message: "hello"}})
    }
</script>

At the first click the window changes its size but then stops doing it.

Unexpected errors after failed initial run

Canceling the download/extraction for the initial astilectron/electron dependencies returns the following error:

provisioning failed: provisioning electron failed: unzipping /path/to/app/vendor/electron-windows-amd64-v1.6.5.zip into /path/to/app/vendor/electron-windows-amd64 failed: opening overall zip reader on /path/to/app/vendor/electron-windows-amd64-v1.6.5.zip failed: zip: not a valid zip file.

I would expect that if the process is interrupted at .Start() that on the next start it should detect the previous run was interrupted and the extraction directories are not completed that the original zips are deleted, the download restarted.

In this case, the zips were not completely downloaded when the program was interrupted and quit, thus invalid and the application exited.

Not really a big issue, just something I noticed while going through the docs of the project.
Thanks for an interesting project. Cheers!

main.js missing on windows 386

When executing asticon demo on windows 386 the main.js cannot be found. When checking the ...\vendor\astilectron folder it is empty.

commands executed in demo folder:

astilectron-bundler -v
go run main.go bind.go message.go -v -d

Note: same when executing the generated exe file.

Any ideas?

Standalone binary instructions?

I see that example 5 concerns single binary distributions, but I'm not sure what these commands do exactly:

$ go generate examples/5.single_binary_distribution/main.go
$ go run examples/5.single_binary_distribution/main.go examples/5.single_binary_distribution/vendor.go -v

Does this just apply to the last example you've run? Where does it put the binary? Also, the go generate command works on one of my machines, but on another machine I get:

bindata: Failed to stat input path '..\vendor': GetFileAttributesEx ..\vendor: The system cannot find the file specified.
examples\5.single_binary_distribution\main.go:12: running "go-bindata": exit status 1

It seems as though this machine doesn't create the go-astilectron\examples\vendor directory when running the examples for some reason. Both are Windows 10, Go 1.8.3.

Separate question: running go install on any of the examples seems to output a standalone binary in my go\bin directory. Are these true standalone binaries? If so, what is the purpose of example 5? Also, if someone could give me a clearer idea of what the go-astilectron-bundler is for I'd be very grateful. Thanks!

Fix data race

WARNING: DATA RACE
Read at 0x00c4201c09fd by goroutine 43:
  github.com/asticode/go-astilectron.TestSynchronousFunc()
      /home/asticode/projects/go/src/github.com/asticode/go-astilectron/helper_test.go:151 +0x675
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:657 +0x107

Previous write at 0x00c4201c09fd by goroutine 44:
  github.com/asticode/go-astilectron.TestSynchronousFunc.func1()
      /home/asticode/projects/go/src/github.com/asticode/go-astilectron/helper_test.go:139 +0x49
  github.com/asticode/go-astilectron.(*Dispatcher).start()
      /home/asticode/projects/go/src/github.com/asticode/go-astilectron/dispatcher.go:80 +0x27f

Goroutine 43 (running) created at:
  testing.(*T).Run()
      /usr/local/go/src/testing/testing.go:697 +0x543
  testing.runTests.func1()
      /usr/local/go/src/testing/testing.go:882 +0xaa
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:657 +0x107
  testing.runTests()
      /usr/local/go/src/testing/testing.go:888 +0x4e0
  testing.(*M).Run()
      /usr/local/go/src/testing/testing.go:822 +0x1c3
  main.main()
      github.com/asticode/go-astilectron/_test/_testmain.go:114 +0x20f

Goroutine 44 (running) created at:
  github.com/asticode/go-astilectron.TestSynchronousFunc()
      /home/asticode/projects/go/src/github.com/asticode/go-astilectron/helper_test.go:134 +0x212
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:657 +0x107
==================
--- FAIL: TestSynchronousFunc (0.00s)
        testing.go:610: race detected during execution of test
FAIL
exit status 1
FAIL    github.com/asticode/go-astilectron      0.188s```

Store electron and astilectron according OS and arch

Since some developers using Windows and others MacOS and we would like to keep the binary on the git. It's so difficult to cooperate between us. Why not store electron and astilectron according OS and arch?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.