mirror of
https://github.com/wavetermdev/wails.git
synced 2026-08-05 13:53:43 -07:00
Added menu cloning.
Introduced the ability to clone a menu, along with its submenus, in Linux-based web applications to create a full deep copy. This fixes reusing the application menu for window menus.
This commit is contained in:
committed by
Travis McLane
parent
809863d61a
commit
3d93c83920
+17
-15
@@ -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: "<div style='width: 100%; height: 95%; border: 3px solid red; background-color: \"0000\";'></div>",
|
||||
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: "<div style='width: 100%; height: 95%; border: 3px solid red; background-color: \"0000\";'></div>",
|
||||
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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <JavaScriptCore/JavaScript.h>
|
||||
#include <gtk/gtk.h>
|
||||
@@ -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)
|
||||
|
||||
@@ -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{}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user