diff --git a/v3/examples/window/main.go b/v3/examples/window/main.go
index 41fc4660..4a31eaa0 100644
--- a/v3/examples/window/main.go
+++ b/v3/examples/window/main.go
@@ -154,21 +154,23 @@ func main() {
}).Show()
windowCounter++
})
- myMenu.Add("New WebviewWindow (ignores mouse events").
- SetAccelerator("CmdOrCtrl+F").
- OnClick(func(ctx *application.Context) {
- app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
- HTML: "
",
- X: rand.Intn(1000),
- Y: rand.Intn(800),
- IgnoreMouseEvents: true,
- BackgroundType: application.BackgroundTypeTransparent,
- Mac: application.MacWindow{
- InvisibleTitleBarHeight: 50,
- },
- }).Show()
- windowCounter++
- })
+ if runtime.GOOS != "linux" {
+ myMenu.Add("New WebviewWindow (ignores mouse events)").
+ SetAccelerator("CmdOrCtrl+F").
+ OnClick(func(ctx *application.Context) {
+ app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
+ HTML: "",
+ X: rand.Intn(1000),
+ Y: rand.Intn(800),
+ IgnoreMouseEvents: true,
+ BackgroundType: application.BackgroundTypeTransparent,
+ Mac: application.MacWindow{
+ InvisibleTitleBarHeight: 50,
+ },
+ }).Show()
+ windowCounter++
+ })
+ }
if runtime.GOOS == "darwin" {
myMenu.Add("New WebviewWindow (MacTitleBarHiddenInset)").
OnClick(func(ctx *application.Context) {
diff --git a/v3/pkg/application/application_linux.go b/v3/pkg/application/application_linux.go
index a72775f0..2d50e988 100644
--- a/v3/pkg/application/application_linux.go
+++ b/v3/pkg/application/application_linux.go
@@ -22,9 +22,8 @@ func init() {
}
type linuxApp struct {
- application pointer
- applicationMenu pointer
- parent *App
+ application pointer
+ parent *App
startupActions []func()
@@ -55,8 +54,8 @@ func (l *linuxApp) show() {
}
func (l *linuxApp) on(eventID uint) {
- // TODO: What do we need to do here?
- log.Println("linuxApp.on()", eventID)
+ // TODO: Test register/unregister events
+ //C.registerApplicationEvent(l.application, C.uint(eventID))
}
func (l *linuxApp) setIcon(icon []byte) {
@@ -80,21 +79,6 @@ func (r rnr) run() {
r.f()
}
-func (l *linuxApp) getApplicationMenu() pointer {
- if l.applicationMenu != nilPointer {
- return l.applicationMenu
- }
-
- menu := globalApplication.ApplicationMenu
- if menu != nil {
- InvokeSync(func() {
- menu.Update()
- })
- l.applicationMenu = (menu.impl).(*linuxMenu).native
- }
- return l.applicationMenu
-}
-
func (l *linuxApp) setApplicationMenu(menu *Menu) {
// FIXME: How do we avoid putting a menu?
if menu == nil {
diff --git a/v3/pkg/application/keys.go b/v3/pkg/application/keys.go
index 4a6fc0e6..b366c106 100644
--- a/v3/pkg/application/keys.go
+++ b/v3/pkg/application/keys.go
@@ -70,6 +70,11 @@ type accelerator struct {
Modifiers []modifier
}
+func (a *accelerator) clone() *accelerator {
+ result := *a
+ return &result
+}
+
func (a *accelerator) String() string {
var result []string
// Sort modifiers
diff --git a/v3/pkg/application/linux_cgo.go b/v3/pkg/application/linux_cgo.go
index 73e32247..beba773f 100644
--- a/v3/pkg/application/linux_cgo.go
+++ b/v3/pkg/application/linux_cgo.go
@@ -13,7 +13,7 @@ import (
)
/*
-#cgo linux pkg-config: gtk+-3.0 webkit2gtk-4.0 javascriptcoregtk-4.1
+#cgo linux pkg-config: gtk+-3.0 webkit2gtk-4.0 javascriptcoregtk-4.1 gdk-3.0
#include
#include
@@ -697,6 +697,10 @@ func windowDestroy(window pointer) {
//C.gtk_widget_destroy((*C.GtkWidget)(window))
}
+func menuDestroy(gtkMenu pointer) {
+ C.gtk_widget_destroy((*C.GtkWidget)(gtkMenu))
+}
+
func windowFullscreen(window pointer) {
C.gtk_window_fullscreen((*C.GtkWindow)(window))
}
@@ -867,6 +871,16 @@ func windowShow(window pointer) {
C.gtk_widget_show_all((*C.GtkWidget)(window))
}
+func windowIgnoreMouseEvents(window pointer, webview pointer, ignore bool) {
+ var enable C.int
+ if ignore {
+ enable = 1
+ }
+ gdkWindow := (*C.GdkWindow)(window)
+ C.gdk_window_set_pass_through(gdkWindow, enable)
+ C.webkit_web_view_set_editable((*C.WebKitWebView)(webview), C.gboolean(enable))
+}
+
func windowSetBackgroundColour(vbox, webview pointer, colour RGBA) {
rgba := C.GdkRGBA{C.double(colour.Red) / 255.0, C.double(colour.Green) / 255.0, C.double(colour.Blue) / 255.0, C.double(colour.Alpha) / 255.0}
C.webkit_web_view_set_background_color((*C.WebKitWebView)(webview), &rgba)
diff --git a/v3/pkg/application/menu.go b/v3/pkg/application/menu.go
index f4a18f39..25a844a4 100644
--- a/v3/pkg/application/menu.go
+++ b/v3/pkg/application/menu.go
@@ -95,6 +95,17 @@ func (m *Menu) setContextData(data *ContextMenuData) {
}
}
+// Clone recursively clones the menu and all its submenus.
+func (m *Menu) clone() *Menu {
+ result := &Menu{
+ label: m.label,
+ }
+ for _, item := range m.items {
+ result.items = append(result.items, item.clone())
+ }
+ return result
+}
+
func (a *App) NewMenu() *Menu {
return &Menu{}
}
diff --git a/v3/pkg/application/menuitem.go b/v3/pkg/application/menuitem.go
index f363fb74..7e0910a4 100644
--- a/v3/pkg/application/menuitem.go
+++ b/v3/pkg/application/menuitem.go
@@ -332,3 +332,29 @@ func (m *MenuItem) setContextData(data *ContextMenuData) {
m.submenu.setContextData(data)
}
}
+
+// clone returns a deep copy of the MenuItem
+func (m *MenuItem) clone() *MenuItem {
+ result := &MenuItem{
+ id: m.id,
+ label: m.label,
+ tooltip: m.tooltip,
+ disabled: m.disabled,
+ checked: m.checked,
+ hidden: m.hidden,
+ bitmap: m.bitmap,
+ callback: m.callback,
+ itemType: m.itemType,
+ role: m.role,
+ }
+ if m.submenu != nil {
+ result.submenu = m.submenu.clone()
+ }
+ if m.accelerator != nil {
+ result.accelerator = m.accelerator.clone()
+ }
+ if m.contextMenuData != nil {
+ result.contextMenuData = m.contextMenuData.clone()
+ }
+ return result
+}
diff --git a/v3/pkg/application/messageprocessor_contextmenu.go b/v3/pkg/application/messageprocessor_contextmenu.go
index c7c8a86a..0d7f2e89 100644
--- a/v3/pkg/application/messageprocessor_contextmenu.go
+++ b/v3/pkg/application/messageprocessor_contextmenu.go
@@ -11,6 +11,15 @@ type ContextMenuData struct {
Data any `json:"data"`
}
+func (d ContextMenuData) clone() *ContextMenuData {
+ return &ContextMenuData{
+ Id: d.Id,
+ X: d.X,
+ Y: d.Y,
+ Data: d.Data,
+ }
+}
+
const (
ContextMenuOpen = 0
)
diff --git a/v3/pkg/application/options_webview_window.go b/v3/pkg/application/options_webview_window.go
index 7164066e..c2058507 100644
--- a/v3/pkg/application/options_webview_window.go
+++ b/v3/pkg/application/options_webview_window.go
@@ -116,7 +116,7 @@ type WebviewWindowOptions struct {
// KeyBindings is a map of key bindings to functions
KeyBindings map[string]func(window *WebviewWindow)
- // IgnoreMouseEvents will ignore mouse events in the window
+ // IgnoreMouseEvents will ignore mouse events in the window (Windows + Mac only)
IgnoreMouseEvents bool
}
diff --git a/v3/pkg/application/webview_window_linux.go b/v3/pkg/application/webview_window_linux.go
index 75055ddf..80d5b983 100644
--- a/v3/pkg/application/webview_window_linux.go
+++ b/v3/pkg/application/webview_window_linux.go
@@ -34,6 +34,7 @@ type linuxWebviewWindow struct {
lastHeight int
drag dragInfo
lastX, lastY int
+ gtkmenu pointer
}
var (
@@ -357,8 +358,19 @@ func (w *linuxWebviewWindow) run() {
app := getNativeApplication()
- menu := app.getApplicationMenu()
- w.window, w.webview, w.vbox = windowNew(app.application, menu, w.parent.id, w.parent.options.Linux.WebviewGpuPolicy)
+ var menu = w.menu
+ if menu == nil && globalApplication.ApplicationMenu != nil {
+ menu = globalApplication.ApplicationMenu.clone()
+ }
+ if menu != nil {
+ InvokeSync(func() {
+ menu.Update()
+ })
+ w.menu = menu
+ w.gtkmenu = (menu.impl).(*linuxMenu).native
+ }
+
+ w.window, w.webview, w.vbox = windowNew(app.application, w.gtkmenu, w.parent.id, w.parent.options.Linux.WebviewGpuPolicy)
app.registerWindow(w.window, w.parent.id) // record our mapping
w.connectSignals()
if w.parent.options.EnableDragAndDrop {
@@ -403,6 +415,10 @@ func (w *linuxWebviewWindow) run() {
case WindowStateNormal:
}
+ //if w.parent.options.IgnoreMouseEvents {
+ // windowIgnoreMouseEvents(w.window, w.webview, true)
+ //}
+
startURL, err := assetserver.GetStartURL(w.parent.options.URL)
if err != nil {
globalApplication.fatal(err.Error())
@@ -459,6 +475,11 @@ func (w *linuxWebviewWindow) relativePosition() (int, int) {
func (w *linuxWebviewWindow) destroy() {
w.parent.markAsDestroyed()
+ // Free menu
+ if w.gtkmenu != nil {
+ menuDestroy(w.gtkmenu)
+ w.gtkmenu = nil
+ }
windowDestroy(w.window)
}