mirror of
https://gitee.com/energye/energy.git
synced 2024-11-30 10:47:57 +08:00
Fixed Chinese input and gtk3 issues for linux packaging
This commit is contained in:
parent
81f741a279
commit
ef3393bb03
@ -63,9 +63,18 @@ func NewApplicationConfig() *tCefApplicationConfig {
|
||||
m.SetDisableZygote(true)
|
||||
m.SetCheckCEFFiles(false)
|
||||
m.SetRemoteDebuggingPort(0)
|
||||
m.SetExternalMessagePump(false)
|
||||
m.SetMultiThreadedMessageLoop(true)
|
||||
m.SetChromeRuntime(false)
|
||||
//linux >= 107.xxx 版本以后,默认启用的GTK3,106及以前版本默认支持GTK2但无法正常输入中文
|
||||
//顾强制使用GTK3方式,但又无法正常创建lcl组件到窗口中,该框架只对浏览器应用做封装
|
||||
//所以初衷以浏览器应用建设为目标
|
||||
if common.IsLinux() {
|
||||
//linux平台默认设置为false,将启用 ViewsFrameworkBrowserWindow 窗口
|
||||
m.SetExternalMessagePump(false)
|
||||
m.SetMultiThreadedMessageLoop(false)
|
||||
} else {
|
||||
m.SetExternalMessagePump(false)
|
||||
m.SetMultiThreadedMessageLoop(true)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
|
@ -32,14 +32,6 @@ func NewCEFApplication(cfg *tCefApplicationConfig) *TCEFApplication {
|
||||
cfg = NewApplicationConfig()
|
||||
}
|
||||
cfg.framework()
|
||||
|
||||
//linux >= 107.xxx 版本以后,默认不支持GTK2,同时GTK2又无法正常输入中文
|
||||
//顾强制使用GTK3方式,但又无法正常创建lcl组件到窗口中,该框架只是对浏览器应用做封装
|
||||
//所以尽量以正常使用为基准
|
||||
if IsLinux() {
|
||||
cfg.SetExternalMessagePump(false)
|
||||
cfg.SetMultiThreadedMessageLoop(false)
|
||||
}
|
||||
m := new(TCEFApplication)
|
||||
r1, _, _ := Proc(internale_CEFApplication_Create).Call(uintptr(unsafe.Pointer(cfg)))
|
||||
m.instance = unsafe.Pointer(r1)
|
||||
|
@ -35,24 +35,23 @@ type IBaseWindow interface {
|
||||
|
||||
//BaseWindow 是一个基于chromium 和 lcl 的窗口组件
|
||||
type BaseWindow struct {
|
||||
*lcl.TForm //
|
||||
chromium IChromium //
|
||||
windowParent ITCefWindow //
|
||||
browserViewComponent *TCEFBrowserViewComponent //
|
||||
windowComponent *TCEFWindowComponent //
|
||||
windowInfo *TCefWindowInfo //窗口信息
|
||||
windowId int32 //
|
||||
windowType WINDOW_TYPE //0:browser 1:devTools 2:viewSource 默认:0
|
||||
isClosing bool //
|
||||
canClose bool //
|
||||
onResize []TNotifyEvent //
|
||||
onActivate []TNotifyEvent //
|
||||
onShow []TNotifyEvent //
|
||||
onClose []TCloseEvent //
|
||||
onCloseQuery []TCloseQueryEvent //
|
||||
onActivateAfter lcl.TNotifyEvent //
|
||||
isFormCreate bool //是否创建完成 WindowForm
|
||||
isChromiumCreate bool //是否创建完成 Chromium
|
||||
*lcl.TForm //
|
||||
chromium IChromium //
|
||||
windowParent ITCefWindow //
|
||||
vFrameBrowserWindow *ViewsFrameworkBrowserWindow //基于CEF views framework窗口
|
||||
windowInfo *TCefWindowInfo //基于LCL窗口信息
|
||||
windowId int32 //
|
||||
windowType WINDOW_TYPE //0:browser 1:devTools 2:viewSource 默认:0
|
||||
isClosing bool //
|
||||
canClose bool //
|
||||
onResize []TNotifyEvent //
|
||||
onActivate []TNotifyEvent //
|
||||
onShow []TNotifyEvent //
|
||||
onClose []TCloseEvent //
|
||||
onCloseQuery []TCloseQueryEvent //
|
||||
onActivateAfter lcl.TNotifyEvent //
|
||||
isFormCreate bool //是否创建完成 WindowForm
|
||||
isChromiumCreate bool //是否创建完成 Chromium
|
||||
}
|
||||
|
||||
//创建一个带有 chromium 窗口
|
||||
@ -67,6 +66,10 @@ func NewBrowserWindow(config *tCefChromiumConfig, defaultUrl string) *Window {
|
||||
return window
|
||||
}
|
||||
|
||||
func (m *BaseWindow) Id() int32 {
|
||||
return m.windowId
|
||||
}
|
||||
|
||||
func (m *BaseWindow) Show() {
|
||||
m.TForm.Show()
|
||||
}
|
||||
|
@ -12,16 +12,21 @@ import (
|
||||
"github.com/energye/energy/common"
|
||||
)
|
||||
|
||||
type viewsFrameBrowserWindowOnEventCallback func(event *BrowserEvent, window *ViewsFrameworkBrowserWindow)
|
||||
type browserWindowOnEventCallback func(event *BrowserEvent, window *TCefWindowInfo)
|
||||
type browserWindowAfterOnEventCallback func(window *TCefWindowInfo)
|
||||
|
||||
//创建主窗口指定的一些快捷配置属性
|
||||
type browserConfig struct {
|
||||
DefaultUrl string //默认URL地址
|
||||
Title string //窗口标题
|
||||
Icon string //窗口图标
|
||||
Width int32 //窗口宽
|
||||
Height int32 //窗口高
|
||||
chromiumConfig *tCefChromiumConfig //主窗体浏览器配置
|
||||
browserWindowOnEventCallback func(browserEvent *BrowserEvent, window *TCefWindowInfo) //主窗口初始化回调
|
||||
browserWindowAfterOnEventCallback func(window *TCefWindowInfo) //主窗口初始化之后回调
|
||||
DefaultUrl string //默认URL地址
|
||||
Title string //窗口标题
|
||||
Icon string //窗口图标
|
||||
Width int32 //窗口宽
|
||||
Height int32 //窗口高
|
||||
chromiumConfig *tCefChromiumConfig //主窗体浏览器配置
|
||||
viewsFrameBrowserWindowOnEventCallback viewsFrameBrowserWindowOnEventCallback //主窗口初始化回调 - 基于CEF views framework窗口
|
||||
browserWindowOnEventCallback browserWindowOnEventCallback //主窗口初始化回调 - 基于LCL窗口
|
||||
browserWindowAfterOnEventCallback browserWindowAfterOnEventCallback //主窗口初始化之后回调
|
||||
}
|
||||
|
||||
//设置chromium配置
|
||||
@ -31,13 +36,26 @@ func (m *browserConfig) SetChromiumConfig(chromiumConfig *tCefChromiumConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *browserConfig) setBrowserWindowInitOnEvent(fn func(event *BrowserEvent, browserWindow *TCefWindowInfo)) {
|
||||
//主窗口初始化回调 - 基于CEF views framework窗口
|
||||
//
|
||||
//该回调函数和基于LCL窗口回调是互斥的,默认情况只有一个会被回调
|
||||
func (m *browserConfig) setViewsFrameBrowserWindowOnEventCallback(fn viewsFrameBrowserWindowOnEventCallback) {
|
||||
if fn != nil && common.Args.IsMain() {
|
||||
m.viewsFrameBrowserWindowOnEventCallback = fn
|
||||
}
|
||||
}
|
||||
|
||||
//主窗口初始化回调 - 基于LCL窗口
|
||||
//
|
||||
//该回调函数和基于CEF窗口回调是互斥的,默认情况只有一个会被回调
|
||||
func (m *browserConfig) setBrowserWindowInitOnEvent(fn browserWindowOnEventCallback) {
|
||||
if fn != nil && common.Args.IsMain() {
|
||||
m.browserWindowOnEventCallback = fn
|
||||
}
|
||||
}
|
||||
|
||||
func (m *browserConfig) setBrowserWindowInitAfterOnEvent(fn func(browserWindow *TCefWindowInfo)) {
|
||||
//主窗口初始化回调 - 基于LCL窗口
|
||||
func (m *browserConfig) setBrowserWindowInitAfterOnEvent(fn browserWindowAfterOnEventCallback) {
|
||||
if fn != nil && common.Args.IsMain() {
|
||||
m.browserWindowAfterOnEventCallback = fn
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
)
|
||||
|
||||
type TCEFBrowserViewComponent struct {
|
||||
lcl.IComponent
|
||||
instance unsafe.Pointer
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ type browserWindow struct {
|
||||
//
|
||||
// 主进程启动成功之后,将创建主窗口 mainBrowserWindow 是一个默认的主窗口
|
||||
//
|
||||
// externalMessagePump和multiThreadedMessageLoop是false时将使用RunMessageLoop,这对linux v107.xxx之后版本支持的更好
|
||||
// externalMessagePump和multiThreadedMessageLoop是false时启用 ViewsFrameworkBrowserWindow 窗口
|
||||
//
|
||||
// 在这里启动浏览器的主进程和子进程
|
||||
func Run(cefApp *TCEFApplication) {
|
||||
@ -179,24 +179,40 @@ func (m *browser) MainWindow() *TCefWindowInfo {
|
||||
return m.mainWindow
|
||||
}
|
||||
|
||||
// 主窗口和chromium初始化时回调
|
||||
// 基于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初始化时回调
|
||||
//
|
||||
// 在这里可以对主窗体事件监听和属性设置,和主窗口上的子组件创建
|
||||
//
|
||||
// 如果想创建子窗口或带有browser的窗口最好在 SetBrowserInitAfter 回调函数中创建
|
||||
//
|
||||
// event 浏览器事件
|
||||
// mainBrowserWindow 窗口信息对象
|
||||
func (m *browser) SetBrowserInit(fn func(event *BrowserEvent, browserWindow *TCefWindowInfo)) {
|
||||
// event 浏览器事件
|
||||
//
|
||||
// browserWindow 窗口信息对象
|
||||
func (m *browser) SetBrowserInit(fn browserWindowOnEventCallback) {
|
||||
m.Config.setBrowserWindowInitOnEvent(fn)
|
||||
}
|
||||
|
||||
// 主窗体和chromium初始后回调
|
||||
// 基于LCL窗口 - 主窗体和chromium初始后回调
|
||||
//
|
||||
// 在这里可以对主窗体属性设置、添加子窗口、带有browser的窗口和子组件创建
|
||||
//
|
||||
// mainBrowserWindow 窗口信息对象
|
||||
func (m *browser) SetBrowserInitAfter(fn func(browserWindow *TCefWindowInfo)) {
|
||||
func (m *browser) SetBrowserInitAfter(fn browserWindowAfterOnEventCallback) {
|
||||
m.Config.setBrowserWindowInitAfterOnEvent(fn)
|
||||
}
|
||||
|
||||
|
@ -10,17 +10,41 @@ package cef
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/energye/energy/common"
|
||||
"github.com/energye/energy/consts"
|
||||
"github.com/energye/golcl/lcl"
|
||||
)
|
||||
|
||||
//基于CEF views framework窗口
|
||||
//
|
||||
//该窗口使用CEF内部实现,在linux下107.xx以后版本默认使用GTK3,但无法使用lcl组件集成到窗口中
|
||||
//
|
||||
//当创建应用配置时 MultiThreadedMessageLoop 和 ExternalMessagePump 属性同时为false(linux系统默认强制false)时启用ViewsFramework窗口
|
||||
type ViewsFrameworkBrowserWindow struct {
|
||||
component lcl.IComponent //
|
||||
windowComponent *TCEFWindowComponent //
|
||||
browserViewComponent *TCEFBrowserViewComponent //
|
||||
}
|
||||
|
||||
func (m *ViewsFrameworkBrowserWindow) Component() lcl.IComponent {
|
||||
return m.component
|
||||
}
|
||||
|
||||
func (m *ViewsFrameworkBrowserWindow) WindowComponent() *TCEFWindowComponent {
|
||||
return m.windowComponent
|
||||
}
|
||||
|
||||
func (m *ViewsFrameworkBrowserWindow) BrowserViewComponent() *TCEFBrowserViewComponent {
|
||||
return m.browserViewComponent
|
||||
}
|
||||
|
||||
func (m *browserWindow) appContextInitialized(app *TCEFApplication) {
|
||||
if !common.Args.IsMain() {
|
||||
return
|
||||
}
|
||||
app.SetOnContextInitialized(func() {
|
||||
fmt.Println("OnContextInitialized()")
|
||||
component := lcl.NewComponent(nil)
|
||||
m.vFrameBrowserWindow = &ViewsFrameworkBrowserWindow{}
|
||||
m.vFrameBrowserWindow.component = lcl.NewComponent(nil)
|
||||
if BrowserWindow.Config.chromiumConfig == nil {
|
||||
BrowserWindow.Config.chromiumConfig = NewChromiumConfig()
|
||||
BrowserWindow.Config.chromiumConfig.SetEnableMenu(true)
|
||||
@ -28,43 +52,43 @@ func (m *browserWindow) appContextInitialized(app *TCEFApplication) {
|
||||
BrowserWindow.Config.chromiumConfig.SetEnableOpenUrlTab(true)
|
||||
BrowserWindow.Config.chromiumConfig.SetEnableWindowPopup(true)
|
||||
}
|
||||
m.chromium = NewChromium(component, BrowserWindow.Config.chromiumConfig)
|
||||
m.chromium = NewChromium(m.vFrameBrowserWindow.component, BrowserWindow.Config.chromiumConfig)
|
||||
m.chromium.SetEnableMultiBrowserMode(true)
|
||||
m.browserViewComponent = NewBrowserViewComponent(component)
|
||||
m.windowComponent = NewWindowComponent(component)
|
||||
m.vFrameBrowserWindow.browserViewComponent = NewBrowserViewComponent(m.vFrameBrowserWindow.component)
|
||||
m.vFrameBrowserWindow.windowComponent = NewWindowComponent(m.vFrameBrowserWindow.component)
|
||||
|
||||
m.chromium.SetOnBeforePopup(func(sender lcl.IObject, browser *ICefBrowser, frame *ICefFrame, beforePopupInfo *BeforePopupInfo, client *ICefClient, noJavascriptAccess *bool) bool {
|
||||
fmt.Println("OnBeforePopup TargetUrl:", beforePopupInfo.TargetUrl)
|
||||
|
||||
return false
|
||||
})
|
||||
m.windowComponent.SetOnWindowCreated(func(sender lcl.IObject, window *ICefWindow) {
|
||||
if m.chromium.CreateBrowserByBrowserViewComponent(BrowserWindow.Config.DefaultUrl, m.browserViewComponent) {
|
||||
m.windowComponent.AddChildView(m.browserViewComponent)
|
||||
m.windowComponent.SetTitle(BrowserWindow.Config.Title)
|
||||
m.vFrameBrowserWindow.windowComponent.SetOnWindowCreated(func(sender lcl.IObject, window *ICefWindow) {
|
||||
if m.chromium.CreateBrowserByBrowserViewComponent(BrowserWindow.Config.DefaultUrl, m.vFrameBrowserWindow.browserViewComponent) {
|
||||
m.vFrameBrowserWindow.windowComponent.AddChildView(m.vFrameBrowserWindow.browserViewComponent)
|
||||
m.vFrameBrowserWindow.windowComponent.SetTitle(BrowserWindow.Config.Title)
|
||||
window.CenterWindow(NewCefSize(BrowserWindow.Config.Width, BrowserWindow.Config.Height))
|
||||
m.browserViewComponent.RequestFocus()
|
||||
m.vFrameBrowserWindow.browserViewComponent.RequestFocus()
|
||||
if BrowserWindow.Config.Icon != "" {
|
||||
window.SetWindowAppIconFS(1, BrowserWindow.Config.Icon)
|
||||
}
|
||||
if BrowserWindow.Config.browserWindowOnEventCallback != nil {
|
||||
if BrowserWindow.Config.viewsFrameBrowserWindowOnEventCallback != nil {
|
||||
BrowserWindow.browserEvent.chromium = m.chromium
|
||||
BrowserWindow.Config.browserWindowOnEventCallback(BrowserWindow.browserEvent, m.windowInfo)
|
||||
BrowserWindow.Config.viewsFrameBrowserWindowOnEventCallback(BrowserWindow.browserEvent, m.vFrameBrowserWindow)
|
||||
}
|
||||
window.Show()
|
||||
}
|
||||
})
|
||||
m.windowComponent.SetOnCanClose(func(sender lcl.IObject, window *ICefWindow, aResult *bool) {
|
||||
m.vFrameBrowserWindow.windowComponent.SetOnCanClose(func(sender lcl.IObject, window *ICefWindow, aResult *bool) {
|
||||
fmt.Println("OnCanClose")
|
||||
*aResult = true
|
||||
app.QuitMessageLoop()
|
||||
})
|
||||
m.windowComponent.SetOnGetInitialBounds(func(sender lcl.IObject, window *ICefWindow, aResult *TCefRect) {
|
||||
m.vFrameBrowserWindow.windowComponent.SetOnGetInitialBounds(func(sender lcl.IObject, window *ICefWindow, aResult *TCefRect) {
|
||||
fmt.Println("OnGetInitialBounds")
|
||||
})
|
||||
m.windowComponent.SetOnGetInitialShowState(func(sender lcl.IObject, window *ICefWindow, aResult *consts.TCefShowState) {
|
||||
m.vFrameBrowserWindow.windowComponent.SetOnGetInitialShowState(func(sender lcl.IObject, window *ICefWindow, aResult *consts.TCefShowState) {
|
||||
fmt.Println("OnGetInitialShowState", *aResult)
|
||||
})
|
||||
m.windowComponent.CreateTopLevelWindow()
|
||||
m.vFrameBrowserWindow.windowComponent.CreateTopLevelWindow()
|
||||
})
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
)
|
||||
|
||||
type TCEFWindowComponent struct {
|
||||
lcl.IComponent
|
||||
instance unsafe.Pointer
|
||||
}
|
||||
|
||||
|
@ -117,10 +117,6 @@ func (m *TCefWindowInfo) Maximize() {
|
||||
})
|
||||
}
|
||||
|
||||
func (m *TCefWindowInfo) WindowId() int32 {
|
||||
return m.Window.windowId
|
||||
}
|
||||
|
||||
// 关闭窗口-在ui线程中执行
|
||||
func (m *TCefWindowInfo) Close() {
|
||||
BrowserWindow.uiLock.Lock()
|
||||
@ -131,7 +127,7 @@ func (m *TCefWindowInfo) Close() {
|
||||
return
|
||||
}
|
||||
if m.Window == nil {
|
||||
logger.Error("关闭浏览器 Form 为空 WindowId:", m.WindowId())
|
||||
logger.Error("关闭浏览器 Window 为空")
|
||||
return
|
||||
}
|
||||
if common.IsDarwin() {
|
||||
|
@ -21,7 +21,16 @@ func main() {
|
||||
//指定一个URL地址,或本地html文件目录
|
||||
cef.BrowserWindow.Config.DefaultUrl = "http://localhost:22022/index.html"
|
||||
cef.BrowserWindow.Config.Icon = "resources/icon.png"
|
||||
cef.BrowserWindow.SetViewFrameBrowserInit(func(event *cef.BrowserEvent, window *cef.ViewsFrameworkBrowserWindow) {
|
||||
fmt.Println("cef.BrowserWindow.SetViewFrameBrowserInit", window)
|
||||
fmt.Printf("%+v\n", window)
|
||||
|
||||
})
|
||||
cef.BrowserWindow.SetBrowserInit(func(event *cef.BrowserEvent, window *cef.TCefWindowInfo) {
|
||||
fmt.Println("cef.BrowserWindow.SetBrowserInit", window)
|
||||
fmt.Printf("%+v\n", window)
|
||||
|
||||
})
|
||||
//在主进程启动成功之后执行
|
||||
//在这里启动内置http服务
|
||||
//内置http服务需要使用 go:embed resources 内置资源到执行程序中
|
||||
|
Loading…
Reference in New Issue
Block a user