提交 fb1924c9 编写于 作者: yanghye's avatar yanghye

A: lcl custom window drag

上级 f99f42c4
......@@ -13,8 +13,10 @@
package cef
import (
"fmt"
"github.com/energye/energy/v2/cef/internal/ipc"
"github.com/energye/energy/v2/cef/internal/process"
ipcArgument "github.com/energye/energy/v2/cef/ipc/argument"
"github.com/energye/energy/v2/consts"
)
......@@ -26,6 +28,11 @@ func appOnContextCreated(browser *ICefBrowser, frame *ICefFrame, context *ICefV8
ipcRender.registerGoSyncReplayEvent() // render ipc
ipcRender.makeIPC(context) // render ipc make
makeProcess(browser, frame, context) // process make
// 只在LCL窗口中使用自定义窗口拖拽, VF窗口默认已实现
// 在MacOS中LCL窗口没有有效的消息事件
var executeJS = `energyExtension.drag.setEnableDrag(true); energyExtension.drag.setup();`
frame.ExecuteJavaScript(executeJS, "", 0)
}
// appMainRunCallback 应用运行 - 默认实现
......@@ -35,45 +42,89 @@ func appMainRunCallback() {
// appWebKitInitialized - webkit - 默认实现
func appWebKitInitialized() {
// var myparamValue string
// v8Handler := V8HandlerRef.New()
// v8Handler.Execute(func(name string, object *ICefV8Value, arguments *TCefV8ValueArray, retVal *ResultV8Value, exception *ResultString) bool {
// fmt.Println("v8Handler.Execute", name)
// var result bool
// if name == "GetMyParam" {
// result = true
// retVal.SetResult(V8ValueRef.NewString(myparamValue))
// } else if name == "SetMyParam" {
// if arguments.Size() > 0 {
// newValue := arguments.Get(0)
// fmt.Println("value is string:", newValue.IsString())
// fmt.Println("value:", newValue.GetStringValue())
// myparamValue = newValue.GetStringValue()
// newValue.Free()
// }
// result = true
// }
// return result
// })
// //注册js
// var jsCode = `
// let energyExtension;
// if (!energyExtension) {
// energyExtension = {};
// }
// (function () {
// test.__defineGetter__('mouseover', function (e) {
// native function mouseover();
// return mouseover(e);
// });
// test.__defineSetter__('mousemove', function (e) {
// native function mousemove();
// mousemove(e);
// });
// })();
//`
// // 注册JS 和v8处理器
// RegisterExtension("v8/test", jsCode, v8Handler)
energyExtensionHandler := V8HandlerRef.New()
energyExtensionHandler.Execute(func(name string, object *ICefV8Value, arguments *TCefV8ValueArray, retVal *ResultV8Value, exception *ResultString) bool {
fmt.Println("Execute", name, consts.IsMessageLoop, application.SingleProcess())
message := &ipcArgument.List{
Id: -1,
BId: ipc.RenderChan().BrowserId(),
Name: internalIPCDRAG,
}
ipc.RenderChan().IPC().Send(message.Bytes())
return false
})
var code = `
let energyExtension;
if (!energyExtension) {
energyExtension = {
drag: {
enableDrag: false,
shouldDrag: false,
cssDragProperty: "--webkit-app-region",
cssDragValue: "drag",
defaultCursor: null
},
};
}
(function () {
energyExtension.drag.war = function (e) {
let v = window.getComputedStyle(e.target).getPropertyValue(energyExtension.drag.cssDragProperty);
if (v) {
v = v.trim();
if (v !== energyExtension.drag.cssDragValue || e.buttons !== 1) {
return false;
}
return e.detail === 1;
}
return false;
}
energyExtension.drag.mouseMove = function (e) {
if (!energyExtension.drag.enableDrag && !energyExtension.drag.shouldDrag) {
return
}
if (energyExtension.drag.shouldDrag) {
energyExtension.drag.shouldDrag = false;
native function mouseMove();
mouseMove(e);
}
}
energyExtension.drag.mouseUp = function (e) {
if (!energyExtension.drag.enableDrag) {
return
}
energyExtension.drag.shouldDrag = false;
//document.body.style.cursor = "default";
native function mouseUp();
mouseUp(e);
}
energyExtension.drag.mouseDown = function (e) {
if (!energyExtension.drag.enableDrag && ((e.offsetX > e.target.clientWidth || e.offsetY > e.target.clientHeight))) {
return
}
if (energyExtension.drag.war(e)) {
console.log('mouseDown');
e.preventDefault();
energyExtension.drag.shouldDrag = true;
native function mouseDown();
mouseDown(e);
} else {
energyExtension.drag.shouldDrag = false;
}
}
energyExtension.drag.setEnableDrag = function (v) {
console.log('drag.setEnableDrag', v, energyExtension);
energyExtension.drag.enableDrag = v;
}
energyExtension.drag.setup = function () {
console.log('drag.setup', energyExtension);
window.addEventListener("mousemove", energyExtension.drag.mouseMove);
window.addEventListener("mousedown", energyExtension.drag.mouseDown);
window.addEventListener("mouseup", energyExtension.drag.mouseUp);
}
})();
`
// 注册 EnergyExtension JS
RegisterExtension("energyExtension", code, energyExtensionHandler)
}
// renderProcessMessageReceived 渲染进程消息 - 默认实现
......
......@@ -81,6 +81,7 @@ func Run(app *TCEFApplication) {
}
appMainRunCallback()
if consts.IsMessageLoop {
lcl.Application.Initialize()
// VF窗口消息轮询
app.RunMessageLoop()
} else {
......
......@@ -22,8 +22,10 @@ import (
"github.com/energye/golcl/energy/emfs"
"github.com/energye/golcl/energy/tools"
"github.com/energye/golcl/lcl"
"github.com/energye/golcl/lcl/api"
"github.com/energye/golcl/lcl/rtl"
"github.com/energye/golcl/lcl/types"
"runtime"
"time"
)
......@@ -132,6 +134,20 @@ func (m *LCLBrowserWindow) Handle() types.HWND {
return m.hWnd
}
// RunOnMainThread
// 在主线程中运行
func (m *LCLBrowserWindow) RunOnMainThread(fn func()) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
if api.DMainThreadId() == api.DCurrentThreadId() {
fn()
} else {
lcl.ThreadSync(func() {
fn()
})
}
}
// BrowserWindow 返回LCL窗口组件实例对象
func (m *LCLBrowserWindow) BrowserWindow() *LCLBrowserWindow {
return m
......
......@@ -111,3 +111,7 @@ func (m *LCLBrowserWindow) Maximize() {
}
})
}
func (m *LCLBrowserWindow) drag() {
}
......@@ -357,3 +357,9 @@ func (m *LCLBrowserWindow) Maximize() {
// //LWA_ALPHA | LWA_COLORKEY: crKey的地方全透明,其它地方根据bAlpha确定透明度
// win.LWA_ALPHA|win.LWA_COLORKEY)
//}
func (m *LCLBrowserWindow) drag() {
if win.ReleaseCapture() {
win.PostMessage(m.Handle(), consts.WM_NCLBUTTONDOWN, consts.HTCAPTION, 0)
}
}
......@@ -22,7 +22,9 @@ import (
"github.com/energye/golcl/energy/emfs"
"github.com/energye/golcl/energy/tools"
"github.com/energye/golcl/lcl"
"github.com/energye/golcl/lcl/api"
"github.com/energye/golcl/lcl/types"
"runtime"
)
// ViewsFrameworkBrowserWindow 基于CEF views framework 窗口组件
......@@ -598,3 +600,17 @@ func (m *ViewsFrameworkBrowserWindow) WindowComponent() *TCEFWindowComponent {
func (m *ViewsFrameworkBrowserWindow) BrowserViewComponent() *TCEFBrowserViewComponent {
return m.browserViewComponent
}
// RunOnMainThread
// 在主线程中运行
func (m *ViewsFrameworkBrowserWindow) RunOnMainThread(fn func()) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
if api.DMainThreadId() == api.DCurrentThreadId() {
fn()
} else {
lcl.ThreadSync(func() {
fn()
})
}
}
......@@ -103,6 +103,7 @@ type IBrowserWindow interface {
NewCefTray(width, height int32, url string) ITray //仅支持windows托盘LCL+[CEF|VF](使用web端技术自定义实现,如使用LCL窗口组件该托盘实现是LCL+CEF,如使用VF窗口组件该托盘实现是LCL+VF)
NewSysTray() ITray //systray系统原生
SetCreateBrowserExtraInfo(windowName string, context *ICefRequestContext, extraInfo *ICefDictionaryValue) //设置 Chromium 创建浏览器时设置的扩展信息
RunOnMainThread(fn func()) //在主线程中运行
}
// ILCLBrowserWindow
......
......@@ -13,11 +13,13 @@
package cef
import (
"fmt"
"github.com/energye/energy/v2/cef/internal/ipc"
ipcArgument "github.com/energye/energy/v2/cef/ipc/argument"
"github.com/energye/energy/v2/cef/ipc/context"
"github.com/energye/energy/v2/consts"
"github.com/energye/energy/v2/pkgs/json"
"github.com/energye/golcl/lcl/api"
)
// ipcBrowserProcess 主进程
......@@ -140,7 +142,23 @@ func (m *ipcBrowserProcess) registerEvent() {
}
return false
})
// drag
ipc.BrowserChan().AddCallback(func(channelId int64, argument ipcArgument.IList) bool {
if argument != nil {
if argument.GetName() == internalIPCDRAG {
if wi := BrowserWindow.GetWindowInfo(argument.BrowserId()); wi != nil {
if wi.IsLCL() {
wi.RunOnMainThread(func() {
fmt.Println("call-1-DMainThreadId:", api.DMainThreadId(), api.DCurrentThreadId())
wi.AsLCLBrowserWindow().BrowserWindow().drag()
})
}
}
return true
}
}
return false
})
}
// jsExecuteGoSyncMethodMessage JS执行Go事件 - 同步消息处理
......
......@@ -25,6 +25,7 @@ const (
internalIPCEmit = "emit" // JavaScript -> ipc.emit 在 JavaScript 触发 GO 监听事件函数名, 异步
internalIPCEmitSync = "emitSync" // JavaScript -> ipc.emitSync 在 JavaScript 触发 GO 监听事件函数名, 同步
internalIPCOn = "on" // JavaScript -> ipc.on 在 JavaScript 监听事件, 提供给 GO 调用
internalIPCDRAG = "drag" // JavaScript -> ipc.on drag
)
// ipc message name
......@@ -77,7 +78,7 @@ type ipcCallback struct {
// isIPCInternalKey IPC 内部定义使用 key 不允许使用
func isIPCInternalKey(key string) bool {
return key == internalIPC || key == internalIPCEmit || key == internalIPCOn || key == internalIPCEmitSync ||
return key == internalIPC || key == internalIPCEmit || key == internalIPCOn || key == internalIPCDRAG || key == internalIPCEmitSync ||
key == internalIPCJSExecuteGoEvent || key == internalIPCJSExecuteGoEventReplay ||
key == internalIPCGoExecuteJSEvent || key == internalIPCGoExecuteJSEventReplay ||
key == internalIPCJSExecuteGoSyncEvent || key == internalIPCJSExecuteGoSyncEventReplay
......
......@@ -80,8 +80,10 @@ func (m *ICefBrowser) HostWindowHandle() types.HWND {
if !m.IsValid() {
return 0
}
r1, _, _ := imports.Proc(def.CEFBrowser_GetHostWindowHandle).Call(m.Instance())
return r1
if m.windowHandle == 0 {
m.windowHandle, _, _ = imports.Proc(def.CEFBrowser_GetHostWindowHandle).Call(m.Instance())
}
return m.windowHandle
}
// CloseBrowser 关闭浏览器,同时关闭窗口
......
......@@ -20,6 +20,7 @@ import (
. "github.com/energye/energy/v2/types"
"github.com/energye/golcl/lcl"
"github.com/energye/golcl/lcl/api"
"github.com/energye/golcl/lcl/types"
"time"
"unsafe"
)
......@@ -263,6 +264,7 @@ type ICefBrowser struct {
instance unsafe.Pointer
mainFrame *ICefFrame
requestContext *ICefRequestContext
windowHandle types.HWND
idFrames map[int64]*ICefFrame
nameFrames map[string]*ICefFrame
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册