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:
parent
35b1dfdd2a
commit
c97e1c50af
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user