energy/cef/cef-browser-window.go

610 lines
17 KiB
Go
Raw Normal View History

2022-10-04 13:21:05 +08:00
//----------------------------------------
//
// Copyright © yanghy. All Rights Reserved.
//
2022-10-04 16:38:43 +08:00
// Licensed under GNU General Public License v3.0
2022-10-04 13:21:05 +08:00
//
//----------------------------------------
package cef
import (
. "github.com/energye/energy/common"
2022-10-04 22:34:57 +08:00
. "github.com/energye/energy/consts"
2022-12-15 23:13:27 +08:00
"github.com/energye/energy/ipc"
2022-10-26 16:48:32 +08:00
"github.com/energye/energy/logger"
2022-10-04 13:21:05 +08:00
"github.com/energye/golcl/lcl"
2022-12-30 21:23:33 +08:00
"github.com/energye/golcl/lcl/api"
2022-10-04 13:21:05 +08:00
"sync"
)
var (
2022-10-05 16:38:43 +08:00
//1. BrowserWindow 是基于 BaseWindow 浏览器主窗口
//
//2. 可以对窗口的属性设置和事件监听chromium 的配置和事件监听
//
//3. 该窗口是主窗体,因此初始化时必须第一个初始化完成,如果创建子窗口最好在 SetBrowserInitAfter 回调函数中创建
2022-10-04 13:21:05 +08:00
BrowserWindow = &browser{
2022-11-23 15:40:23 +08:00
mainBrowserWindow: &browserWindow{},
browserEvent: &BrowserEvent{},
2022-11-18 22:50:44 +08:00
Config: &browserConfig{
WindowProperty: *NewWindowProperty(),
2022-11-18 22:50:44 +08:00
},
windowInfo: make(map[int32]*LCLBrowserWindow),
2022-11-18 22:50:44 +08:00
windowSerial: 1,
uiLock: new(sync.Mutex),
2022-10-04 13:21:05 +08:00
}
browserProcessStartAfterCallback browserProcessStartAfterCallbackFunc
2022-10-04 13:21:05 +08:00
)
type browserProcessStartAfterCallbackFunc func(b bool)
// SetBrowserProcessStartAfterCallback 主进程启动之后回调函数
func SetBrowserProcessStartAfterCallback(callback browserProcessStartAfterCallbackFunc) {
if Args.IsMain() {
if browserProcessStartAfterCallback == nil {
browserProcessStartAfterCallback = callback
}
}
}
2022-10-04 13:21:05 +08:00
// 浏览器包装结构体
type browser struct {
mainBrowserWindow *browserWindow //主浏览器窗口
popupWindow *LCLBrowserWindow //弹出的子窗口
browserEvent *BrowserEvent //浏览器全局事件
Config *browserConfig //浏览器和窗口配置
windowInfo map[int32]*LCLBrowserWindow //窗口信息集合
windowSerial int32 //窗口序号
2022-11-23 15:40:23 +08:00
uiLock *sync.Mutex
2022-10-04 13:21:05 +08:00
}
// 浏览器全局事件监听
//
// 在主浏览器进程调用
type BrowserEvent struct {
2022-12-15 23:13:27 +08:00
chromium IChromiumEvent //chromium event
onBeforePopup ChromiumEventOnBeforePopupForWindowInfo //default
onAfterCreated ChromiumEventOnAfterCreated //default
onBeforeBrowser ChromiumEventOnBeforeBrowser //default
onBeforeClose ChromiumEventOnBeforeClose //default
onClose ChromiumEventOnClose //default
onFrameCreated ChromiumEventOnFrameCreated //default
onFrameDetached ChromiumEventOnFrameDetached //default
onMainFrameChanged ChromiumEventOnMainFrameChanged //default
onBeforeDownload ChromiumEventOnBeforeDownload //default
onKeyEvent ChromiumEventOnKeyEvent //default
onProcessMessageReceived BrowseProcessMessageReceived //default
onTitleChange ChromiumEventOnTitleChange //default
onLoadingStateChange ChromiumEventOnLoadingStateChange //default
onContextMenuCommand ChromiumEventOnContextMenuCommand //default
onBeforeContextMenu ChromiumEventOnBeforeContextMenu //default
onBeforeResourceLoad ChromiumEventOnBeforeResourceLoad //default
2022-10-04 13:21:05 +08:00
}
2022-10-26 16:25:59 +08:00
type browserWindow struct {
LCLBrowserWindow
2022-10-04 13:21:05 +08:00
isFirstActivate bool
tray ITray
}
// 运行应用
//
2022-10-05 16:38:43 +08:00
// 多进程方式启动主进程然后启动子进程在MacOS下需要单独调用启动子进程函数单进程只启动主进程
//
2022-11-23 15:40:23 +08:00
// 主进程启动成功之后,将创建主窗口 mainBrowserWindow 是一个默认的主窗口
2022-10-05 16:38:43 +08:00
//
// externalMessagePump和multiThreadedMessageLoop是false时启用 ViewsFrameworkBrowserWindow 窗口
//
2022-10-04 13:21:05 +08:00
// 在这里启动浏览器的主进程和子进程
func Run(cefApp *TCEFApplication) {
if IsDarwin() && !SingleProcess && !Args.IsMain() {
// mac os 启动子进程
cefApp.StartSubProcess()
2022-12-09 21:08:30 +08:00
cefApp.Free()
2022-10-04 13:21:05 +08:00
} else {
IsMessageLoop = !api.GoBool(cefApp.cfg.externalMessagePump) && !api.GoBool(cefApp.cfg.multiThreadedMessageLoop)
if IsMessageLoop {
BrowserWindow.mainBrowserWindow.appContextInitialized(cefApp)
2022-12-15 23:13:27 +08:00
}
success := cefApp.StartMainProcess()
if browserProcessStartAfterCallback != nil {
browserProcessStartAfterCallback(success)
}
if success {
internalBrowserIPCOnEventInit()
ipc.IPC.StartBrowserIPC()
bindGoToJS(nil, nil)
if IsMessageLoop {
2022-12-30 21:23:33 +08:00
cefApp.RunMessageLoop()
} else {
lcl.RunApp(&BrowserWindow.mainBrowserWindow)
}
2022-10-04 13:21:05 +08:00
}
}
}
2022-10-26 16:25:59 +08:00
func (m *browserWindow) OnFormCreate(sender lcl.IObject) {
2022-10-04 13:21:05 +08:00
if BrowserWindow.Config.chromiumConfig == nil {
BrowserWindow.Config.chromiumConfig = NewChromiumConfig()
BrowserWindow.Config.chromiumConfig.SetEnableMenu(true)
BrowserWindow.Config.chromiumConfig.SetEnableDevTools(true)
BrowserWindow.Config.chromiumConfig.SetEnableOpenUrlTab(true)
BrowserWindow.Config.chromiumConfig.SetEnableWindowPopup(true)
}
2022-10-30 00:35:04 +08:00
m.SetWindowType(WT_MAIN_BROWSER)
2022-10-04 13:21:05 +08:00
m.FormCreate()
m.defaultWindowEvent()
m.defaultWindowCloseEvent()
m.ChromiumCreate(BrowserWindow.Config.chromiumConfig, BrowserWindow.Config.Url)
2022-10-04 13:21:05 +08:00
m.putChromiumWindowInfo()
m.defaultChromiumEvent()
m.AddOnCloseQuery(func(sender lcl.IObject, canClose *bool) bool {
if m.tray != nil {
m.tray.close()
}
return false
})
if BrowserWindow.Config.Title != "" {
m.SetCaption(BrowserWindow.Config.Title)
}
if BrowserWindow.Config.IconFS != "" {
lcl.Application.Icon().LoadFromFSFile(BrowserWindow.Config.IconFS)
2022-11-23 15:40:23 +08:00
}
2022-10-04 13:21:05 +08:00
m.SetWidth(BrowserWindow.Config.Width)
m.SetHeight(BrowserWindow.Config.Height)
if BrowserWindow.Config.browserWindowOnEventCallback != nil {
BrowserWindow.browserEvent.chromium = m.chromium
BrowserWindow.Config.browserWindowOnEventCallback(BrowserWindow.browserEvent, &m.LCLBrowserWindow)
2022-10-04 13:21:05 +08:00
}
//主进程(主窗口)启动后回调函数事件
//主窗体第一次激活之后执行一次
m.SetOnActivateAfter(func(sender lcl.IObject) {
if !m.isFirstActivate {
m.isFirstActivate = true
if BrowserWindow.Config.browserWindowAfterOnEventCallback != nil {
BrowserWindow.Config.browserWindowAfterOnEventCallback(&m.LCLBrowserWindow)
2022-10-04 13:21:05 +08:00
}
}
})
}
func (m *browser) MainWindow() *LCLBrowserWindow {
return &m.mainBrowserWindow.LCLBrowserWindow
2022-10-04 13:21:05 +08:00
}
// 基于CEF views framework窗口 - 主窗口和chromium初始化时回调
//
// 当使用ViewsFramework创建窗口后我们无法使用lcl创建组件到窗口中
//
// ViewsFramework窗口主要解决在linux下gtk2和gtk3共存以及无法输入中文问题
//
// ViewsFramework窗口 和 LCL窗口同时只能存在一种
//
// event 浏览器事件
//
// views framework window 窗口信息对象
func (m *browser) SetViewFrameBrowserInit(fn viewsFrameBrowserWindowOnEventCallback) {
m.Config.setViewsFrameBrowserWindowOnEventCallback(fn)
}
// 基于LCL窗口 - 主窗口和chromium初始化时回调
2022-10-04 13:21:05 +08:00
//
2022-10-05 16:38:43 +08:00
// 在这里可以对主窗体事件监听和属性设置,和主窗口上的子组件创建
2022-10-04 13:21:05 +08:00
//
2022-10-05 16:38:43 +08:00
// 如果想创建子窗口或带有browser的窗口最好在 SetBrowserInitAfter 回调函数中创建
//
// event 浏览器事件
//
// browserWindow 窗口信息对象
func (m *browser) SetBrowserInit(fn browserWindowOnEventCallback) {
2022-10-05 16:38:43 +08:00
m.Config.setBrowserWindowInitOnEvent(fn)
}
// 基于LCL窗口 - 主窗体和chromium初始后回调
2022-10-05 16:38:43 +08:00
//
// 在这里可以对主窗体属性设置、添加子窗口、带有browser的窗口和子组件创建
//
2022-11-23 15:40:23 +08:00
// mainBrowserWindow 窗口信息对象
func (m *browser) SetBrowserInitAfter(fn browserWindowAfterOnEventCallback) {
2022-10-04 13:21:05 +08:00
m.Config.setBrowserWindowInitAfterOnEvent(fn)
}
2022-10-26 16:48:32 +08:00
// 设置或增加一个窗口序号
func (m *browser) setOrIncNextWindowNum(browserId ...int32) int32 {
if len(browserId) > 0 {
m.windowSerial = browserId[0]
} else {
m.windowSerial++
}
logger.Debug("next window serial:", m.windowSerial)
return m.windowSerial
}
// 设置或减少一个窗口序号
func (m *browser) setOrDecNextWindowNum(browserId ...int32) int32 {
if len(browserId) > 0 {
m.windowSerial = browserId[0]
} else {
m.windowSerial--
}
return m.windowSerial
}
// 获得窗口序号
func (m *browser) GetNextWindowNum() int32 {
return m.windowSerial
}
func (m *browser) createNextPopupWindow() {
m.popupWindow = &LCLBrowserWindow{}
m.popupWindow.TForm = lcl.NewForm(m.MainWindow())
2022-10-26 16:48:32 +08:00
m.popupWindow.FormCreate()
m.popupWindow.defaultWindowEvent()
m.popupWindow.defaultWindowCloseEvent()
}
// 拿到窗口信息
func (m *browser) GetWindowInfo(browserId int32) *LCLBrowserWindow {
2022-10-26 16:48:32 +08:00
if winInfo, ok := m.windowInfo[browserId]; ok {
return winInfo
}
return nil
}
func (m *browser) GetWindowsInfo() map[int32]*LCLBrowserWindow {
2022-10-26 16:48:32 +08:00
return m.windowInfo
}
func (m *browser) putWindowInfo(browserId int32, windowInfo *LCLBrowserWindow) {
m.windowInfo[browserId] = windowInfo
2022-10-04 13:21:05 +08:00
}
2022-10-26 16:48:32 +08:00
func (m *browser) removeWindowInfo(browseId int32) {
delete(m.windowInfo, browseId)
RemoveGoForm(browseId)
2022-10-26 16:48:32 +08:00
}
func (m *browser) GetBrowser(browseId int32) *ICefBrowser {
if winInfo, ok := m.windowInfo[browseId]; ok {
return winInfo.browser
2022-10-04 13:21:05 +08:00
}
2022-10-26 16:48:32 +08:00
return nil
2022-10-04 13:21:05 +08:00
}
2022-10-26 16:48:32 +08:00
func (m *browser) putBrowserFrame(browser *ICefBrowser, frame *ICefFrame) {
if winInfo, ok := m.windowInfo[browser.Identifier()]; ok {
if winInfo.frames == nil {
winInfo.frames = make(TCEFFrame)
2022-10-26 16:48:32 +08:00
}
winInfo.browser = browser
winInfo.frames[frame.Id] = frame
2022-10-26 16:48:32 +08:00
}
}
func (m *browser) GetFrames(browseId int32) map[int64]*ICefFrame {
if winInfo, ok := m.windowInfo[browseId]; ok {
return winInfo.frames
2022-10-26 16:48:32 +08:00
}
return nil
}
func (m *browser) GetFrame(browseId int32, frameId int64) *ICefFrame {
if winInfo, ok := m.windowInfo[browseId]; ok {
return winInfo.frames[frameId]
2022-10-26 16:48:32 +08:00
}
return nil
}
func (m *browser) RemoveFrame(browseId int32, frameId int64) {
if winInfo, ok := m.windowInfo[browseId]; ok {
delete(winInfo.frames, frameId)
2022-10-26 16:48:32 +08:00
}
}
func (m *browser) IsSameFrame(browseId int32, frameId int64) bool {
if frame := m.GetFrame(browseId, frameId); frame != nil {
return true
}
return false
}
func (m *browser) removeNoValidFrames() {
for _, winInfo := range m.windowInfo {
for _, frm := range winInfo.frames {
2022-10-26 16:48:32 +08:00
if !frm.IsValid() {
delete(winInfo.frames, frm.Id)
2022-10-26 16:48:32 +08:00
}
}
2022-10-04 13:21:05 +08:00
}
}
// BrowserEvent.SetOnAfterCreated
func (m *BrowserEvent) SetOnAfterCreated(event ChromiumEventOnAfterCreated) {
if Args.IsMain() {
m.onAfterCreated = event
}
}
// BrowserEvent.SetOnBeforeBrowser
func (m *BrowserEvent) SetOnBeforeBrowser(event ChromiumEventOnBeforeBrowser) {
if Args.IsMain() {
m.onBeforeBrowser = event
}
}
2022-10-25 12:38:06 +08:00
// BrowserEvent.SetOnAddressChange
func (m *BrowserEvent) SetOnAddressChange(event ChromiumEventOnAddressChange) {
if Args.IsMain() {
m.chromium.SetOnAddressChange(event)
}
}
2022-10-04 13:21:05 +08:00
// BrowserEvent.SetOnBeforeClose
func (m *BrowserEvent) SetOnBeforeClose(event ChromiumEventOnBeforeClose) {
if Args.IsMain() {
m.onBeforeClose = event
}
}
// BrowserEvent.SetOnClose
func (m *BrowserEvent) SetOnClose(event ChromiumEventOnClose) {
if Args.IsMain() {
m.onClose = event
}
}
// BrowserEvent.SetOnPdfPrintFinished
func (m *BrowserEvent) SetOnPdfPrintFinished(event ChromiumEventOnResult) {
if Args.IsMain() {
m.chromium.SetOnPdfPrintFinished(event)
}
}
// BrowserEvent.SetOnZoomPctAvailable
func (m *BrowserEvent) SetOnZoomPctAvailable(event ChromiumEventOnResultFloat) {
if Args.IsMain() {
m.chromium.SetOnZoomPctAvailable(event)
}
}
// BrowserEvent.SetOnLoadStart
func (m *BrowserEvent) SetOnLoadStart(event ChromiumEventOnLoadStart) {
if Args.IsMain() {
m.chromium.SetOnLoadStart(event)
}
}
// BrowserEvent.SetOnLoadingStateChange
func (m *BrowserEvent) SetOnLoadingStateChange(event ChromiumEventOnLoadingStateChange) {
if Args.IsMain() {
m.onLoadingStateChange = event
}
}
// BrowserEvent.SetOnLoadingProgressChange
func (m *BrowserEvent) SetOnLoadingProgressChange(event ChromiumEventOnLoadingProgressChange) {
if Args.IsMain() {
m.chromium.SetOnLoadingProgressChange(event)
}
}
// BrowserEvent.SetOnLoadError
func (m *BrowserEvent) SetOnLoadError(event ChromiumEventOnLoadError) {
if Args.IsMain() {
m.chromium.SetOnLoadError(event)
}
}
// BrowserEvent.SetOnLoadEnd
func (m *BrowserEvent) SetOnLoadEnd(event ChromiumEventOnLoadEnd) {
if Args.IsMain() {
m.chromium.SetOnLoadEnd(event)
}
}
// BrowserEvent.SetOnBeforeDownload
func (m *BrowserEvent) SetOnBeforeDownload(event ChromiumEventOnBeforeDownload) {
if Args.IsMain() {
m.onBeforeDownload = event
}
}
// BrowserEvent.SetOnDownloadUpdated
func (m *BrowserEvent) SetOnDownloadUpdated(event ChromiumEventOnDownloadUpdated) {
if Args.IsMain() {
m.chromium.SetOnDownloadUpdated(event)
}
}
// BrowserEvent.SetOnFullScreenModeChange
func (m *BrowserEvent) SetOnFullScreenModeChange(event ChromiumEventOnFullScreenModeChange) {
if Args.IsMain() {
m.chromium.SetOnFullScreenModeChange(event)
}
}
// BrowserEvent.SetOnKeyEvent
func (m *BrowserEvent) SetOnKeyEvent(event ChromiumEventOnKeyEvent) {
if Args.IsMain() {
m.onKeyEvent = event
}
}
// BrowserEvent.SetOnTitleChange
func (m *BrowserEvent) SetOnTitleChange(event ChromiumEventOnTitleChange) {
if Args.IsMain() {
m.onTitleChange = event
}
}
// BrowserEvent.SetOnRenderCompMsg
func (m *BrowserEvent) SetOnRenderCompMsg(event ChromiumEventOnRenderCompMsg) {
if Args.IsMain() {
m.chromium.SetOnRenderCompMsg(event)
}
}
// BrowserEvent.SetOnRenderProcessTerminated
func (m *BrowserEvent) SetOnRenderProcessTerminated(event ChromiumEventOnRenderProcessTerminated) {
if Args.IsMain() {
m.chromium.SetOnRenderProcessTerminated(event)
}
}
// BrowserEvent.SetOnRenderViewReady
func (m *BrowserEvent) SetOnRenderViewReady(event ChromiumEventOnCefBrowser) {
if Args.IsMain() {
m.chromium.SetOnRenderViewReady(event)
}
}
// BrowserEvent.SetOnScrollOffsetChanged
func (m *BrowserEvent) SetOnScrollOffsetChanged(event ChromiumEventOnScrollOffsetChanged) {
if Args.IsMain() {
m.chromium.SetOnScrollOffsetChanged(event)
}
}
// BrowserEvent.SetOnBrowseProcessMessageReceived
func (m *BrowserEvent) SetOnBrowseProcessMessageReceived(event BrowseProcessMessageReceived) {
if Args.IsMain() {
m.onProcessMessageReceived = event
}
}
// BrowserEvent.SetOnBeforeResourceLoad
func (m *BrowserEvent) SetOnBeforeResourceLoad(event ChromiumEventOnBeforeResourceLoad) {
if Args.IsMain() {
m.onBeforeResourceLoad = event
2022-10-04 13:21:05 +08:00
}
}
// BrowserEvent.SetOnResourceResponse
func (m *BrowserEvent) SetOnResourceResponse(event ChromiumEventOnResourceResponse) {
if Args.IsMain() {
m.chromium.SetOnResourceResponse(event)
}
}
// BrowserEvent.SetOnResourceRedirect
func (m *BrowserEvent) SetOnResourceRedirect(event ChromiumEventOnResourceRedirect) {
if Args.IsMain() {
m.chromium.SetOnResourceRedirect(event)
}
}
// BrowserEvent.SetOnResourceLoadComplete
func (m *BrowserEvent) SetOnResourceLoadComplete(event ChromiumEventOnResourceLoadComplete) {
if Args.IsMain() {
m.chromium.SetOnResourceLoadComplete(event)
}
}
// BrowserEvent.SetOnCookieSet
func (m *BrowserEvent) SetOnCookieSet(event ChromiumEventOnCookieSet) {
if Args.IsMain() {
m.chromium.SetOnCookieSet(event)
}
}
// BrowserEvent.SetOnCookiesDeleted
func (m *BrowserEvent) SetOnCookiesDeleted(event ChromiumEventOnCookiesDeleted) {
if Args.IsMain() {
m.chromium.SetOnCookiesDeleted(event)
}
}
// BrowserEvent.SetOnCookiesFlushed
func (m *BrowserEvent) SetOnCookiesFlushed(event ChromiumEventOnCookiesFlushed) {
if Args.IsMain() {
m.chromium.SetOnCookiesFlushed(event)
}
}
// BrowserEvent.SetOnCookiesVisited
func (m *BrowserEvent) SetOnCookiesVisited(event ChromiumEventOnCookiesVisited) {
if Args.IsMain() {
m.chromium.SetOnCookiesVisited(event)
}
}
// BrowserEvent.SetOnCookieVisitorDestroyed
func (m *BrowserEvent) SetOnCookieVisitorDestroyed(event ChromiumEventOnCookieVisitorDestroyed) {
if Args.IsMain() {
m.chromium.SetOnCookieVisitorDestroyed(event)
}
}
// BrowserEvent.SetOnBeforeContextMenu
func (m *BrowserEvent) SetOnBeforeContextMenu(event ChromiumEventOnBeforeContextMenu) {
if Args.IsMain() {
m.onBeforeContextMenu = event
}
}
// BrowserEvent.SetOnContextMenuCommand
func (m *BrowserEvent) SetOnContextMenuCommand(event ChromiumEventOnContextMenuCommand) {
if Args.IsMain() {
m.onContextMenuCommand = event
}
}
// BrowserEvent.SetOnContextMenuDismissed
func (m *BrowserEvent) SetOnContextMenuDismissed(event ChromiumEventOnContextMenuDismissed) {
if Args.IsMain() {
m.chromium.SetOnContextMenuDismissed(event)
}
}
// BrowserEvent.SetOnFrameAttached
func (m *BrowserEvent) SetOnFrameAttached(event ChromiumEventOnFrameAttached) {
if Args.IsMain() {
m.chromium.SetOnFrameAttached(event)
}
}
// BrowserEvent.SetOnFrameCreated
func (m *BrowserEvent) SetOnFrameCreated(event ChromiumEventOnFrameCreated) {
if Args.IsMain() {
m.onFrameCreated = event
}
}
// BrowserEvent.SetOnFrameDetached
func (m *BrowserEvent) SetOnFrameDetached(event ChromiumEventOnFrameDetached) {
if Args.IsMain() {
m.onFrameDetached = event
}
}
// BrowserEvent.SetOnMainFrameChanged
func (m *BrowserEvent) SetOnMainFrameChanged(event ChromiumEventOnMainFrameChanged) {
if Args.IsMain() {
m.onMainFrameChanged = event
}
}
// BrowserEvent.SetOnBeforePopup
//
// 子窗口弹出之前,设置子窗口样式及系统组件和功能
2022-12-15 23:13:27 +08:00
func (m *BrowserEvent) SetOnBeforePopup(event ChromiumEventOnBeforePopupForWindowInfo) {
2022-10-04 13:21:05 +08:00
if Args.IsMain() {
m.onBeforePopup = event
}
}
// BrowserEvent.SetOnOpenUrlFromTab
func (m *BrowserEvent) SetOnOpenUrlFromTab(event ChromiumEventOnOpenUrlFromTab) {
if Args.IsMain() {
m.chromium.SetOnOpenUrlFromTab(event)
}
}
func (m *BrowserEvent) SetOnFindResult(event ChromiumEventOnFindResult) {
if Args.IsMain() {
m.chromium.SetOnFindResult(event)
}
}