wailsapp / wails

Create beautiful applications using Go
https://wails.io
MIT License
25.39k stars 1.23k forks source link

[v2] runtime.SomeDialog causes application to crash on linux #1402

Closed lambdajack closed 2 years ago

lambdajack commented 2 years ago

Description

Calling runtime.OpenDirectorDialog (or any of the dialog options described in the docs here) causes the application to crash on linux.

Tested on fresh ubuntu and fedora updated vms (as well as bare metal ubuntu).

The exact same application works as expected in windows.

To Reproduce

  1. wails init -n menutest -t react-ts
  2. Set up a menu on the app like this:
    
    package main

import ( "context" "embed" "fmt"

"github.com/wailsapp/wails/v2"
"github.com/wailsapp/wails/v2/pkg/menu"
"github.com/wailsapp/wails/v2/pkg/options"
"github.com/wailsapp/wails/v2/pkg/runtime"

)

//go:embed frontend/dist var assets embed.FS

type App struct { ctx context.Context } func NewApp() App { return &App{} } func (a App) startup(ctx context.Context) { a.ctx = ctx } func (a App) setMenu() menu.Menu { return menu.NewMenuFromItems( menu.SubMenu("File", menu.NewMenuFromItems( // --------------------------------------------------------------------- menu.Text("Dialog 1", nil, func( *menu.CallbackData) { fmt.Println("Dialog 1 callback fires") runtime.OpenMultipleFilesDialog(a.ctx, runtime.OpenDialogOptions{ Title: "Application crash on linux", }) }), // --------------------------------------------------------------------- menu.Text("Dialog 2", nil, func( menu.CallbackData) { fmt.Println("Dialog 2 callback fires") runtime.OpenDirectoryDialog(a.ctx, runtime.OpenDialogOptions{ Title: "Application crash on linux", }) }), // --------------------------------------------------------------------- menu.Text("Quit", nil, func(_ menu.CallbackData) { fmt.Println("Quit callback fires (works on all os)") runtime.Quit(a.ctx) }), ))) }

func main() { app := NewApp()

err := wails.Run(&options.App{
    Title:     "Menu Does not work on linux",
    Width:     1024,
    Height:    768,
    Assets:    assets,
    Menu: app.setMenu(), // the dialog items work on windows, not linux (fedora & ubuntu tested)
    OnStartup: app.startup,
    Bind: []interface{}{
        app,
    },
})

if err != nil {
    println("Error:", err)
}

}

3. Remove the default `Greet` function dependency from the frontend if you copied/pasted the above.
4. `wails dev` or `wails build`
5. The application will run as expected - however when you try to select one of the file/dialog options, the window will crash and become totally unresponsive. (try typing in the box or clicking the buttons).
6. Get the same project over to a windows vm and run it. It will work as expected.

### Expected behaviour

The dialog options should open on linux the same way they do on windows.

### Screenshots

![Screenshot from 2022-05-16 15-02-07](https://user-images.githubusercontent.com/69592559/168615798-9c8aa6e8-dd5d-4def-b457-bcba6a882227.png)
_Fig1 - application crash on ubuntu_

![Screenshot from 2022-05-16 15-32-10](https://user-images.githubusercontent.com/69592559/168616983-76acf191-4e8d-4424-9621-2c95d1e02d5f.png)
_Fig2 - application crash on fedora_

![Screenshot from 2022-05-16 15-00-11](https://user-images.githubusercontent.com/69592559/168615800-dd506657-ee71-4c1a-9619-52cbe6bd48ed.png)
_Fig3 - working on windows_

### Attempted Fixes

I have tried implementing the menu without using the `menu.NewMenuFromItems` helper function, however the problem remains.

I have also tried on `master`.

### System Details

```bash
1. UBUNTU:

Wails CLI v2.0.0-beta.36

Scanning system - Please wait (this may take a long time)...Done.

System
------
OS:             Ubuntu
Version:        22.04
ID:             ubuntu
Go Version:     go1.18.1
Platform:       linux
Architecture:   amd64

Wails
------
Version:                v2.0.0-beta.36
Revision:               35b1dfdd2a2165b29ef5c2728d3adbd57a062710
Modified:               false
Package Manager:        apt

Dependency      Package Name            Status          Version
----------      ------------            ------          -------
*docker         docker.io               Installed       20.10.14
gcc             build-essential         Installed       12.9ubuntu3
libgtk-3        libgtk-3-dev            Installed       3.24.33-1ubuntu1
libwebkit       libwebkit2gtk-4.0-dev   Installed       2.36.0-2ubuntu1
npm             npm                     Installed       8.9.0
*nsis           nsis                    Installed       v3.08-2
pkg-config      pkg-config              Installed       0.29.2

* - Optional Dependency

Diagnosis
---------
Your system is ready for Wails development!

If Wails is useful to you or your company, please consider sponsoring the project:
https://github.com/sponsors/leaanthony

2: FEDORA:

Wails CLI v2.0.0-beta.36

Scanning system - Please wait (this may take a long time)...Done.

System
------
OS:             Ubuntu
Version:        22.04
ID:             ubuntu
Go Version:     go1.18.1
Platform:       linux
Architecture:   amd64

Wails
------
Version:                v2.0.0-beta.36
Revision:               35b1dfdd2a2165b29ef5c2728d3adbd57a062710
Modified:               false
Package Manager:        apt

Dependency      Package Name            Status          Version
----------      ------------            ------          -------
*docker         docker.io               Installed       20.10.14
gcc             build-essential         Installed       12.9ubuntu3
libgtk-3        libgtk-3-dev            Installed       3.24.33-1ubuntu1
libwebkit       libwebkit2gtk-4.0-dev   Installed       2.36.0-2ubuntu1
npm             npm                     Installed       8.9.0
*nsis           nsis                    Installed       v3.08-2
pkg-config      pkg-config              Installed       0.29.2

* - Optional Dependency

Diagnosis
---------
Your system is ready for Wails development!

If Wails is useful to you or your company, please consider sponsoring the project:
https://github.com/sponsors/leaanthony
  1. WINDOWS:
    
    Wails CLI v2.0.0-beta.36

Scanning system - Please wait (this may take a long time)...Done.

System

OS: Windows 10 Enterprise Evaluation Version: 2009 (Build: 22000) ID: 21H2 Go Version: go1.18.1 Platform: windows Architecture: amd64

Wails

Version: v2.0.0-beta.36

Dependency Package Name Status Version


WebView2 N/A Installed 101.0.1210.47 npm N/A Installed 8.5.5 upx N/A Available nsis N/A Available

Diagnosis

Your system is ready for Wails development! Optional package(s) installation details:

If Wails is useful to you or your company, please consider sponsoring the project: https://github.com/sponsors/leaanthony

Additional context

No response

leaanthony commented 2 years ago

Thanks for the very detailed report Jack 🙏 It's very likely to be a threading issue, but interesting that @ianmjones hasn't seen this.

stffabi commented 2 years ago

Would be interesting to see if PR #1392 would fix this issue. @lambdajack Would it be possible for you to give that PR a try? That would be really awesome

lambdajack commented 2 years ago

Happy to help @leaanthony - you are both onto something with the threading.

@stffabi interestingly your PR #1392 has some positive effect on the problem, but does not resolve the issue completely.

Using #1392 the dialog windows themselves open as expected (excellent!) (see screenshots below). I am able to navigate around the file system and highlight files/folders etc...

The problems resume however, when trying to either 'Cancel' the dialog, or 'Open' the selected files/folders. When trying to interact with the Dialog's native buttons, the application crashes again. This appears to be the case with each of the runtime.Dialog functions.

Using the same PR, the application still functions as expected and dialog windows remain responsive on windows.

It appears GTK may be somewhat involved, as I get the following errors in the terminal, only when clicking a dialog native button (like 'Cancel' or 'OK'):

Ubuntu:

Dialog 2 callback fires

(boilerplate-dev-linux-amd64:1246185): Gtk-CRITICAL **: 02:48:18.525: gtk_window_set_transient_for: assertion 'parent == NULL || GTK_IS_WINDOW (parent)' failed

Fedora:

(process:27238): GLib-CRITICAL **: 02:53:59.671: Failed to set scheduler settings: Operation not permitted
Dialog 2 callback fires

(boilerplate-dev-linux-amd64:27210): Gtk-CRITICAL **: 02:54:01.700: gtk_window_set_transient_for: assertion 'parent == NULL || GTK_IS_WINDOW (parent)' failed

Screenshot from 2022-05-17 03-25-15 Screenshot from 2022-05-17 03-24-27 Screenshot from 2022-05-17 03-15-30

Thanks for the quick response on this one guys - I'll have a look into it also, but I must be honest, GTK is not my forte! Though I suppose it might just be that GTK is looking for something on the wrong thread?

Let me know if there's anything more I can do!

stffabi commented 2 years ago

@lambdajack Thanks for testing #1392

I was able to reproduce the problem on my latest Fedora on arm64. It seems like it get's triggered when the dialogs are opened through the menu callback. From the message "is not responding" I suspected that the main thread is somehow blocked and this stopped GTK from processing messages for the native part. Adding a go before opening the dialogs got them working.

At line 28 we are waiting for the results of the dialog and that's going to block the message loop since OpenFileDialog is called from the menu callback which is on the main thread: https://github.com/wailsapp/wails/blob/35b1dfdd2a2165b29ef5c2728d3adbd57a062710/v2/internal/frontend/desktop/linux/dialog.go#L26-L33

I think we should call the menu click callbacks on a new goroutine and that should fix the issue. @leaanthony do you see a problem with that? I've created PR #1403 which executes the callbacks in another goroutine, this is without the changes from #1392, nevertheless it should fix the issue. @lambdajack could you please give it another try?

lambdajack commented 2 years ago

Great stuff @stffabi! #1403 works as expected on ubuntu, fedora and windows for me. I wasn't able to cause a crash on that PR.

I am still seeing console errors on linux when pressing the menu button to open the dialog, but they don't appear to be fatal as the application remains responsive and the function return values are as expected, even after many dialog open/close ops:

Windows shows no console errors.

Ubuntu:

Dialog 1 callback fires

(boilerplate-dev-linux-amd64:1380611): Gtk-CRITICAL **: 08:27:01.937: gtk_window_set_transient_for: assertion 'parent == NULL || GTK_IS_WINDOW (parent)' failed

Fedora:

Dialog 1 callback fires

(boilerplate-dev-linux-amd64:31086): Gtk-CRITICAL **: 08:28:51.894: gtk_window_set_transient_for: assertion 'parent == NULL || GTK_IS_WINDOW (parent)' failed
stffabi commented 2 years ago

@lambdajack Awesome thanks so much for testing it and your feedback.

Yeah, I've just pushed a new commit to the PR, which fixes those assertion messages.