mirror of
https://github.com/taigrr/wails.git
synced 2026-04-14 10:50:53 -07:00
Compare commits
123 Commits
v0.18.3
...
267-Check-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
544fa7319c | ||
|
|
96fc70df26 | ||
|
|
1c8d4c902a | ||
|
|
08fc1d53d0 | ||
|
|
6c5d5e40f4 | ||
|
|
3f1dfe931c | ||
|
|
cb850c9653 | ||
|
|
8d8f47363a | ||
|
|
1b04b71254 | ||
|
|
0b19ad1427 | ||
|
|
9aca99911e | ||
|
|
a7f61e335e | ||
|
|
9fff0a513e | ||
|
|
7fd5b77cbe | ||
|
|
d2cac50f93 | ||
|
|
00f1f82520 | ||
|
|
02fbb14e34 | ||
|
|
f961659ada | ||
|
|
93942111bc | ||
|
|
dc5a68acce | ||
|
|
12ff0f8c97 | ||
|
|
c375c281ee | ||
|
|
7d86b0f7c4 | ||
|
|
990f7dd06c | ||
|
|
0b6f256d55 | ||
|
|
0a57fa4035 | ||
|
|
af1a1a2498 | ||
|
|
cc0617d247 | ||
|
|
99a3f87cef | ||
|
|
1ccdb1bc4e | ||
|
|
62b1967e45 | ||
|
|
c10303e7c0 | ||
|
|
4a61584827 | ||
|
|
cf249ba836 | ||
|
|
08fe7b64d6 | ||
|
|
77939ea414 | ||
|
|
468394d03c | ||
|
|
dc87699a1e | ||
|
|
36e906507d | ||
|
|
a5f9688708 | ||
|
|
880f900e51 | ||
|
|
349306cf73 | ||
|
|
f140697857 | ||
|
|
26ff8df7e5 | ||
|
|
b7dae216df | ||
|
|
0b9d093d6c | ||
|
|
7f282ad071 | ||
|
|
d6ed583e07 | ||
|
|
930cab2d9d | ||
|
|
ae41f33dcc | ||
|
|
5af6b7cafe | ||
|
|
68ac3763d0 | ||
|
|
cdc66b556e | ||
|
|
3ff16322c2 | ||
|
|
d60066a0b1 | ||
|
|
9d6ebf0fd4 | ||
|
|
839815e2fb | ||
|
|
846fe479bf | ||
|
|
62f7070e0c | ||
|
|
dd418b36c2 | ||
|
|
f4f04f2199 | ||
|
|
3a7514bbdc | ||
|
|
213f07fed4 | ||
|
|
ed3ed8aa18 | ||
|
|
d038dca37c | ||
|
|
bb86d770a1 | ||
|
|
33daa8621e | ||
|
|
6c124fcff4 | ||
|
|
45833574b3 | ||
|
|
5cb00eb481 | ||
|
|
e2105331c1 | ||
|
|
21d2383e63 | ||
|
|
6c945a4eed | ||
|
|
6c8d34dfd3 | ||
|
|
b9b42c059e | ||
|
|
3f657b34cf | ||
|
|
6e81a36ada | ||
|
|
ddec01a429 | ||
|
|
21fdb3be7d | ||
|
|
c1a13ab6d0 | ||
|
|
750a02efc6 | ||
|
|
5e047debfc | ||
|
|
9cac336708 | ||
|
|
827c2b9a95 | ||
|
|
b36a3c4abb | ||
|
|
0bac205565 | ||
|
|
67a8ad8e12 | ||
|
|
9de2f66f50 | ||
|
|
9370030ff3 | ||
|
|
e38d6e7ef0 | ||
|
|
2f21fc3575 | ||
|
|
63e73f5f64 | ||
|
|
e1adc1ba49 | ||
|
|
030e911ea4 | ||
|
|
d2f114e44e | ||
|
|
700d3f84d3 | ||
|
|
1d49042013 | ||
|
|
8671b1e6cf | ||
|
|
517d6c44ec | ||
|
|
a082a659ea | ||
|
|
083153efc9 | ||
|
|
65a2560153 | ||
|
|
29535c10a3 | ||
|
|
24c7362163 | ||
|
|
f6ff7d7b16 | ||
|
|
b0a075cdf2 | ||
|
|
98d4d6b33c | ||
|
|
9ba3e0512b | ||
|
|
eff63175e5 | ||
|
|
75a0b632bc | ||
|
|
a2af626477 | ||
|
|
8aa97f64ef | ||
|
|
caa1e04b5a | ||
|
|
cddf6a0204 | ||
|
|
9fa1f42dc7 | ||
|
|
c7e709d487 | ||
|
|
6801398f3d | ||
|
|
982d14c049 | ||
|
|
ddbaf55ae7 | ||
|
|
5552a8501b | ||
|
|
b997becb2f | ||
|
|
753516bab7 | ||
|
|
89992d8636 |
@@ -19,3 +19,4 @@ Wails is what it is because of the time and effort given by these great people.
|
|||||||
* [Nikolai Zimmermann](https://github.com/Chronophylos)
|
* [Nikolai Zimmermann](https://github.com/Chronophylos)
|
||||||
* [Toyam Cox](https://github.com/Vaelatern)
|
* [Toyam Cox](https://github.com/Vaelatern)
|
||||||
* [Robin Eklind](https://github.com/mewmew)
|
* [Robin Eklind](https://github.com/mewmew)
|
||||||
|
* [Kris Raney](https://github.com/kraney)
|
||||||
|
|||||||
39
app.go
39
app.go
@@ -1,6 +1,10 @@
|
|||||||
package wails
|
package wails
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/syossan27/tebata"
|
||||||
"github.com/wailsapp/wails/cmd"
|
"github.com/wailsapp/wails/cmd"
|
||||||
"github.com/wailsapp/wails/lib/binding"
|
"github.com/wailsapp/wails/lib/binding"
|
||||||
"github.com/wailsapp/wails/lib/event"
|
"github.com/wailsapp/wails/lib/event"
|
||||||
@@ -66,6 +70,7 @@ func CreateApp(optionalConfig ...*AppConfig) *App {
|
|||||||
|
|
||||||
// Run the app
|
// Run the app
|
||||||
func (a *App) Run() error {
|
func (a *App) Run() error {
|
||||||
|
|
||||||
if BuildMode != cmd.BuildModeProd {
|
if BuildMode != cmd.BuildModeProd {
|
||||||
return a.cli.Run()
|
return a.cli.Run()
|
||||||
}
|
}
|
||||||
@@ -97,6 +102,13 @@ func (a *App) start() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start signal handler
|
||||||
|
t := tebata.New(os.Interrupt, os.Kill, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL)
|
||||||
|
t.Reserve(func() {
|
||||||
|
a.log.Debug("SIGNAL CAUGHT! Starting Shutdown")
|
||||||
|
a.renderer.Close()
|
||||||
|
})
|
||||||
|
|
||||||
// Start event manager and give it our renderer
|
// Start event manager and give it our renderer
|
||||||
a.eventManager.Start(a.renderer)
|
a.eventManager.Start(a.renderer)
|
||||||
|
|
||||||
@@ -112,8 +124,33 @@ func (a *App) start() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Defer the shutdown
|
||||||
|
defer a.shutdown()
|
||||||
|
|
||||||
// Run the renderer
|
// Run the renderer
|
||||||
return a.renderer.Run()
|
err = a.renderer.Run()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// shutdown the app
|
||||||
|
func (a *App) shutdown() {
|
||||||
|
// Make sure this is only called once
|
||||||
|
a.log.Debug("Shutting down")
|
||||||
|
|
||||||
|
// Shutdown Binding Manager
|
||||||
|
a.bindingManager.Shutdown()
|
||||||
|
|
||||||
|
// Shutdown IPC Manager
|
||||||
|
a.ipc.Shutdown()
|
||||||
|
|
||||||
|
// Shutdown Event Manager
|
||||||
|
a.eventManager.Shutdown()
|
||||||
|
|
||||||
|
a.log.Debug("Cleanly Shutdown")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind allows the user to bind the given object
|
// Bind allows the user to bind the given object
|
||||||
|
|||||||
@@ -219,6 +219,15 @@ func InstallFrontendDeps(projectDir string, projectOptions *ProjectOptions, forc
|
|||||||
|
|
||||||
const md5sumFile = "package.json.md5"
|
const md5sumFile = "package.json.md5"
|
||||||
|
|
||||||
|
// If node_modules does not exist, force a rebuild.
|
||||||
|
nodeModulesPath, err := filepath.Abs(filepath.Join(".", "node_modules"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !fs.DirExists(nodeModulesPath) {
|
||||||
|
forceRebuild = true
|
||||||
|
}
|
||||||
|
|
||||||
// If we aren't forcing the install and the md5sum file exists
|
// If we aren't forcing the install and the md5sum file exists
|
||||||
if !forceRebuild && fs.FileExists(md5sumFile) {
|
if !forceRebuild && fs.FileExists(md5sumFile) {
|
||||||
// Yes - read contents
|
// Yes - read contents
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
// Version - Wails version
|
// Version - Wails version
|
||||||
const Version = "v0.18.3"
|
const Version = "v0.18.4"
|
||||||
|
|||||||
1
go.mod
1
go.mod
@@ -22,6 +22,7 @@ require (
|
|||||||
github.com/pkg/errors v0.8.1 // indirect
|
github.com/pkg/errors v0.8.1 // indirect
|
||||||
github.com/sirupsen/logrus v1.4.1
|
github.com/sirupsen/logrus v1.4.1
|
||||||
github.com/stretchr/testify v1.3.0 // indirect
|
github.com/stretchr/testify v1.3.0 // indirect
|
||||||
|
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 // indirect
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 // indirect
|
||||||
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 // indirect
|
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 // indirect
|
||||||
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862
|
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -68,6 +68,8 @@ github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
|||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba h1:2DHfQOxcpWdGf5q5IzCUFPNvRX9Icf+09RvQK2VnJq0=
|
||||||
|
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba/go.mod h1:iLnlXG2Pakcii2CU0cbY07DRCSvpWNa7nFxtevhOChk=
|
||||||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk=
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ type Manager struct {
|
|||||||
functions map[string]*boundFunction
|
functions map[string]*boundFunction
|
||||||
internalMethods *internalMethods
|
internalMethods *internalMethods
|
||||||
initMethods []*boundMethod
|
initMethods []*boundMethod
|
||||||
|
shutdownMethods []*boundMethod
|
||||||
log *logger.CustomLogger
|
log *logger.CustomLogger
|
||||||
renderer interfaces.Renderer
|
renderer interfaces.Renderer
|
||||||
runtime interfaces.Runtime // The runtime object to pass to bound structs
|
runtime interfaces.Runtime // The runtime object to pass to bound structs
|
||||||
@@ -127,6 +128,9 @@ func (b *Manager) bindMethod(object interface{}) error {
|
|||||||
if newMethod.isWailsInit {
|
if newMethod.isWailsInit {
|
||||||
b.log.Debugf("Detected WailsInit function: %s", fullMethodName)
|
b.log.Debugf("Detected WailsInit function: %s", fullMethodName)
|
||||||
b.initMethods = append(b.initMethods, newMethod)
|
b.initMethods = append(b.initMethods, newMethod)
|
||||||
|
} else if newMethod.isWailsShutdown {
|
||||||
|
b.log.Debugf("Detected WailsShutdown function: %s", fullMethodName)
|
||||||
|
b.shutdownMethods = append(b.shutdownMethods, newMethod)
|
||||||
} else {
|
} else {
|
||||||
// Save boundMethod
|
// Save boundMethod
|
||||||
b.log.Infof("Bound Method: %s()", fullMethodName)
|
b.log.Infof("Bound Method: %s()", fullMethodName)
|
||||||
@@ -292,3 +296,13 @@ func (b *Manager) callWailsInitMethods() error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shutdown the binding manager
|
||||||
|
func (b *Manager) Shutdown() {
|
||||||
|
b.log.Debug("Shutdown called")
|
||||||
|
for _, method := range b.shutdownMethods {
|
||||||
|
b.log.Debugf("Calling Shutdown for method: %s", method.fullName)
|
||||||
|
method.call("[]")
|
||||||
|
}
|
||||||
|
b.log.Debug("Shutdown complete")
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ type boundMethod struct {
|
|||||||
log *logger.CustomLogger
|
log *logger.CustomLogger
|
||||||
hasErrorReturnType bool // Indicates if there is an error return type
|
hasErrorReturnType bool // Indicates if there is an error return type
|
||||||
isWailsInit bool
|
isWailsInit bool
|
||||||
|
isWailsShutdown bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new bound method based on the given method + type
|
// Creates a new bound method based on the given method + type
|
||||||
@@ -39,6 +40,11 @@ func newBoundMethod(name string, fullName string, method reflect.Value, objectTy
|
|||||||
err = result.processWailsInit()
|
err = result.processWailsInit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Are we a WailsShutdown method?
|
||||||
|
if result.Name == "WailsShutdown" {
|
||||||
|
err = result.processWailsShutdown()
|
||||||
|
}
|
||||||
|
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,3 +217,20 @@ func (b *boundMethod) processWailsInit() error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *boundMethod) processWailsShutdown() error {
|
||||||
|
// We must have only 1 input, it must be *wails.Runtime
|
||||||
|
if len(b.inputs) != 0 {
|
||||||
|
return fmt.Errorf("Invalid WailsShutdown() definition. Expected 0 inputs, but got %d", len(b.inputs))
|
||||||
|
}
|
||||||
|
|
||||||
|
// We must have only 1 output, it must be error
|
||||||
|
if len(b.returnTypes) != 0 {
|
||||||
|
return fmt.Errorf("Invalid WailsShutdown() definition. Expected 0 return types, but got %d", len(b.returnTypes))
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are indeed a wails Shutdown method
|
||||||
|
b.isWailsShutdown = true
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,18 +3,21 @@ package event
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/wailsapp/wails/lib/interfaces"
|
||||||
"github.com/wailsapp/wails/lib/logger"
|
"github.com/wailsapp/wails/lib/logger"
|
||||||
"github.com/wailsapp/wails/lib/messages"
|
"github.com/wailsapp/wails/lib/messages"
|
||||||
"github.com/wailsapp/wails/lib/interfaces"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Manager handles and processes events
|
// Manager handles and processes events
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
incomingEvents chan *messages.EventData
|
incomingEvents chan *messages.EventData
|
||||||
listeners map[string][]*eventListener
|
listeners map[string][]*eventListener
|
||||||
exit bool
|
running bool
|
||||||
log *logger.CustomLogger
|
log *logger.CustomLogger
|
||||||
renderer interfaces.Renderer // Messages will be dispatched to the frontend
|
renderer interfaces.Renderer // Messages will be dispatched to the frontend
|
||||||
|
wg sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewManager creates a new event manager with a 100 event buffer
|
// NewManager creates a new event manager with a 100 event buffer
|
||||||
@@ -22,7 +25,7 @@ func NewManager() interfaces.EventManager {
|
|||||||
return &Manager{
|
return &Manager{
|
||||||
incomingEvents: make(chan *messages.EventData, 100),
|
incomingEvents: make(chan *messages.EventData, 100),
|
||||||
listeners: make(map[string][]*eventListener),
|
listeners: make(map[string][]*eventListener),
|
||||||
exit: false,
|
running: false,
|
||||||
log: logger.NewCustomLogger("Events"),
|
log: logger.NewCustomLogger("Events"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,15 +90,14 @@ func (e *Manager) Start(renderer interfaces.Renderer) {
|
|||||||
// Store renderer
|
// Store renderer
|
||||||
e.renderer = renderer
|
e.renderer = renderer
|
||||||
|
|
||||||
// Set up waitgroup so we can wait for goroutine to start
|
// Set up waitgroup so we can wait for goroutine to quit
|
||||||
var wg sync.WaitGroup
|
e.running = true
|
||||||
wg.Add(1)
|
e.wg.Add(1)
|
||||||
|
|
||||||
// Run main loop in separate goroutine
|
// Run main loop in separate goroutine
|
||||||
go func() {
|
go func() {
|
||||||
wg.Done()
|
|
||||||
e.log.Info("Listening")
|
e.log.Info("Listening")
|
||||||
for e.exit == false {
|
for e.running {
|
||||||
// TODO: Listen for application exit
|
// TODO: Listen for application exit
|
||||||
select {
|
select {
|
||||||
case event := <-e.incomingEvents:
|
case event := <-e.incomingEvents:
|
||||||
@@ -139,14 +141,18 @@ func (e *Manager) Start(renderer interfaces.Renderer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
time.Sleep(1 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
e.wg.Done()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Wait for goroutine to start
|
|
||||||
wg.Wait()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Manager) stop() {
|
// Shutdown is called when exiting the Application
|
||||||
e.exit = true
|
func (e *Manager) Shutdown() {
|
||||||
|
e.log.Debug("Shutting Down")
|
||||||
|
e.running = false
|
||||||
|
e.log.Debug("Waiting for main loop to exit")
|
||||||
|
e.wg.Wait()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ type BindingManager interface {
|
|||||||
Bind(object interface{})
|
Bind(object interface{})
|
||||||
Start(renderer Renderer, runtime Runtime) error
|
Start(renderer Renderer, runtime Runtime) error
|
||||||
ProcessCall(callData *messages.CallData) (result interface{}, err error)
|
ProcessCall(callData *messages.CallData) (result interface{}, err error)
|
||||||
|
Shutdown()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ type EventManager interface {
|
|||||||
Emit(eventName string, optionalData ...interface{})
|
Emit(eventName string, optionalData ...interface{})
|
||||||
On(eventName string, callback func(...interface{}))
|
On(eventName string, callback func(...interface{}))
|
||||||
Start(Renderer)
|
Start(Renderer)
|
||||||
|
Shutdown()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ type IPCManager interface {
|
|||||||
BindRenderer(Renderer)
|
BindRenderer(Renderer)
|
||||||
Dispatch(message string)
|
Dispatch(message string)
|
||||||
Start(eventManager EventManager, bindingManager BindingManager)
|
Start(eventManager EventManager, bindingManager BindingManager)
|
||||||
|
Shutdown()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package ipc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/lib/interfaces"
|
"github.com/wailsapp/wails/lib/interfaces"
|
||||||
"github.com/wailsapp/wails/lib/logger"
|
"github.com/wailsapp/wails/lib/logger"
|
||||||
@@ -12,18 +14,20 @@ import (
|
|||||||
type Manager struct {
|
type Manager struct {
|
||||||
renderer interfaces.Renderer // The renderer
|
renderer interfaces.Renderer // The renderer
|
||||||
messageQueue chan *ipcMessage
|
messageQueue chan *ipcMessage
|
||||||
// quitChannel chan struct{}
|
quitChannel chan struct{}
|
||||||
// signals chan os.Signal
|
// signals chan os.Signal
|
||||||
log *logger.CustomLogger
|
log *logger.CustomLogger
|
||||||
eventManager interfaces.EventManager
|
eventManager interfaces.EventManager
|
||||||
bindingManager interfaces.BindingManager
|
bindingManager interfaces.BindingManager
|
||||||
|
running bool
|
||||||
|
wg sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewManager creates a new IPC Manager
|
// NewManager creates a new IPC Manager
|
||||||
func NewManager() interfaces.IPCManager {
|
func NewManager() interfaces.IPCManager {
|
||||||
result := &Manager{
|
result := &Manager{
|
||||||
messageQueue: make(chan *ipcMessage, 100),
|
messageQueue: make(chan *ipcMessage, 100),
|
||||||
// quitChannel: make(chan struct{}),
|
quitChannel: make(chan struct{}),
|
||||||
// signals: make(chan os.Signal, 1),
|
// signals: make(chan os.Signal, 1),
|
||||||
log: logger.NewCustomLogger("IPC"),
|
log: logger.NewCustomLogger("IPC"),
|
||||||
}
|
}
|
||||||
@@ -44,9 +48,12 @@ func (i *Manager) Start(eventManager interfaces.EventManager, bindingManager int
|
|||||||
|
|
||||||
i.log.Info("Starting")
|
i.log.Info("Starting")
|
||||||
// signal.Notify(manager.signals, os.Interrupt)
|
// signal.Notify(manager.signals, os.Interrupt)
|
||||||
|
i.running = true
|
||||||
|
|
||||||
|
// Keep track of this goroutine
|
||||||
|
i.wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
running := true
|
for i.running {
|
||||||
for running {
|
|
||||||
select {
|
select {
|
||||||
case incomingMessage := <-i.messageQueue:
|
case incomingMessage := <-i.messageQueue:
|
||||||
i.log.DebugFields("Processing message", logger.Fields{
|
i.log.DebugFields("Processing message", logger.Fields{
|
||||||
@@ -117,15 +124,12 @@ func (i *Manager) Start(eventManager interfaces.EventManager, bindingManager int
|
|||||||
i.log.DebugFields("Finished processing message", logger.Fields{
|
i.log.DebugFields("Finished processing message", logger.Fields{
|
||||||
"1D": &incomingMessage,
|
"1D": &incomingMessage,
|
||||||
})
|
})
|
||||||
// case <-manager.quitChannel:
|
default:
|
||||||
// Debug("[MessageQueue] Quit caught")
|
time.Sleep(1 * time.Millisecond)
|
||||||
// running = false
|
|
||||||
// case <-manager.signals:
|
|
||||||
// Debug("[MessageQueue] Signal caught")
|
|
||||||
// running = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i.log.Debug("Stopping")
|
i.log.Debug("Stopping")
|
||||||
|
i.wg.Done()
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,3 +171,11 @@ func (i *Manager) SendResponse(response *ipcResponse) error {
|
|||||||
// Call back to the front end
|
// Call back to the front end
|
||||||
return i.renderer.Callback(data)
|
return i.renderer.Callback(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shutdown is called when exiting the Application
|
||||||
|
func (i *Manager) Shutdown() {
|
||||||
|
i.log.Debug("Shutdown called")
|
||||||
|
i.running = false
|
||||||
|
i.log.Debug("Waiting of main loop shutdown")
|
||||||
|
i.wg.Wait()
|
||||||
|
}
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ func (h *Bridge) Run() error {
|
|||||||
h.log.Info("The frontend will connect automatically.")
|
h.log.Info("The frontend will connect automatically.")
|
||||||
|
|
||||||
err := h.server.ListenAndServe()
|
err := h.server.ListenAndServe()
|
||||||
if err != nil {
|
if err != nil && err != http.ErrServerClosed {
|
||||||
h.log.Fatal(err.Error())
|
h.log.Fatal(err.Error())
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@@ -250,5 +250,9 @@ func (h *Bridge) SetTitle(title string) {
|
|||||||
// Close is unsupported for Bridge but required
|
// Close is unsupported for Bridge but required
|
||||||
// for the Renderer interface
|
// for the Renderer interface
|
||||||
func (h *Bridge) Close() {
|
func (h *Bridge) Close() {
|
||||||
h.log.Warn("Close() unsupported in bridge mode")
|
h.log.Debug("Shutting down")
|
||||||
|
err := h.server.Close()
|
||||||
|
if err != nil {
|
||||||
|
h.log.Errorf(err.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
package webview
|
package webview
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#cgo linux openbsd freebsd CFLAGS: -DWEBVIEW_GTK=1
|
#cgo linux openbsd freebsd CFLAGS: -DWEBVIEW_GTK=1 -Wno-deprecated-declarations
|
||||||
#cgo linux openbsd freebsd pkg-config: gtk+-3.0 webkit2gtk-4.0
|
#cgo linux openbsd freebsd pkg-config: gtk+-3.0 webkit2gtk-4.0
|
||||||
|
|
||||||
#cgo windows CFLAGS: -DWEBVIEW_WINAPI=1
|
#cgo windows CFLAGS: -DWEBVIEW_WINAPI=1
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ struct webview_priv
|
|||||||
NSAutoreleasePool *pool;
|
NSAutoreleasePool *pool;
|
||||||
NSWindow *window;
|
NSWindow *window;
|
||||||
WebView *webview;
|
WebView *webview;
|
||||||
id windowDelegate;
|
id delegate;
|
||||||
int should_exit;
|
int should_exit;
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
@@ -1894,6 +1894,22 @@ struct webview_priv
|
|||||||
[script setValue:self forKey:@"external"];
|
[script setValue:self forKey:@"external"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void webview_run_input_open_panel(id self, SEL cmd, id webview,
|
||||||
|
id listener, BOOL allowMultiple) {
|
||||||
|
char filename[256] = "";
|
||||||
|
struct webview *w =
|
||||||
|
(struct webview *)objc_getAssociatedObject(self, "webview");
|
||||||
|
|
||||||
|
webview_dialog(w, WEBVIEW_DIALOG_TYPE_OPEN, WEBVIEW_DIALOG_FLAG_FILE, "", "",
|
||||||
|
filename, 255);
|
||||||
|
if (strlen(filename)) {
|
||||||
|
[listener chooseFilename:[NSString stringWithUTF8String:filename]];
|
||||||
|
} else {
|
||||||
|
[listener cancel];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void webview_external_invoke(id self, SEL cmd, id arg)
|
static void webview_external_invoke(id self, SEL cmd, id arg)
|
||||||
{
|
{
|
||||||
struct webview *w =
|
struct webview *w =
|
||||||
@@ -1927,12 +1943,17 @@ struct webview_priv
|
|||||||
class_addMethod(webViewDelegateClass,
|
class_addMethod(webViewDelegateClass,
|
||||||
sel_registerName("webView:didClearWindowObject:forFrame:"),
|
sel_registerName("webView:didClearWindowObject:forFrame:"),
|
||||||
(IMP)webview_did_clear_window_object, "v@:@@@");
|
(IMP)webview_did_clear_window_object, "v@:@@@");
|
||||||
|
class_addMethod(
|
||||||
|
webViewDelegateClass,
|
||||||
|
sel_registerName("webView:runOpenPanelForFileButtonWithResultListener:"
|
||||||
|
"allowMultipleFiles:"),
|
||||||
|
(IMP)webview_run_input_open_panel, "v@:@@c");
|
||||||
class_addMethod(webViewDelegateClass, sel_registerName("invoke:"),
|
class_addMethod(webViewDelegateClass, sel_registerName("invoke:"),
|
||||||
(IMP)webview_external_invoke, "v@:@");
|
(IMP)webview_external_invoke, "v@:@");
|
||||||
objc_registerClassPair(webViewDelegateClass);
|
objc_registerClassPair(webViewDelegateClass);
|
||||||
|
|
||||||
w->priv.windowDelegate = [[webViewDelegateClass alloc] init];
|
w->priv.delegate = [[webViewDelegateClass alloc] init];
|
||||||
objc_setAssociatedObject(w->priv.windowDelegate, "webview", (id)(w),
|
objc_setAssociatedObject(w->priv.delegate, "webview", (id)(w),
|
||||||
OBJC_ASSOCIATION_ASSIGN);
|
OBJC_ASSOCIATION_ASSIGN);
|
||||||
|
|
||||||
NSRect r = NSMakeRect(0, 0, w->width, w->height);
|
NSRect r = NSMakeRect(0, 0, w->width, w->height);
|
||||||
@@ -1960,7 +1981,7 @@ struct webview_priv
|
|||||||
NSString *nsTitle = [NSString stringWithUTF8String:w->title];
|
NSString *nsTitle = [NSString stringWithUTF8String:w->title];
|
||||||
[w->priv.window setTitle:nsTitle];
|
[w->priv.window setTitle:nsTitle];
|
||||||
|
|
||||||
[w->priv.window setDelegate:w->priv.windowDelegate];
|
[w->priv.window setDelegate:w->priv.delegate];
|
||||||
[w->priv.window center];
|
[w->priv.window center];
|
||||||
|
|
||||||
// NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"wat"];
|
// NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"wat"];
|
||||||
@@ -1989,7 +2010,8 @@ struct webview_priv
|
|||||||
[w->priv.webview setAutoresizesSubviews:YES];
|
[w->priv.webview setAutoresizesSubviews:YES];
|
||||||
[w->priv.webview
|
[w->priv.webview
|
||||||
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||||
w->priv.webview.frameLoadDelegate = w->priv.windowDelegate;
|
w->priv.webview.frameLoadDelegate = w->priv.delegate;
|
||||||
|
w->priv.webview.UIDelegate = w->priv.delegate;
|
||||||
[[w->priv.window contentView] addSubview:w->priv.webview];
|
[[w->priv.window contentView] addSubview:w->priv.webview];
|
||||||
[w->priv.window orderFrontRegardless];
|
[w->priv.window orderFrontRegardless];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user