energy/cef/cef-browser-window-lcl.go

1018 lines
27 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
//
//----------------------------------------
2023-02-20 00:20:01 +08:00
// LCL窗口组件定义和实现
2022-10-04 13:21:05 +08:00
package cef
import (
"fmt"
. "github.com/energye/energy/common"
"github.com/energye/energy/common/assetserve"
"github.com/energye/energy/consts"
2022-10-04 22:34:57 +08:00
"github.com/energye/energy/logger"
"github.com/energye/golcl/energy/emfs"
"github.com/energye/golcl/energy/tools"
2022-10-04 13:21:05 +08:00
"github.com/energye/golcl/lcl"
"github.com/energye/golcl/lcl/api"
"github.com/energye/golcl/lcl/rtl"
2022-10-04 13:21:05 +08:00
"github.com/energye/golcl/lcl/types"
"time"
2022-10-04 13:21:05 +08:00
)
// LCLBrowserWindow 基于CEF lcl 窗口组件
//
// 该窗口使用CEF和LCL组件实现CEF<=1.106.xx版本 在windows、MacOSX可正常使用, Linux无法输入中文, CEF>=2.107.xx版本linux强制使用 ViewsFrameworkBrowserWindow 窗口组件
type LCLBrowserWindow struct {
*lcl.TForm //
chromium IChromium //
windowParent ITCefWindowParent //
windowProperty *WindowProperty //
windowId int32 //
windowType consts.WINDOW_TYPE //窗口类型
isClosing bool //
canClose bool //
onResize TNotifyEvent //
windowResize TNotifyEvent //
onActivate TNotifyEvent //
onShow TNotifyEvent //
onClose TCloseEvent //
onCloseQuery TCloseQueryEvent //
onActivateAfter lcl.TNotifyEvent //
isFormCreate bool //是否创建完成 WindowForm
isChromiumCreate bool //是否创建完成 Chromium
auxTools *auxTools //辅助工具
tray ITray //托盘
hWnd types.HWND //
cwcap *customWindowCaption //自定义窗口标题栏
2022-10-04 13:21:05 +08:00
}
// 创建一个 LCL 带有 chromium 窗口
2022-10-04 13:21:05 +08:00
//
// 该窗口默认不具备默认事件处理能力, 通过 EnableDefaultEvent 函数注册事件处理
func NewLCLBrowserWindow(config *tCefChromiumConfig, windowProperty WindowProperty, owner ...lcl.IComponent) *LCLBrowserWindow {
var window = NewLCLWindow(windowProperty, owner...)
window.ChromiumCreate(config, windowProperty.Url)
2022-10-04 13:21:05 +08:00
window.putChromiumWindowInfo()
//OnBeforeBrowser 是一个必须的默认事件在浏览器创建时窗口序号会根据browserId生成
window.Chromium().SetOnBeforeBrowser(func(sender lcl.IObject, browser *ICefBrowser, frame *ICefFrame) bool {
chromiumOnBeforeBrowser(browser, frame)
return false
})
2022-10-04 13:21:05 +08:00
return window
}
// 创建一个LCL window窗口
func NewLCLWindow(windowProperty WindowProperty, owner ...lcl.IComponent) *LCLBrowserWindow {
var window = &LCLBrowserWindow{}
if len(owner) > 0 {
window.TForm = lcl.NewForm(owner[0])
} else {
window.TForm = lcl.NewForm(BrowserWindow.mainBrowserWindow)
//lcl.Application.CreateForm(&window)
}
window.windowProperty = &windowProperty
window.cwcap = &customWindowCaption{
bw: window,
}
window.SetWindowType(windowProperty.WindowType)
window.SetDoubleBuffered(true)
window.FormCreate()
window.SetShowInTaskBar()
window.defaultWindowEvent()
window.setProperty()
return window
}
// 设置属性
func (m *LCLBrowserWindow) setProperty() {
m.SetTitle(m.windowProperty.Title)
if m.windowProperty.IconFS != "" {
if emfs.IsExist(m.windowProperty.IconFS) {
_ = lcl.Application.Icon().LoadFromFSFile(m.windowProperty.IconFS)
}
} else if m.windowProperty.Icon != "" {
if tools.IsExist(m.windowProperty.Icon) {
lcl.Application.Icon().LoadFromFile(m.windowProperty.Icon)
}
}
if m.windowProperty.EnableCenterWindow {
m.SetSize(m.windowProperty.Width, m.windowProperty.Height)
m.SetPosition(types.PoDesktopCenter)
} else {
m.SetPosition(types.PoDesigned)
m.SetBounds(m.windowProperty.X, m.windowProperty.Y, m.windowProperty.Width, m.windowProperty.Height)
}
if m.windowProperty.AlwaysOnTop {
m.SetFormStyle(types.FsSystemStayOnTop)
}
if m.windowProperty.EnableHideCaption {
m.HideTitle()
} else {
if !m.windowProperty.EnableMinimize {
m.DisableMinimize()
}
if !m.windowProperty.EnableMaximize {
m.DisableMaximize()
}
if !m.windowProperty.EnableResize {
m.SetBorderStyle(types.BsSingle)
}
}
}
2023-02-20 00:20:01 +08:00
// Handle 窗口句柄
func (m *LCLBrowserWindow) Handle() types.HWND {
if m.hWnd == 0 {
m.hWnd = m.TForm.Handle()
}
return m.hWnd
}
2023-02-20 00:20:01 +08:00
// BrowserWindow 返回LCL窗口组件实现
func (m *LCLBrowserWindow) BrowserWindow() *LCLBrowserWindow {
return m
}
2023-02-20 00:20:01 +08:00
// AsViewsFrameworkBrowserWindow 转换为VF窗口组件这里返回nil
func (m *LCLBrowserWindow) AsViewsFrameworkBrowserWindow() IViewsFrameworkBrowserWindow {
return nil
}
2023-02-20 00:20:01 +08:00
// AsLCLBrowserWindow 转换为LCL窗口组件这里返回LCL窗口组件
func (m *LCLBrowserWindow) AsLCLBrowserWindow() ILCLBrowserWindow {
return m
}
2023-02-20 00:20:01 +08:00
// SetCenterWindow
func (m *LCLBrowserWindow) SetCenterWindow(value bool) {
if m.TForm == nil {
return
}
if value {
m.SetPosition(types.PoDesktopCenter)
} else {
m.SetPosition(types.PoDesigned)
}
}
2023-02-20 00:20:01 +08:00
// Close 关闭窗口 非browser窗口使用
func (m *LCLBrowserWindow) Close() {
if m.TForm == nil {
return
}
m.TForm.Close()
}
2023-02-20 00:20:01 +08:00
// SetTitle 设置窗口标题栏标题
func (m *LCLBrowserWindow) SetTitle(title string) {
if m.TForm == nil {
return
}
2023-02-03 09:02:43 +08:00
m.WindowProperty().Title = title
m.TForm.SetCaption(title)
}
2023-02-20 00:20:01 +08:00
// SetWidth 设置窗口宽
func (m *LCLBrowserWindow) SetWidth(value int32) {
if m.TForm == nil {
return
}
2023-02-03 09:02:43 +08:00
m.WindowProperty().Width = value
m.TForm.SetWidth(value)
}
2023-02-20 00:20:01 +08:00
// SetHeight 设置窗口高
func (m *LCLBrowserWindow) SetHeight(value int32) {
if m.TForm == nil {
return
}
2023-02-03 09:02:43 +08:00
m.WindowProperty().Height = value
m.TForm.SetHeight(value)
}
2023-02-20 00:20:01 +08:00
// Point 窗口坐标
func (m *LCLBrowserWindow) Point() *TCefPoint {
if m.TForm == nil {
return nil
}
result := &TCefPoint{
X: m.Left(),
Y: m.Top(),
}
m.WindowProperty().X = result.X
m.WindowProperty().Y = result.Y
return result
}
2023-02-20 00:20:01 +08:00
// Size 窗口宽高
func (m *LCLBrowserWindow) Size() *TCefSize {
if m.TForm == nil {
return nil
}
result := &TCefSize{
Width: m.Width(),
Height: m.Height(),
}
m.WindowProperty().Width = result.Width
m.WindowProperty().Height = result.Height
return result
}
2023-02-20 00:20:01 +08:00
// Bounds 窗口坐标和宽高
func (m *LCLBrowserWindow) Bounds() *TCefRect {
if m.TForm == nil {
return nil
}
rect := m.BoundsRect()
result := &TCefRect{
X: rect.Left,
Y: rect.Top,
Width: rect.Width(),
Height: rect.Height(),
}
m.WindowProperty().X = result.X
m.WindowProperty().Y = result.Y
m.WindowProperty().Width = result.Width
m.WindowProperty().Height = result.Height
return result
}
2023-02-20 00:20:01 +08:00
// SetPoint 设置窗口坐标
func (m *LCLBrowserWindow) SetPoint(x, y int32) {
if m.TForm == nil {
return
}
2023-02-03 09:02:43 +08:00
m.WindowProperty().X = x
m.WindowProperty().Y = y
m.TForm.SetLeft(x)
m.TForm.SetTop(y)
}
2023-02-20 00:20:01 +08:00
// SetSize 设置窗口宽高
func (m *LCLBrowserWindow) SetSize(width, height int32) {
if m.TForm == nil {
return
}
2023-02-03 09:02:43 +08:00
m.WindowProperty().Width = width
m.WindowProperty().Height = height
m.SetWidth(width)
m.SetHeight(height)
}
2023-02-20 00:20:01 +08:00
// SetBounds 设置窗口坐标和宽高
func (m *LCLBrowserWindow) SetBounds(x, y, width, height int32) {
if m.TForm == nil {
return
}
2023-02-03 09:02:43 +08:00
m.WindowProperty().X = x
m.WindowProperty().Y = y
m.WindowProperty().Width = width
m.WindowProperty().Height = height
m.TForm.SetBounds(x, y, width, height)
}
2023-02-20 00:20:01 +08:00
// getAuxTools
func (m *LCLBrowserWindow) getAuxTools() *auxTools {
return m.auxTools
}
2023-02-20 00:20:01 +08:00
// createAuxTools
func (m *LCLBrowserWindow) createAuxTools() {
if m.auxTools == nil {
m.auxTools = &auxTools{}
}
}
2023-02-20 00:20:01 +08:00
// Browser
func (m *LCLBrowserWindow) Browser() *ICefBrowser {
2023-02-26 19:14:49 +08:00
if m == nil || m.Chromium() == nil || !m.Chromium().Initialized() {
return nil
}
2023-02-26 19:14:49 +08:00
return m.Chromium().Browser()
}
2023-02-20 00:20:01 +08:00
// Chromium
func (m *LCLBrowserWindow) Chromium() IChromium {
return m.chromium
}
2023-02-20 00:20:01 +08:00
// Id
func (m *LCLBrowserWindow) Id() int32 {
return m.windowId
}
2023-02-20 00:20:01 +08:00
// Show
func (m *LCLBrowserWindow) Show() {
if m.TForm == nil {
return
}
2022-10-04 13:21:05 +08:00
m.TForm.Show()
}
2023-02-20 00:20:01 +08:00
// Hide
func (m *LCLBrowserWindow) Hide() {
if m.TForm == nil {
return
}
2022-10-04 13:21:05 +08:00
m.TForm.Hide()
}
2023-02-20 00:20:01 +08:00
// WindowState 返回窗口最小化、最大化、全屏状态
func (m *LCLBrowserWindow) WindowState() types.TWindowState {
if m.TForm == nil {
return -1
}
return m.TForm.WindowState()
}
// Visible
func (m *LCLBrowserWindow) Visible() bool {
if m.TForm == nil {
return false
}
2022-10-04 13:21:05 +08:00
return m.TForm.Visible()
}
2023-02-20 00:20:01 +08:00
// SetVisible
func (m *LCLBrowserWindow) SetVisible(value bool) {
if m.TForm == nil {
return
}
2022-10-04 13:21:05 +08:00
m.TForm.SetVisible(value)
}
2023-02-20 00:20:01 +08:00
// SetDefaultInTaskBar 以默认的方式展示在任务栏上
func (m *LCLBrowserWindow) SetDefaultInTaskBar() {
if m.TForm == nil {
return
}
2022-10-04 13:21:05 +08:00
m.TForm.SetShowInTaskBar(types.StDefault)
}
2023-02-20 00:20:01 +08:00
// SetShowInTaskBar 展示在任务栏上
func (m *LCLBrowserWindow) SetShowInTaskBar() {
if m.TForm == nil {
return
}
2022-10-04 13:21:05 +08:00
m.TForm.SetShowInTaskBar(types.StAlways)
}
2023-02-20 00:20:01 +08:00
// SetNotInTaskBar 不会展示在任务栏上
func (m *LCLBrowserWindow) SetNotInTaskBar() {
if m.TForm == nil {
return
}
2022-10-04 13:21:05 +08:00
m.TForm.SetShowInTaskBar(types.StNever)
}
2023-02-20 00:20:01 +08:00
// WindowParent
// 返回chromium的父组件对象该对象不是window组件对象,属于window的一个子组件
2022-10-25 12:38:06 +08:00
//
// 在windows下它是 TCEFWindowParent, linux或macOSx下它是 TCEFLinkedWindowParent
2022-10-25 12:38:06 +08:00
//
// 通过函数可调整该组件的属性
func (m *LCLBrowserWindow) WindowParent() ITCefWindowParent {
2022-10-04 13:21:05 +08:00
return m.windowParent
}
2023-02-20 00:20:01 +08:00
// IsClosing 返回窗口是否正在关闭/或已关闭 true正在或已关闭
func (m *LCLBrowserWindow) IsClosing() bool {
2022-10-04 13:21:05 +08:00
return m.isClosing
}
2023-02-20 00:20:01 +08:00
// SetWindowType 设置窗口类型
func (m *LCLBrowserWindow) SetWindowType(windowType consts.WINDOW_TYPE) {
2022-10-04 13:21:05 +08:00
m.windowType = windowType
}
2023-02-20 00:20:01 +08:00
// WindowType 返回窗口类型
func (m *LCLBrowserWindow) WindowType() consts.WINDOW_TYPE {
2022-11-01 17:18:46 +08:00
return m.windowType
}
2023-02-20 00:20:01 +08:00
// ChromiumCreate
2022-10-26 17:26:25 +08:00
// 创建window浏览器组件
2022-10-04 13:21:05 +08:00
//
// 不带有默认事件的chromium
func (m *LCLBrowserWindow) ChromiumCreate(config *tCefChromiumConfig, defaultUrl string) {
2022-10-04 13:21:05 +08:00
if m.isChromiumCreate {
return
}
m.isChromiumCreate = true
m.windowId = BrowserWindow.GetNextWindowNum()
if config == nil {
config = NewChromiumConfig()
}
m.chromium = NewChromium(m, config)
m.chromium.SetEnableMultiBrowserMode(true)
if defaultUrl != "" {
m.chromium.SetDefaultURL(defaultUrl)
}
//windowParent
m.windowParent = NewCEFWindow(m)
m.windowParent.SetParent(m)
m.windowParent.SetAlign(types.AlClient)
m.windowParent.SetAnchors(types.NewSet(types.AkTop, types.AkLeft, types.AkRight, types.AkBottom))
m.windowParent.SetChromium(m.chromium, 0)
m.windowParent.SetOnEnter(func(sender lcl.IObject) {
if m.isClosing {
return
}
m.chromium.Initialized()
m.chromium.FrameIsFocused()
m.chromium.SetFocus(true)
})
m.windowParent.SetOnExit(func(sender lcl.IObject) {
if m.isClosing {
return
}
m.chromium.SendCaptureLostEvent()
})
}
2023-02-20 00:20:01 +08:00
// WindowProperty 部分提供部分窗口属性设置
func (m *LCLBrowserWindow) WindowProperty() *WindowProperty {
return m.windowProperty
}
2023-02-20 00:20:01 +08:00
// putChromiumWindowInfo
func (m *LCLBrowserWindow) putChromiumWindowInfo() {
BrowserWindow.putWindowInfo(m.windowId, m)
2022-10-04 13:21:05 +08:00
}
2023-02-20 00:20:01 +08:00
// defaultChromiumEvent 默认的chromium事件
func (m *LCLBrowserWindow) defaultChromiumEvent() {
if m.WindowType() != consts.WT_DEV_TOOLS {
AddGoForm(m.windowId, m.Instance())
m.registerPopupEvent()
2022-10-04 13:21:05 +08:00
m.registerDefaultEvent()
m.registerDefaultChromiumCloseEvent()
}
}
2023-02-20 00:20:01 +08:00
// FormCreate
2022-10-04 13:21:05 +08:00
// 创建窗口
//
// 不带有默认事件的窗口
func (m *LCLBrowserWindow) FormCreate() {
2022-10-04 13:21:05 +08:00
if m.isFormCreate {
return
}
m.isFormCreate = true
m.SetName(fmt.Sprintf("energy_window_name_%d", time.Now().UnixNano()/1e6))
2022-10-04 13:21:05 +08:00
}
2023-02-20 00:20:01 +08:00
// defaultWindowEvent 默认窗口活动/关闭处理事件
func (m *LCLBrowserWindow) defaultWindowEvent() {
if m.WindowType() != consts.WT_DEV_TOOLS {
m.TForm.SetOnActivate(m.activate)
2022-10-04 13:21:05 +08:00
}
m.TForm.SetOnResize(m.resize)
m.TForm.SetOnShow(m.show)
2022-10-04 13:21:05 +08:00
}
2023-02-20 00:20:01 +08:00
// defaultWindowCloseEvent 默认的窗口关闭事件
func (m *LCLBrowserWindow) defaultWindowCloseEvent() {
m.TForm.SetOnClose(m.close)
m.TForm.SetOnCloseQuery(m.closeQuery)
2022-10-04 13:21:05 +08:00
}
2023-02-20 00:20:01 +08:00
// EnableDefaultCloseEvent 启用默认关闭事件行为-该窗口将被关闭
func (m *LCLBrowserWindow) EnableDefaultCloseEvent() {
m.defaultWindowCloseEvent()
m.registerDefaultChromiumCloseEvent()
}
2023-02-20 00:20:01 +08:00
// EnableAllDefaultEvent 启用所有默认事件行为
func (m *LCLBrowserWindow) EnableAllDefaultEvent() {
m.defaultWindowCloseEvent()
m.defaultChromiumEvent()
}
// SetOnResize 事件,不会覆盖默认事件返回值false继续执行默认事件, true跳过默认事件
func (m *LCLBrowserWindow) SetOnResize(fn TNotifyEvent) {
m.onResize = fn
2022-10-04 13:21:05 +08:00
}
// SetOnActivate 事件,不会覆盖默认事件返回值false继续执行默认事件, true跳过默认事件
func (m *LCLBrowserWindow) SetOnActivate(fn TNotifyEvent) {
m.onActivate = fn
2022-10-04 13:21:05 +08:00
}
// SetOnShow 事件,不会覆盖默认事件返回值false继续执行默认事件, true跳过默认事件
func (m *LCLBrowserWindow) SetOnShow(fn TNotifyEvent) {
m.onShow = fn
2022-10-04 13:21:05 +08:00
}
// SetOnClose 事件,不会覆盖默认事件返回值false继续执行默认事件, true跳过默认事件
func (m *LCLBrowserWindow) SetOnClose(fn TCloseEvent) {
m.onClose = fn
2022-10-04 13:21:05 +08:00
}
// SetOnCloseQuery 事件,不会覆盖默认事件返回值false继续执行默认事件, true跳过默认事件
func (m *LCLBrowserWindow) SetOnCloseQuery(fn TCloseQueryEvent) {
m.onCloseQuery = fn
2022-10-04 13:21:05 +08:00
}
2023-02-20 00:20:01 +08:00
// SetOnActivateAfter 每次激活窗口之后执行一次
func (m *LCLBrowserWindow) SetOnActivateAfter(fn lcl.TNotifyEvent) {
2022-10-04 13:21:05 +08:00
m.onActivateAfter = fn
}
2023-02-20 00:20:01 +08:00
// Minimize
func (m *LCLBrowserWindow) Minimize() {
if m.TForm == nil {
return
}
QueueAsyncCall(func(id int) {
m.SetWindowState(types.WsMinimized)
})
}
2023-02-20 00:20:01 +08:00
// Restore
2023-02-14 15:25:02 +08:00
func (m *LCLBrowserWindow) Restore() {
m.SetWindowState(types.WsNormal)
}
2023-02-20 00:20:01 +08:00
// CloseBrowserWindow 关闭带有浏览器的窗口
func (m *LCLBrowserWindow) CloseBrowserWindow() {
if m.TForm == nil {
return
}
QueueAsyncCall(func(id int) {
if m == nil {
logger.Error("关闭浏览器 WindowInfo 为空")
return
}
if IsDarwin() {
//main window close
if m.WindowType() == consts.WT_MAIN_BROWSER {
m.Close()
} else {
//sub window close
m.isClosing = true
m.Hide()
m.chromium.CloseBrowser(true)
}
} else {
m.isClosing = true
m.Hide()
m.chromium.CloseBrowser(true)
}
})
}
2023-02-20 00:20:01 +08:00
// DisableTransparent 禁用口透明
func (m *LCLBrowserWindow) DisableTransparent() {
if m.TForm == nil {
return
}
m.SetAlphaBlend(false)
m.SetAlphaBlendValue(255)
}
2023-02-20 00:20:01 +08:00
// EnableTransparent 使窗口透明 value 0 ~ 255
func (m *LCLBrowserWindow) EnableTransparent(value uint8) {
if m.TForm == nil {
return
}
m.SetAlphaBlend(true)
m.SetAlphaBlendValue(value)
}
2023-02-20 00:20:01 +08:00
// DisableMinimize 禁用最小化按钮
func (m *LCLBrowserWindow) DisableMinimize() {
if m.TForm == nil {
return
}
//m.SetBorderIcons(m.BorderIcons().Exclude(types.BiMinimize))
m.WindowProperty().EnableMinimize = false
m.EnabledMinimize(m.WindowProperty().EnableMinimize)
}
2023-02-20 00:20:01 +08:00
// DisableMaximize 禁用最大化按钮
func (m *LCLBrowserWindow) DisableMaximize() {
if m.TForm == nil {
return
}
//m.SetBorderIcons(m.BorderIcons().Exclude(types.BiMaximize))
m.WindowProperty().EnableMaximize = false
m.EnabledMaximize(m.WindowProperty().EnableMaximize)
}
2023-02-20 00:20:01 +08:00
// DisableResize 禁用调整窗口大小
func (m *LCLBrowserWindow) DisableResize() {
if m.TForm == nil {
return
}
m.WindowProperty().EnableResize = false
if !m.WindowProperty().EnableHideCaption {
m.TForm.SetBorderStyle(types.BsSingle)
}
}
2023-02-20 00:20:01 +08:00
// DisableSystemMenu 禁用系统菜单-同时禁用最小化,最大化,关闭按钮
func (m *LCLBrowserWindow) DisableSystemMenu() {
if m.TForm == nil {
return
}
//m.SetBorderIcons(m.BorderIcons().Exclude(types.BiSystemMenu))
m.EnabledSystemMenu(false)
}
2023-02-20 00:20:01 +08:00
// DisableHelp 禁用帮助菜单
func (m *LCLBrowserWindow) DisableHelp() {
if m.TForm == nil {
return
}
m.SetBorderIcons(m.BorderIcons().Exclude(types.BiHelp))
}
2023-02-20 00:20:01 +08:00
// EnableMinimize 启用最小化按钮
func (m *LCLBrowserWindow) EnableMinimize() {
if m.TForm == nil {
return
}
//m.SetBorderIcons(m.BorderIcons().Include(types.BiMinimize))
m.WindowProperty().EnableMinimize = true
m.EnabledMinimize(m.WindowProperty().EnableMinimize)
}
2023-02-20 00:20:01 +08:00
// EnableMaximize 启用最大化按钮
func (m *LCLBrowserWindow) EnableMaximize() {
if m.TForm == nil {
return
}
//m.SetBorderIcons(m.BorderIcons().Include(types.BiMaximize))
m.WindowProperty().EnableMaximize = true
m.EnabledMaximize(m.WindowProperty().EnableMaximize)
}
2023-02-20 00:20:01 +08:00
// EnableResize 启用允许调整窗口大小
func (m *LCLBrowserWindow) EnableResize() {
if m.TForm == nil {
return
}
m.WindowProperty().EnableResize = true
if !m.WindowProperty().EnableHideCaption {
m.TForm.SetBorderStyle(types.BsSizeable)
}
}
2023-02-20 00:20:01 +08:00
// EnableSystemMenu 启用系统菜单
func (m *LCLBrowserWindow) EnableSystemMenu() {
if m.TForm == nil {
return
}
//m.SetBorderIcons(m.BorderIcons().Include(types.BiSystemMenu))
m.EnabledSystemMenu(true)
}
2023-02-20 00:20:01 +08:00
// EnableHelp 启用帮助菜单
func (m *LCLBrowserWindow) EnableHelp() {
if m.TForm == nil {
return
}
m.SetBorderIcons(m.BorderIcons().Include(types.BiHelp))
}
2023-02-20 00:20:01 +08:00
// IsViewsFramework 返回是否VF窗口组件这里返回false
func (m *LCLBrowserWindow) IsViewsFramework() bool {
return false
}
2023-02-20 00:20:01 +08:00
// IsLCL 返回是否LCL窗口组件这里返回true
func (m *LCLBrowserWindow) IsLCL() bool {
return true
}
2023-02-20 00:20:01 +08:00
// show 内部调用
func (m *LCLBrowserWindow) show(sender lcl.IObject) {
2022-10-04 13:21:05 +08:00
var ret bool
if m.onShow != nil {
ret = m.onShow(sender)
2022-10-04 13:21:05 +08:00
}
if !ret {
if m.windowParent != nil {
QueueAsyncCall(func(id int) {
m.windowParent.UpdateSize()
})
}
}
}
2023-02-20 00:20:01 +08:00
// resize 内部调用
func (m *LCLBrowserWindow) resize(sender lcl.IObject) {
2022-10-04 13:21:05 +08:00
var ret bool
if m.onResize != nil {
if m.onResize(sender) {
ret = true
2022-10-04 13:21:05 +08:00
}
}
if !ret {
if m.isClosing {
return
}
if m.windowResize != nil {
m.windowResize(sender)
}
2022-10-04 13:21:05 +08:00
if m.chromium != nil {
m.chromium.NotifyMoveOrResizeStarted()
}
if m.windowParent != nil {
m.windowParent.UpdateSize()
}
}
}
2023-02-20 00:20:01 +08:00
// activate 内部调用
func (m *LCLBrowserWindow) activate(sender lcl.IObject) {
2022-10-04 13:21:05 +08:00
var ret bool
if m.onActivate != nil {
ret = m.onActivate(sender)
2022-10-04 13:21:05 +08:00
}
if !ret {
if m.isClosing {
return
}
if m.chromium != nil {
if !m.chromium.Initialized() {
m.chromium.CreateBrowser(m.windowParent)
}
}
}
if m.onActivateAfter != nil {
m.onActivateAfter(sender)
}
}
2023-02-20 00:20:01 +08:00
// registerPopupEvent 注册弹出子窗口事件
func (m *LCLBrowserWindow) registerPopupEvent() {
2022-10-04 13:21:05 +08:00
var bwEvent = BrowserWindow.browserEvent
2022-12-15 23:13:27 +08:00
m.chromium.SetOnBeforePopup(func(sender lcl.IObject, browser *ICefBrowser, frame *ICefFrame, beforePopupInfo *BeforePopupInfo, client *ICefClient, noJavascriptAccess *bool) bool {
if !api.GoBool(BrowserWindow.Config.ChromiumConfig().enableWindowPopup) {
2022-10-04 13:21:05 +08:00
return true
}
var bw = BrowserWindow.popupWindow.AsLCLBrowserWindow().BrowserWindow()
bw.SetWindowType(consts.WT_POPUP_SUB_BROWSER)
bw.ChromiumCreate(BrowserWindow.Config.ChromiumConfig(), beforePopupInfo.TargetUrl)
bw.putChromiumWindowInfo()
bw.defaultChromiumEvent()
bw.registerWindowsCompMsgEvent()
2022-12-15 23:13:27 +08:00
var result = false
2022-10-04 13:21:05 +08:00
if bwEvent.onBeforePopup != nil {
result = bwEvent.onBeforePopup(sender, browser, frame, beforePopupInfo, bw, noJavascriptAccess)
}
bw.setProperty()
if !result {
QueueAsyncCall(func(id int) {
if bw.WindowProperty().IsShowModel {
bw.ShowModal()
return
}
BrowserWindow.popupWindow.Show()
})
result = true
2022-10-04 13:21:05 +08:00
}
2022-12-15 23:13:27 +08:00
return result
2022-10-04 13:21:05 +08:00
})
}
2023-02-20 00:20:01 +08:00
// registerDefaultEvent 注册默认事件 部分事件允许被覆盖
func (m *LCLBrowserWindow) registerDefaultEvent() {
var bwEvent = BrowserWindow.browserEvent
//默认自定义快捷键
defaultAcceleratorCustom()
2023-02-26 21:17:28 +08:00
m.chromium.SetOnProcessMessageReceived(func(sender lcl.IObject, browser *ICefBrowser, frame *ICefFrame, sourceProcess consts.CefProcessId, message *ICefProcessMessage) bool {
2022-10-04 13:21:05 +08:00
if bwEvent.onProcessMessageReceived != nil {
return bwEvent.onProcessMessageReceived(sender, browser, frame, sourceProcess, message)
}
return false
})
m.chromium.SetOnBeforeResourceLoad(func(sender lcl.IObject, browser *ICefBrowser, frame *ICefFrame, request *ICefRequest, callback *ICefCallback, result *consts.TCefReturnValue) {
if assetserve.AssetsServerHeaderKeyValue != "" {
request.SetHeaderByName(assetserve.AssetsServerHeaderKeyName, assetserve.AssetsServerHeaderKeyValue, true)
}
if bwEvent.onBeforeResourceLoad != nil {
bwEvent.onBeforeResourceLoad(sender, browser, frame, request, callback, result)
}
})
//事件可以被覆盖
2023-02-28 09:55:20 +08:00
m.chromium.SetOnBeforeDownload(func(sender lcl.IObject, browser *ICefBrowser, beforeDownloadItem *ICefDownloadItem, suggestedName string, callback *ICefBeforeDownloadCallback) {
if bwEvent.onBeforeDownload != nil {
bwEvent.onBeforeDownload(sender, browser, beforeDownloadItem, suggestedName, callback)
} else {
callback.Cont(consts.ExePath+consts.Separator+suggestedName, true)
}
})
m.chromium.SetOnBeforeContextMenu(func(sender lcl.IObject, browser *ICefBrowser, frame *ICefFrame, params *ICefContextMenuParams, model *ICefMenuModel) {
if bwEvent.onBeforeContextMenu != nil {
bwEvent.onBeforeContextMenu(sender, browser, frame, params, model)
} else {
chromiumOnBeforeContextMenu(sender, browser, frame, params, model)
}
})
m.chromium.SetOnContextMenuCommand(func(sender lcl.IObject, browser *ICefBrowser, frame *ICefFrame, params *ICefContextMenuParams, commandId consts.MenuId, eventFlags uint32, result *bool) {
if bwEvent.onContextMenuCommand != nil {
bwEvent.onContextMenuCommand(sender, browser, frame, params, commandId, eventFlags, result)
} else {
chromiumOnContextMenuCommand(sender, browser, frame, params, commandId, eventFlags, result)
}
})
2022-10-04 13:21:05 +08:00
m.chromium.SetOnFrameCreated(func(sender lcl.IObject, browser *ICefBrowser, frame *ICefFrame) {
if bwEvent.onFrameCreated != nil {
bwEvent.onFrameCreated(sender, browser, frame)
}
})
m.chromium.SetOnFrameDetached(func(sender lcl.IObject, browser *ICefBrowser, frame *ICefFrame) {
2022-12-15 23:13:27 +08:00
chromiumOnFrameDetached(browser, frame)
2022-10-04 13:21:05 +08:00
if bwEvent.onFrameDetached != nil {
bwEvent.onFrameDetached(sender, browser, frame)
}
})
2022-10-04 13:21:05 +08:00
m.chromium.SetOnAfterCreated(func(sender lcl.IObject, browser *ICefBrowser) {
2022-12-15 23:13:27 +08:00
if chromiumOnAfterCreate(browser) {
return
}
2022-10-04 13:21:05 +08:00
if bwEvent.onAfterCreated != nil {
bwEvent.onAfterCreated(sender, browser)
}
})
//事件可以被覆盖
m.chromium.SetOnKeyEvent(func(sender lcl.IObject, browser *ICefBrowser, event *TCefKeyEvent, result *bool) {
2022-12-03 21:56:51 +08:00
if api.GoBool(BrowserWindow.Config.chromiumConfig.enableDevTools) {
2022-10-04 13:21:05 +08:00
if winInfo := BrowserWindow.GetWindowInfo(browser.Identifier()); winInfo != nil {
if winInfo.WindowType() == consts.WT_DEV_TOOLS || winInfo.WindowType() == consts.WT_VIEW_SOURCE {
2022-10-04 13:21:05 +08:00
return
}
}
if event.WindowsKeyCode == VkF12 && event.Kind == consts.KEYEVENT_RAW_KEYDOWN {
2022-10-04 13:21:05 +08:00
browser.ShowDevTools()
*result = true
} else if event.WindowsKeyCode == VkF12 && event.Kind == consts.KEYEVENT_KEYUP {
2022-10-04 13:21:05 +08:00
*result = true
}
}
if KeyAccelerator.accelerator(browser, event, result) {
return
}
if bwEvent.onKeyEvent != nil {
bwEvent.onKeyEvent(sender, browser, event, result)
}
})
m.chromium.SetOnBeforeBrowser(func(sender lcl.IObject, browser *ICefBrowser, frame *ICefFrame) bool {
2022-12-15 23:13:27 +08:00
chromiumOnBeforeBrowser(browser, frame)
2022-10-04 13:21:05 +08:00
if bwEvent.onBeforeBrowser != nil {
return bwEvent.onBeforeBrowser(sender, browser, frame)
}
return false
})
m.chromium.SetOnTitleChange(func(sender lcl.IObject, browser *ICefBrowser, title string) {
updateBrowserDevTools(browser, title)
if bwEvent.onTitleChange != nil {
bwEvent.onTitleChange(sender, browser, title)
}
})
m.chromium.SetOnDragEnter(func(sender lcl.IObject, browser *ICefBrowser, dragData *ICefDragData, mask consts.TCefDragOperations, result *bool) {
*result = !m.WindowProperty().EnableDragFile
if bwEvent.onDragEnter != nil {
bwEvent.onDragEnter(sender, browser, dragData, mask, result)
}
})
m.chromium.SetOnLoadEnd(func(sender lcl.IObject, browser *ICefBrowser, frame *ICefFrame, httpStatusCode int32) {
if bwEvent.onLoadEnd != nil {
bwEvent.onLoadEnd(sender, browser, frame, httpStatusCode)
}
})
if m.WindowProperty().EnableWebkitAppRegion {
m.chromium.SetOnDraggableRegionsChanged(func(sender lcl.IObject, browser *ICefBrowser, frame *ICefFrame, regions *TCefDraggableRegions) {
if bwEvent.onDraggableRegionsChanged != nil {
bwEvent.onDraggableRegionsChanged(sender, browser, frame, regions)
}
m.cwcap.regions = regions
m.setDraggableRegions()
})
}
2022-10-04 13:21:05 +08:00
}
2023-02-20 00:20:01 +08:00
// close 内部调用
func (m *LCLBrowserWindow) close(sender lcl.IObject, action *types.TCloseAction) {
2022-12-09 21:08:30 +08:00
var ret bool
if m.onClose != nil {
ret = m.onClose(sender, action)
2022-12-09 21:08:30 +08:00
}
if !ret {
2022-12-11 16:01:57 +08:00
logger.Debug("window.onClose")
2022-12-09 21:08:30 +08:00
*action = types.CaFree
}
}
2023-02-20 00:20:01 +08:00
// closeQuery 内部调用
func (m *LCLBrowserWindow) closeQuery(sender lcl.IObject, close *bool) {
2022-12-09 21:08:30 +08:00
var ret bool
if m.onCloseQuery != nil {
ret = m.onCloseQuery(sender, close)
2022-12-09 21:08:30 +08:00
}
if !ret {
if m.tray != nil {
m.tray.close()
}
2022-12-11 16:01:57 +08:00
logger.Debug("window.onCloseQuery windowType:", m.WindowType())
2022-12-09 21:08:30 +08:00
if IsDarwin() {
//main window close
if m.WindowType() == consts.WT_MAIN_BROWSER {
2022-12-09 21:08:30 +08:00
*close = true
desChildWind := m.windowParent.DestroyChildWindow()
2022-12-11 16:01:57 +08:00
logger.Debug("window.onCloseQuery => windowParent.DestroyChildWindow:", desChildWind)
2022-12-09 21:08:30 +08:00
} else {
//sub window close
*close = m.canClose
}
if !m.isClosing {
m.isClosing = true
m.Hide()
m.chromium.CloseBrowser(true)
}
} else {
*close = m.canClose
if !m.isClosing {
m.isClosing = true
m.Hide()
m.chromium.CloseBrowser(true)
}
}
}
}
2022-10-04 13:21:05 +08:00
2023-02-20 00:20:01 +08:00
// registerDefaultChromiumCloseEvent 注册默认的chromium关闭事件
func (m *LCLBrowserWindow) registerDefaultChromiumCloseEvent() {
2022-10-04 13:21:05 +08:00
var bwEvent = BrowserWindow.browserEvent
m.chromium.SetOnClose(func(sender lcl.IObject, browser *ICefBrowser, aAction *TCefCloseBrowsesAction) {
2022-12-11 16:01:57 +08:00
logger.Debug("chromium.onClose")
if IsDarwin() { //MacOSX
2022-12-11 16:01:57 +08:00
desChildWind := m.windowParent.DestroyChildWindow()
logger.Debug("chromium.onClose => windowParent.DestroyChildWindow:", desChildWind)
*aAction = consts.CbaClose
2022-12-11 19:09:09 +08:00
} else if IsLinux() {
*aAction = consts.CbaClose
2022-12-11 19:09:09 +08:00
} else if IsWindows() {
*aAction = consts.CbaDelay
2022-12-11 16:01:57 +08:00
}
2022-12-11 19:33:43 +08:00
if !IsDarwin() {
QueueAsyncCall(func(id int) { //main thread run
m.windowParent.Free()
logger.Debug("chromium.onClose => windowParent.Free")
})
}
m.cwcap.free()
2022-10-04 13:21:05 +08:00
if bwEvent.onClose != nil {
bwEvent.onClose(sender, browser, aAction)
}
})
m.chromium.SetOnBeforeClose(func(sender lcl.IObject, browser *ICefBrowser) {
2022-12-11 16:01:57 +08:00
logger.Debug("chromium.onBeforeClose")
2022-12-15 23:13:27 +08:00
chromiumOnBeforeClose(browser)
m.canClose = true
var closeWindow = func() {
defer func() {
if err := recover(); err != nil {
2022-12-11 16:01:57 +08:00
logger.Error("chromium.OnBeforeClose Error:", err)
2022-10-04 13:21:05 +08:00
}
}()
if m.auxTools != nil {
if m.auxTools.viewSourceWindow != nil {
m.auxTools.viewSourceWindow = nil
}
if m.auxTools.devToolsWindow != nil {
m.auxTools.devToolsWindow = nil
}
}
BrowserWindow.removeWindowInfo(m.windowId)
//主窗口关闭
if m.WindowType() == consts.WT_MAIN_BROWSER {
if IsWindows() {
rtl.PostMessage(m.Handle(), WM_CLOSE, 0, 0)
} else {
m.Close()
}
2022-12-09 21:08:30 +08:00
} else if IsDarwin() {
m.Close()
}
2022-10-04 13:21:05 +08:00
}
2022-12-09 21:08:30 +08:00
QueueAsyncCall(func(id int) { // main thread run
closeWindow()
})
2022-10-04 13:21:05 +08:00
if bwEvent.onBeforeClose != nil {
bwEvent.onBeforeClose(sender, browser)
}
})
}