From db5553ec750c1459cf1b1a82ee9a685cd11b184c Mon Sep 17 00:00:00 2001 From: abichinger Date: Sun, 24 Mar 2024 06:51:45 +0100 Subject: [PATCH] [linux] fix closing of custom context menu #3329 (#3330) * [linux] fix closing of custom context menu * Update changelog --------- Co-authored-by: Lea Anthony --- mkdocs-website/docs/en/changelog.md | 1 + v3/pkg/application/linux_cgo.go | 33 ++++++++++++++++++++++ v3/pkg/application/webview_window_linux.go | 32 ++++++++++++--------- 3 files changed, 52 insertions(+), 14 deletions(-) diff --git a/mkdocs-website/docs/en/changelog.md b/mkdocs-website/docs/en/changelog.md index 1606420e575..eaa7d0dc921 100644 --- a/mkdocs-website/docs/en/changelog.md +++ b/mkdocs-website/docs/en/changelog.md @@ -52,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Correctly compute `startURL` across multiple `GetStartURL` invocations when `FRONTEND_DEVSERVER_URL` is present. [#3299](https://github.com/wailsapp/wails/pull/3299) - Fix the JS type of the `Screen` struct to match its Go counterpart by [@fbbdev](https://github.com/fbbdev) in [#3295](https://github.com/wailsapp/wails/pull/3295) - Fix the `WML.Reload` method to ensure proper cleanup of registered event listeners by [@fbbdev](https://github.com/fbbdev) in [#3295](https://github.com/wailsapp/wails/pull/3295) +- Fix custom context menu closing immediately on linux by [@abichinger](https://github.com/abichinger) in [#3330](https://github.com/wailsapp/wails/pull/3330) - Fix the output path and extension of model files produced by the binding generator by [@fbbdev](https://github.com/fbbdev) in [#3334](https://github.com/wailsapp/wails/pull/3334) - Fix the import paths of model files in JS code produced by the binding generator by [@fbbdev](https://github.com/fbbdev) in [#3334](https://github.com/wailsapp/wails/pull/3334) diff --git a/v3/pkg/application/linux_cgo.go b/v3/pkg/application/linux_cgo.go index 8c7c2d27f95..07b50144b2e 100644 --- a/v3/pkg/application/linux_cgo.go +++ b/v3/pkg/application/linux_cgo.go @@ -64,6 +64,7 @@ extern gboolean handleFocusEvent(GtkWidget*, GdkEvent*, uintptr_t); extern void handleLoadChanged(WebKitWebView*, WebKitLoadEvent, uintptr_t); void handleClick(void*); extern gboolean onButtonEvent(GtkWidget *widget, GdkEventButton *event, uintptr_t user_data); +extern gboolean onMenuButtonEvent(GtkWidget *widget, GdkEventButton *event, uintptr_t user_data); extern void onDragNDrop( void *target, GdkDragContext* context, @@ -361,6 +362,13 @@ func appDestroy(application pointer) { C.g_application_quit((*C.GApplication)(application)) } +func (w *linuxWebviewWindow) contextMenuSignals(menu pointer) { + c := NewCalloc() + defer c.Free() + winID := unsafe.Pointer(uintptr(C.uint(w.parent.ID()))) + C.signal_connect(unsafe.Pointer(menu), c.String("button-release-event"), C.onMenuButtonEvent, winID) +} + func (w *linuxWebviewWindow) contextMenuShow(menu pointer, data *ContextMenuData) { geometry := C.GdkRectangle{ x: C.int(data.X), @@ -376,6 +384,7 @@ func (w *linuxWebviewWindow) contextMenuShow(menu pointer, data *ContextMenuData C.GDK_GRAVITY_NORTH_WEST, (*C.GdkEvent)(&event), ) + w.ctxMenuOpened = true } func (a *linuxApp) getCurrentWindowID() uint { @@ -1329,6 +1338,30 @@ func onButtonEvent(_ *C.GtkWidget, event *C.GdkEventButton, data C.uintptr_t) C. return C.gboolean(0) } +//export onMenuButtonEvent +func onMenuButtonEvent(_ *C.GtkWidget, event *C.GdkEventButton, data C.uintptr_t) C.gboolean { + // Constants (defined here to be easier to use with purego) + GdkButtonRelease := C.GDK_BUTTON_RELEASE // 7 + + windowId := uint(C.uint(data)) + window := globalApplication.getWindowForID(windowId) + if window == nil { + return C.gboolean(0) + } + lw, ok := (window.(*WebviewWindow).impl).(*linuxWebviewWindow) + if !ok { + return C.gboolean(0) + } + + // prevent custom context menu from closing immediately + if event.button == 3 && int(event._type) == GdkButtonRelease && lw.ctxMenuOpened { + lw.ctxMenuOpened = false + return C.gboolean(1) + } + + return C.gboolean(0) +} + //export onDragNDrop func onDragNDrop(target unsafe.Pointer, context *C.GdkDragContext, x C.gint, y C.gint, seldata unsafe.Pointer, info C.guint, time C.guint, data unsafe.Pointer) { var length C.gint diff --git a/v3/pkg/application/webview_window_linux.go b/v3/pkg/application/webview_window_linux.go index 28df0f4f3c7..034655333ee 100644 --- a/v3/pkg/application/webview_window_linux.go +++ b/v3/pkg/application/webview_window_linux.go @@ -20,20 +20,21 @@ type dragInfo struct { } type linuxWebviewWindow struct { - id uint - application pointer - window pointer - webview pointer - parent *WebviewWindow - menubar pointer - vbox pointer - menu *Menu - accels pointer - lastWidth int - lastHeight int - drag dragInfo - lastX, lastY int - gtkmenu pointer + id uint + application pointer + window pointer + webview pointer + parent *WebviewWindow + menubar pointer + vbox pointer + menu *Menu + accels pointer + lastWidth int + lastHeight int + drag dragInfo + lastX, lastY int + gtkmenu pointer + ctxMenuOpened bool } var ( @@ -61,6 +62,9 @@ func (w *linuxWebviewWindow) openContextMenu(menu *Menu, data *ContextMenuData) } if menu.impl == nil { ctxMenu.update() + + native := ctxMenu.menu.impl.(*linuxMenu).native + w.contextMenuSignals(native) } native := ctxMenu.menu.impl.(*linuxMenu).native