5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-02 23:51:44 +08:00

[v2, linux] Make sure to execute the menu callbacks on a new goroutine (#1403)

* Make sure to execute the menu callbacks on a new goroutine
* Fix assertion message when opening file dialogs by passing the correct parent window
This commit is contained in:
stffabi 2022-05-17 12:45:48 +02:00 committed by GitHub
parent 35b1dfdd2a
commit c97e1c50af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 8 deletions

View File

@ -11,8 +11,11 @@ extern void blockClick(GtkWidget* menuItem, gulong handler_id);
extern void unblockClick(GtkWidget* menuItem, gulong handler_id); extern void unblockClick(GtkWidget* menuItem, gulong handler_id);
*/ */
import "C" import "C"
import "unsafe" import (
import "github.com/wailsapp/wails/v2/pkg/menu" "unsafe"
"github.com/wailsapp/wails/v2/pkg/menu"
)
func GtkMenuItemWithLabel(label string) *C.GtkWidget { func GtkMenuItemWithLabel(label string) *C.GtkWidget {
cLabel := C.CString(label) cLabel := C.CString(label)
@ -37,6 +40,10 @@ func GtkRadioMenuItemWithLabel(label string, group *C.GSList) *C.GtkWidget {
//export handleMenuItemClick //export handleMenuItemClick
func handleMenuItemClick(gtkWidget unsafe.Pointer) { func handleMenuItemClick(gtkWidget unsafe.Pointer) {
// Make sure to execute the final callback on a new goroutine otherwise if the callback e.g. tries to open a dialog, the
// main thread will get blocked and so the message loop blocks. As a result the app will block and shows a
// "not responding" dialog.
item := gtkSignalToMenuItem[(*C.GtkWidget)(gtkWidget)] item := gtkSignalToMenuItem[(*C.GtkWidget)(gtkWidget)]
switch item.Type { switch item.Type {
case menu.CheckboxType: case menu.CheckboxType:
@ -51,7 +58,7 @@ func handleMenuItemClick(gtkWidget unsafe.Pointer) {
C.gtk_check_menu_item_set_active(C.toGtkCheckMenuItem(unsafe.Pointer(gtkCheckbox)), checked) C.gtk_check_menu_item_set_active(C.toGtkCheckMenuItem(unsafe.Pointer(gtkCheckbox)), checked)
C.unblockClick(gtkCheckbox, handler) C.unblockClick(gtkCheckbox, handler)
} }
item.Click(&menu.CallbackData{MenuItem: item}) go item.Click(&menu.CallbackData{MenuItem: item})
case menu.RadioType: case menu.RadioType:
gtkRadioItems := gtkRadioMenuCache[item] gtkRadioItems := gtkRadioMenuCache[item]
active := C.gtk_check_menu_item_get_active(C.toGtkCheckMenuItem(gtkWidget)) active := C.gtk_check_menu_item_get_active(C.toGtkCheckMenuItem(gtkWidget))
@ -63,11 +70,11 @@ func handleMenuItemClick(gtkWidget unsafe.Pointer) {
C.unblockClick(gtkRadioItem, handler) C.unblockClick(gtkRadioItem, handler)
} }
item.Checked = true item.Checked = true
item.Click(&menu.CallbackData{MenuItem: item}) go item.Click(&menu.CallbackData{MenuItem: item})
} else { } else {
item.Checked = false item.Checked = false
} }
default: default:
item.Click(&menu.CallbackData{MenuItem: item}) go item.Click(&menu.CallbackData{MenuItem: item})
} }
} }

View File

@ -314,7 +314,7 @@ gboolean messageDialog(gpointer data) {
void extern processOpenFileResult(void*); void extern processOpenFileResult(void*);
typedef struct OpenFileDialogOptions { typedef struct OpenFileDialogOptions {
void* webview; GtkWindow* window;
char* title; char* title;
char* defaultFilename; char* defaultFilename;
char* defaultDirectory; char* defaultDirectory;
@ -339,7 +339,7 @@ gboolean opendialog(gpointer data) {
if (options->action == GTK_FILE_CHOOSER_ACTION_SAVE) { if (options->action == GTK_FILE_CHOOSER_ACTION_SAVE) {
label = "_Save"; label = "_Save";
} }
GtkWidget *dlgWidget = gtk_file_chooser_dialog_new(options->title, options->webview, options->action, GtkWidget *dlgWidget = gtk_file_chooser_dialog_new(options->title, options->window, options->action,
"_Cancel", GTK_RESPONSE_CANCEL, "_Cancel", GTK_RESPONSE_CANCEL,
label, GTK_RESPONSE_ACCEPT, label, GTK_RESPONSE_ACCEPT,
NULL); NULL);
@ -854,7 +854,7 @@ func (w *Window) Quit() {
func (w *Window) OpenFileDialog(dialogOptions frontend.OpenDialogOptions, multipleFiles int, action C.GtkFileChooserAction) { func (w *Window) OpenFileDialog(dialogOptions frontend.OpenDialogOptions, multipleFiles int, action C.GtkFileChooserAction) {
data := C.OpenFileDialogOptions{ data := C.OpenFileDialogOptions{
webview: w.webview, window: w.asGTKWindow(),
title: C.CString(dialogOptions.Title), title: C.CString(dialogOptions.Title),
multipleFiles: C.int(multipleFiles), multipleFiles: C.int(multipleFiles),
action: action, action: action,