energy/cef/application.go

389 lines
14 KiB
Go
Raw Normal View History

2022-10-04 13:21:05 +08:00
//----------------------------------------
//
// Copyright © yanghy. All Rights Reserved.
//
// Licensed under Apache License Version 2.0, January 2004
//
// https://www.apache.org/licenses/LICENSE-2.0
2022-10-04 13:21:05 +08:00
//
//----------------------------------------
// Package cef All CEF implementations of Energy in Go
2022-10-04 13:21:05 +08:00
package cef
import (
"github.com/energye/energy/v2/cef/internal/cef"
"github.com/energye/energy/v2/cef/internal/def"
2023-05-31 18:00:34 +08:00
"github.com/energye/energy/v2/cef/process"
"github.com/energye/energy/v2/common/imports"
. "github.com/energye/energy/v2/consts"
"github.com/energye/energy/v2/logger"
2022-12-13 11:49:32 +08:00
"github.com/energye/golcl/lcl"
2022-10-04 13:21:05 +08:00
"github.com/energye/golcl/lcl/api"
"unsafe"
)
var application *TCEFApplication
2023-02-28 18:41:12 +08:00
// TCEFApplication CEF应用对象
2022-10-04 13:21:05 +08:00
type TCEFApplication struct {
2022-12-04 18:27:20 +08:00
instance unsafe.Pointer
2022-10-04 13:21:05 +08:00
}
2023-02-28 18:41:12 +08:00
// NewApplication 创建CEF应用
//
// 参数: disableRegisDefaultEvent = true 时不会注册默认事件
func NewApplication(disableRegisDefaultEvent ...bool) *TCEFApplication {
if application == nil {
2023-06-12 22:24:03 +08:00
application = CreateApplication()
2023-02-28 18:41:12 +08:00
if len(disableRegisDefaultEvent) == 0 || !disableRegisDefaultEvent[0] {
application.registerDefaultEvent()
}
2023-03-05 16:17:40 +08:00
application.initDefaultSettings()
// 将应用设置到内部实现
cef.SetApplication(application)
2022-10-04 13:21:05 +08:00
}
return application
2022-12-15 23:13:27 +08:00
}
2023-06-12 22:24:03 +08:00
func CreateApplication() *TCEFApplication {
var result uintptr
imports.Proc(def.CEFApplication_Create).Call(uintptr(unsafe.Pointer(&result)))
return &TCEFApplication{instance: unsafe.Pointer(result)}
}
2023-02-28 18:41:12 +08:00
// AddCrDelegate MacOSX Delegate
func (m *TCEFApplication) AddCrDelegate() {
imports.Proc(def.CEF_AddCrDelegate).Call()
2022-12-15 23:13:27 +08:00
}
2023-02-28 18:41:12 +08:00
//registerDefaultEvent 注册默认事件
2022-12-15 23:13:27 +08:00
func (m *TCEFApplication) registerDefaultEvent() {
m.defaultSetOnContextCreated()
m.defaultSetOnProcessMessageReceived()
2023-03-14 11:19:09 +08:00
m.defaultSetOnRenderLoadStart()
2023-03-14 11:06:08 +08:00
//m.defaultSetOnBeforeChildProcessLaunch()
2023-03-23 21:34:56 +08:00
m.defaultSetOnWebKitInitialized()
2022-10-04 13:21:05 +08:00
}
2023-02-28 18:41:12 +08:00
// Instance 实例
2022-12-04 18:27:20 +08:00
func (m *TCEFApplication) Instance() uintptr {
return uintptr(m.instance)
}
2023-05-31 17:41:14 +08:00
// StartMainProcess 启动主进程
2022-10-04 13:21:05 +08:00
func (m *TCEFApplication) StartMainProcess() bool {
2023-03-24 09:11:32 +08:00
if m.instance != nil {
2023-03-25 11:38:56 +08:00
v8init()
2023-05-31 17:41:14 +08:00
logger.Debug("application single exe,", process.Args.ProcessType(), "process start")
r1, _, _ := imports.Proc(def.CEFStartMainProcess).Call(m.Instance())
2022-12-15 23:13:27 +08:00
return api.GoBool(r1)
2022-10-04 13:21:05 +08:00
}
return false
}
2023-02-28 18:41:12 +08:00
// StartSubProcess 启动子进程, 如果指定了子进程执行程序, 将执行指定的子进程程序
2022-12-09 21:08:30 +08:00
func (m *TCEFApplication) StartSubProcess() (result bool) {
2023-03-24 09:11:32 +08:00
if m.instance != nil {
2023-03-25 11:38:56 +08:00
v8init()
2023-05-31 17:41:14 +08:00
logger.Debug("application multiple exe,", process.Args.ProcessType(), "process start")
r1, _, _ := imports.Proc(def.CEFStartSubProcess).Call(m.Instance())
2022-12-09 21:08:30 +08:00
result = api.GoBool(r1)
2022-10-04 13:21:05 +08:00
}
return false
}
2023-05-31 17:41:14 +08:00
// RunMessageLoop
2022-12-15 23:13:27 +08:00
func (m *TCEFApplication) RunMessageLoop() {
2023-02-06 15:25:28 +08:00
defer func() {
2023-03-14 11:06:08 +08:00
logger.Debug("application run value loop end")
2023-02-06 15:25:28 +08:00
api.EnergyLibRelease()
}()
2023-03-14 11:06:08 +08:00
logger.Debug("application run value loop start")
imports.Proc(def.CEFApplication_RunMessageLoop).Call()
2022-12-15 23:13:27 +08:00
}
2023-02-28 18:41:12 +08:00
// QuitMessageLoop 退出消息轮询
2022-12-27 21:38:01 +08:00
func (m *TCEFApplication) QuitMessageLoop() {
2023-03-14 11:06:08 +08:00
logger.Debug("application quit value loop")
imports.Proc(def.CEFApplication_QuitMessageLoop).Call()
2022-12-27 21:38:01 +08:00
}
2022-12-09 21:08:30 +08:00
func (m *TCEFApplication) StopScheduler() {
2023-06-21 08:39:51 +08:00
GlobalWorkScheduler.StopScheduler()
2022-12-09 21:08:30 +08:00
}
func (m *TCEFApplication) Destroy() {
imports.Proc(def.CEFApplication_Destroy).Call()
2022-12-09 21:08:30 +08:00
}
2022-10-04 13:21:05 +08:00
func (m *TCEFApplication) Free() {
2023-03-24 09:11:32 +08:00
if m.instance != nil {
imports.Proc(def.CEFApplication_Free).Call()
2023-03-24 09:11:32 +08:00
m.instance = nil
2022-10-04 13:21:05 +08:00
}
}
2023-03-14 11:06:08 +08:00
func (m *TCEFApplication) AddCustomCommandLine(commandLine, value string) {
imports.Proc(def.AddCustomCommandLine).Call(api.PascalStr(commandLine), api.PascalStr(value))
2023-03-14 11:06:08 +08:00
}
func (m *TCEFApplication) SetOnRegCustomSchemes(fn GlobalCEFAppEventOnRegCustomSchemes) {
imports.Proc(def.CEFGlobalApp_SetOnRegCustomSchemes).Call(api.MakeEventDataPtr(fn))
2023-03-14 11:06:08 +08:00
}
2023-05-31 17:41:14 +08:00
// TODO TCefPreferenceRegistrarRef
2023-03-14 11:06:08 +08:00
func (m *TCEFApplication) SetOnRegisterCustomPreferences(fn GlobalCEFAppEventOnRegisterCustomPreferences) {
imports.Proc(def.CEFGlobalApp_SetOnRegisterCustomPreferences).Call(api.MakeEventDataPtr(fn))
2023-03-14 11:06:08 +08:00
}
func (m *TCEFApplication) SetOnContextInitialized(fn GlobalCEFAppEventOnContextInitialized) {
imports.Proc(def.CEFGlobalApp_SetOnContextInitialized).Call(api.MakeEventDataPtr(fn))
2023-03-14 11:06:08 +08:00
}
// 启动子进程之前自定义命令行参数设置
func (m *TCEFApplication) SetOnBeforeChildProcessLaunch(fn GlobalCEFAppEventOnBeforeChildProcessLaunch) {
imports.Proc(def.CEFGlobalApp_SetOnBeforeChildProcessLaunch).Call(api.MakeEventDataPtr(fn))
2023-03-14 11:06:08 +08:00
}
func (m *TCEFApplication) SetOnGetDefaultClient(fn GlobalCEFAppEventOnGetDefaultClient) {
imports.Proc(def.CEFGlobalApp_SetOnGetDefaultClient).Call(api.MakeEventDataPtr(fn))
2023-03-14 11:06:08 +08:00
}
func (m *TCEFApplication) SetOnGetLocalizedString(fn GlobalCEFAppEventOnGetLocalizedString) {
imports.Proc(def.CEFGlobalApp_SetOnGetLocalizedString).Call(api.MakeEventDataPtr(fn))
2023-03-14 11:06:08 +08:00
}
func (m *TCEFApplication) SetOnGetDataResource(fn GlobalCEFAppEventOnGetDataResource) {
imports.Proc(def.CEFGlobalApp_SetOnGetDataResource).Call(api.MakeEventDataPtr(fn))
2023-03-14 11:06:08 +08:00
}
func (m *TCEFApplication) SetOnGetDataResourceForScale(fn GlobalCEFAppEventOnGetDataResourceForScale) {
imports.Proc(def.CEFGlobalApp_SetOnGetDataResourceForScale).Call(api.MakeEventDataPtr(fn))
2023-03-14 11:06:08 +08:00
}
func (m *TCEFApplication) SetOnWebKitInitialized(fn GlobalCEFAppEventOnWebKitInitialized) {
imports.Proc(def.CEFGlobalApp_SetOnWebKitInitialized).Call(api.MakeEventDataPtr(fn))
2023-03-14 11:06:08 +08:00
}
2023-03-23 21:34:56 +08:00
func (m *TCEFApplication) defaultSetOnWebKitInitialized() {
m.SetOnWebKitInitialized(func() {})
}
2023-03-14 11:06:08 +08:00
func (m *TCEFApplication) SetOnBrowserCreated(fn GlobalCEFAppEventOnBrowserCreated) {
imports.Proc(def.CEFGlobalApp_SetOnBrowserCreated).Call(api.MakeEventDataPtr(fn))
2023-03-14 11:06:08 +08:00
}
func (m *TCEFApplication) SetOnBrowserDestroyed(fn GlobalCEFAppEventOnBrowserDestroyed) {
imports.Proc(def.CEFGlobalApp_SetOnBrowserDestroyed).Call(api.MakeEventDataPtr(fn))
2023-03-14 11:06:08 +08:00
}
2022-10-04 13:21:05 +08:00
func (m *TCEFApplication) SetOnContextCreated(fn GlobalCEFAppEventOnContextCreated) {
imports.Proc(def.CEFGlobalApp_SetOnContextCreated).Call(api.MakeEventDataPtr(fn))
2022-10-04 13:21:05 +08:00
}
2022-12-05 10:44:24 +08:00
2022-10-04 13:21:05 +08:00
func (m *TCEFApplication) defaultSetOnContextCreated() {
m.SetOnContextCreated(func(browse *ICefBrowser, frame *ICefFrame, context *ICefV8Context) bool {
return false
})
}
2023-03-14 11:06:08 +08:00
func (m *TCEFApplication) SetOnContextReleased(fn GlobalCEFAppEventOnContextReleased) {
imports.Proc(def.CEFGlobalApp_SetOnContextReleased).Call(api.MakeEventDataPtr(fn))
2023-03-13 22:40:20 +08:00
}
2023-03-14 11:06:08 +08:00
func (m *TCEFApplication) SetOnUncaughtException(fn GlobalCEFAppEventOnUncaughtException) {
imports.Proc(def.CEFGlobalApp_SetOnUncaughtException).Call(api.MakeEventDataPtr(fn))
2022-12-15 23:13:27 +08:00
}
2023-03-14 11:06:08 +08:00
func (m *TCEFApplication) SetOnFocusedNodeChanged(fn GlobalCEFAppEventOnFocusedNodeChanged) {
imports.Proc(def.CEFGlobalApp_SetOnFocusedNodeChanged).Call(api.MakeEventDataPtr(fn))
2022-10-04 13:21:05 +08:00
}
2023-02-06 15:25:28 +08:00
// 进程间通信处理消息接收
2022-10-04 13:21:05 +08:00
func (m *TCEFApplication) SetOnProcessMessageReceived(fn RenderProcessMessageReceived) {
imports.Proc(def.CEFGlobalApp_SetOnProcessMessageReceived).Call(api.MakeEventDataPtr(fn))
2022-10-04 13:21:05 +08:00
}
2023-03-14 11:06:08 +08:00
2022-10-04 13:21:05 +08:00
func (m *TCEFApplication) defaultSetOnProcessMessageReceived() {
2023-02-26 21:17:28 +08:00
m.SetOnProcessMessageReceived(func(browse *ICefBrowser, frame *ICefFrame, sourceProcess CefProcessId, processMessage *ICefProcessMessage) bool {
2022-10-04 13:21:05 +08:00
return false
})
}
2023-03-14 11:06:08 +08:00
//func (m *TCEFApplication) defaultSetOnBeforeChildProcessLaunch() {
// m.SetOnBeforeChildProcessLaunch(func(commandLine *TCefCommandLine) {})
//}
2022-10-04 13:21:05 +08:00
2023-03-13 22:40:20 +08:00
//func (m *TCEFApplication) SetOnScheduleMessagePumpWork(fn ) {
// imports.Proc(CEFGlobalApp_SetOnScheduleMessagePumpWork).Call(api.MakeEventDataPtr(fn))
2023-03-13 22:40:20 +08:00
//}
2023-03-14 11:06:08 +08:00
func (m *TCEFApplication) SetOnRenderLoadingStateChange(fn GlobalCEFAppEventOnRenderLoadingStateChange) {
imports.Proc(def.CEFGlobalApp_SetOnRenderLoadingStateChange).Call(api.MakeEventDataPtr(fn))
2022-10-04 13:21:05 +08:00
}
2023-03-13 22:40:20 +08:00
func (m *TCEFApplication) SetOnRenderLoadStart(fn GlobalCEFAppEventOnRenderLoadStart) {
imports.Proc(def.CEFGlobalApp_SetOnRenderLoadStart).Call(api.MakeEventDataPtr(fn))
2022-10-04 13:21:05 +08:00
}
2023-03-14 11:19:09 +08:00
func (m *TCEFApplication) defaultSetOnRenderLoadStart() {
m.SetOnRenderLoadStart(func(browser *ICefBrowser, frame *ICefFrame, transitionType TCefTransitionType) {
})
}
2023-03-13 22:40:20 +08:00
func (m *TCEFApplication) SetOnRenderLoadEnd(fn GlobalCEFAppEventOnRenderLoadEnd) {
imports.Proc(def.CEFGlobalApp_SetOnRenderLoadEnd).Call(api.MakeEventDataPtr(fn))
}
2023-03-13 22:40:20 +08:00
func (m *TCEFApplication) SetOnRenderLoadError(fn GlobalCEFAppEventOnRenderLoadError) {
imports.Proc(def.CEFGlobalApp_SetOnRenderLoadError).Call(api.MakeEventDataPtr(fn))
2023-03-13 22:40:20 +08:00
}
2023-06-12 16:53:26 +08:00
func (m *TCEFApplication) SetOnScheduleMessagePumpWork(fn GlobalCEFAppEventOnScheduleMessagePumpWork) {
2023-06-12 13:01:51 +08:00
var callback uintptr
if fn != nil {
callback = api.MakeEventDataPtr(fn)
}
imports.Proc(def.CEFGlobalApp_SetOnScheduleMessagePumpWork).Call(callback)
}
2022-12-13 11:49:32 +08:00
func init() {
2023-03-15 17:06:01 +08:00
//var renderLock sync.Mutex
2022-12-13 11:49:32 +08:00
lcl.RegisterExtEventCallback(func(fn interface{}, getVal func(idx int) uintptr) bool {
getPtr := func(i int) unsafe.Pointer {
return unsafe.Pointer(getVal(i))
}
switch fn.(type) {
2023-03-14 11:06:08 +08:00
case GlobalCEFAppEventOnRegCustomSchemes:
fn.(GlobalCEFAppEventOnRegCustomSchemes)(&TCefSchemeRegistrarRef{instance: getPtr(0)})
case GlobalCEFAppEventOnRegisterCustomPreferences:
fn.(GlobalCEFAppEventOnRegisterCustomPreferences)(TCefPreferencesType(getVal(0)), &TCefPreferenceRegistrarRef{instance: getPtr(1)})
case GlobalCEFAppEventOnContextInitialized:
fn.(GlobalCEFAppEventOnContextInitialized)()
case GlobalCEFAppEventOnBeforeChildProcessLaunch:
//commands := (*uintptr)(getPtr(0))
//commandLine := &TCefCommandLine{commandLines: make(map[string]string)}
2023-05-31 17:41:14 +08:00
fn.(GlobalCEFAppEventOnBeforeChildProcessLaunch)(&ICefCommandLine{instance: getPtr(0)})
2023-03-14 11:06:08 +08:00
//*commands = api.PascalStr(commandLine.toString())
case GlobalCEFAppEventOnGetDefaultClient:
client := (*uintptr)(getPtr(0))
getClient := &ICefClient{instance: unsafe.Pointer(client)}
fn.(GlobalCEFAppEventOnGetDefaultClient)(getClient)
*client = uintptr(getClient.instance)
case GlobalCEFAppEventOnGetLocalizedString:
stringVal := (*uintptr)(getPtr(1))
result := (*bool)(getPtr(2))
resultStringVal := &ResultString{}
resultBool := &ResultBool{}
fn.(GlobalCEFAppEventOnGetLocalizedString)(int32(getVal(0)), resultStringVal, resultBool)
if resultStringVal.Value() != "" {
*stringVal = api.PascalStr(resultStringVal.Value())
} else {
*stringVal = 0
}
*result = resultBool.Value()
case GlobalCEFAppEventOnGetDataResource:
resultBytes := &ResultBytes{}
resultData := (*uintptr)(getPtr(1))
resultDataSize := (*uint32)(getPtr(2))
result := (*bool)(getPtr(3))
resultBool := &ResultBool{}
fn.(GlobalCEFAppEventOnGetDataResource)(int32(getVal(0)), resultBytes, resultBool)
*result = resultBool.Value()
if resultBytes.Value() != nil {
*resultData = uintptr(unsafe.Pointer(&resultBytes.Value()[0]))
*resultDataSize = uint32(len(resultBytes.Value()))
} else {
*resultData = 0
*resultDataSize = 0
}
case GlobalCEFAppEventOnGetDataResourceForScale:
resultBytes := &ResultBytes{}
resultData := (*uintptr)(getPtr(2))
resultDataSize := (*uint32)(getPtr(3))
result := (*bool)(getPtr(4))
resultBool := &ResultBool{}
fn.(GlobalCEFAppEventOnGetDataResourceForScale)(int32(getVal(0)), TCefScaleFactor(getVal(1)), resultBytes, resultBool)
*result = resultBool.Value()
if resultBytes.Value() != nil {
*resultData = uintptr(unsafe.Pointer(&resultBytes.Value()[0]))
*resultDataSize = uint32(len(resultBytes.Value()))
} else {
*resultData = 0
*resultDataSize = 0
}
case GlobalCEFAppEventOnWebKitInitialized:
fn.(GlobalCEFAppEventOnWebKitInitialized)()
2023-03-23 21:34:56 +08:00
appWebKitInitialized()
2023-03-14 11:06:08 +08:00
case GlobalCEFAppEventOnBrowserCreated:
fn.(GlobalCEFAppEventOnBrowserCreated)(&ICefBrowser{instance: getPtr(0)}, &ICefDictionaryValue{instance: getPtr(1)})
2022-12-13 11:49:32 +08:00
case GlobalCEFAppEventOnBrowserDestroyed:
2023-02-26 19:14:49 +08:00
fn.(GlobalCEFAppEventOnBrowserDestroyed)(&ICefBrowser{instance: getPtr(0)})
2023-03-14 11:06:08 +08:00
case GlobalCEFAppEventOnContextCreated:
browse := &ICefBrowser{instance: getPtr(0)}
frame := &ICefFrame{instance: getPtr(1)}
ctx := &ICefV8Context{instance: getPtr(2)}
var result = fn.(GlobalCEFAppEventOnContextCreated)(browse, frame, ctx)
if !result {
appOnContextCreated(browse, frame, ctx)
}
case GlobalCEFAppEventOnContextReleased:
browse := &ICefBrowser{instance: getPtr(0)}
frame := &ICefFrame{instance: getPtr(1)}
ctx := &ICefV8Context{instance: getPtr(2)}
fn.(GlobalCEFAppEventOnContextReleased)(browse, frame, ctx)
case GlobalCEFAppEventOnUncaughtException:
browse := &ICefBrowser{instance: getPtr(0)}
frame := &ICefFrame{instance: getPtr(1)}
ctx := &ICefV8Context{instance: getPtr(2)}
v8Exception := &ICefV8Exception{instance: getPtr(3)}
v8StackTrace := &ICefV8StackTrace{instance: getPtr(3)}
fn.(GlobalCEFAppEventOnUncaughtException)(browse, frame, ctx, v8Exception, v8StackTrace)
case GlobalCEFAppEventOnFocusedNodeChanged:
browse := &ICefBrowser{instance: getPtr(0)}
frame := &ICefFrame{instance: getPtr(1)}
node := &ICefDomNode{instance: getPtr(2)}
fn.(GlobalCEFAppEventOnFocusedNodeChanged)(browse, frame, node)
case GlobalCEFAppEventOnRenderLoadingStateChange:
browse := &ICefBrowser{instance: getPtr(0)}
frame := &ICefFrame{instance: getPtr(1)}
fn.(GlobalCEFAppEventOnRenderLoadingStateChange)(browse, frame, api.GoBool(getVal(2)), api.GoBool(getVal(3)), api.GoBool(getVal(4)))
2022-12-13 11:49:32 +08:00
case GlobalCEFAppEventOnRenderLoadStart:
2023-03-15 11:05:09 +08:00
if ipcRender != nil {
ipcRender.clear()
}
2023-03-13 12:07:31 +08:00
browse := &ICefBrowser{instance: getPtr(0)}
2023-02-26 19:14:49 +08:00
frame := &ICefFrame{instance: getPtr(1)}
2023-03-13 12:07:31 +08:00
fn.(GlobalCEFAppEventOnRenderLoadStart)(browse, frame, TCefTransitionType(getVal(2)))
2022-12-13 11:49:32 +08:00
case GlobalCEFAppEventOnRenderLoadEnd:
2023-03-13 12:07:31 +08:00
browse := &ICefBrowser{instance: getPtr(0)}
2023-03-09 19:27:00 +08:00
frame := &ICefFrame{instance: getPtr(1)}
2023-03-13 12:07:31 +08:00
fn.(GlobalCEFAppEventOnRenderLoadEnd)(browse, frame, int32(getVal(2)))
2022-12-13 11:49:32 +08:00
case GlobalCEFAppEventOnRenderLoadError:
2023-03-13 12:07:31 +08:00
browse := &ICefBrowser{instance: getPtr(0)}
2023-03-09 19:27:00 +08:00
frame := &ICefFrame{instance: getPtr(1)}
2023-03-13 12:07:31 +08:00
fn.(GlobalCEFAppEventOnRenderLoadError)(browse, frame, TCefErrorCode(getVal(2)), api.GoStr(getVal(3)), api.GoStr(getVal(4)))
2022-12-13 11:49:32 +08:00
case RenderProcessMessageReceived:
2023-03-13 12:07:31 +08:00
browse := &ICefBrowser{instance: getPtr(0)}
2023-03-09 19:27:00 +08:00
frame := &ICefFrame{instance: getPtr(1)}
2023-03-03 12:52:00 +08:00
processId := CefProcessId(getVal(2))
2023-03-04 17:12:22 +08:00
message := &ICefProcessMessage{instance: getPtr(3)}
2022-12-13 11:49:32 +08:00
var result = (*bool)(getPtr(4))
2023-05-31 17:41:14 +08:00
*result = renderProcessMessageReceived(browse, frame, processId, message)
2023-03-03 12:52:00 +08:00
if !*result {
2023-05-31 17:41:14 +08:00
*result = fn.(RenderProcessMessageReceived)(browse, frame, processId, message)
2023-03-03 12:52:00 +08:00
}
2023-03-21 13:18:44 +08:00
frame.Free()
browse.Free()
2023-03-04 17:12:22 +08:00
message.Free()
2023-06-12 13:01:51 +08:00
case GlobalCEFAppEventOnScheduleMessagePumpWork:
fn.(GlobalCEFAppEventOnScheduleMessagePumpWork)(*(*int64)(getPtr(0)))
2022-12-13 11:49:32 +08:00
default:
return false
}
return true
})
}