wailsapp / wails

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

Webview failed to set AllowExternalDrag to false on Win 10 ( after cross compile on macOS) #3782

Open barats opened 1 month ago

barats commented 1 month ago

Description

I am developing a Wails application on the macOS platform. I cross-compile the executable file on macOS and run it on a Windows 10 system (with -windowsconsole -platform windows/amd64 options so that I could check output details), basically there are 2 main issues:

1. WebView failed to set AllowExternalDrag to false If AllowExternalDrag is not disabled, WebView will automatically open the files that are dragged into it. But frontend projects can not handle full path of file, so I have to disable WebView DnD and handle files at the backend.

2. Wails backend runtime.OnFileDrop(ctx, func(x, y int, paths []string) doesn't work Registered necessary listener onStartup and then onDomReady, but didn't see any evidence that events been triggered.

Build scripts on macOS is : wails build -clean -windowsconsole -platform windows/amd64

Disabled DnD at Wails app options:

DragAndDrop: &options.DragAndDrop{
                EnableFileDrop:     true,
                DisableWebViewDrop: true,
        },
Windows: &windows.Options{
                Theme:                windows.Light,
                WindowIsTranslucent:  false,
                WebviewIsTransparent: false,
                WebviewUserDataPath:  "",
        },

Listen for coming events when DOM ready:

OnDomReady: func(ctx context.Context) {
        some_manager.StartOnFileDrop(ctx) // call runtime.OnFileDrop(ctx, func(x, y int, paths []string) and handle file paths
},

To Reproduce

  1. Build windows/amd64 app on macOS
  2. Move .exe files to Win10 and double click to run
  3. Drag and drop files into app window

Expected behaviour

  1. WebView DnD should be disabled
  2. Backend DnD events should be called

Screenshots

No response

Attempted Fixes

No response

System Details

# Wails
Version | v2.9.2

# System
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
| OS           | MacOS                                                                                                                                                                   |
| Version      | 15.0                                                                                                                                                                    |
| ID           | 24A335                                                                                                                                                                  |
| Go Version   | go1.21.0                                                                                                                                                                |
| Platform     | darwin                                                                                                                                                                  |
| Architecture | amd64                                                                                                                                                                   |
| CPU          | Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz                                                                                                                              |
| GPU          | Chipset Model: Intel Iris Plus Graphics Type: GPU Bus: Built-In VRAM (Dynamic, Max): 1536 MB Vendor: Intel Device ID: 0x8a53 Revision ID: 0x0007 Metal Support: Metal 3 |
| Memory       | 16GB                                                                                                                                                                    |
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

# Dependencies
┌───────────────────────────────────────────────────────────────────────┐
| Dependency                | Package Name | Status    | Version        |
| Xcode command line tools  | N/A          | Installed | 2409           |
| Nodejs                    | N/A          | Installed | 20.15.1        |
| npm                       | N/A          | Installed | 10.7.0         |
| *Xcode                    | N/A          | Installed | 16.0 (16A242d) |
| *upx                      | N/A          | Installed | upx 4.1.0      |
| *nsis                     | N/A          | Installed | v3.10          |
└─────────────────────── * - Optional Dependency ───────────────────────┘

# Diagnosis
 SUCCESS  Your system is ready for Wails development!

Additional context

No response

barats commented 1 month ago

BTW, above code runs perfectly on macOS, but it doesn't work as expected on Win10.

And, I find out that Win10 has a WebView runtime WebView2 Runtime Version '129.0.2792.52' installed. Minimum version required: 94.0.992.31.

It seems that set DisableWebViewDrop to false doesn't work on Webview2 Runtime 129.0.2792.52.

Wails v2.9.2 uses new Go WebView2Loader as default option, I also tried exp_gowebview2loader, but it didn't work either.

Any suggestions?

barats commented 1 month ago

For the first problem WebView failed to set AllowExternalDrag to false

Wails's implement is

    if f.frontendOptions.DragAndDrop != nil && f.frontendOptions.DragAndDrop.DisableWebViewDrop {
        if err := chromium.AllowExternalDrag(false); err != nil {
            f.logger.Warning("WebView failed to set AllowExternalDrag to false!")
        }
    }

Calling chromium.AllowExternalDrag() could be found at wailsapp/go-webview2 repo , which is

func (i *ICoreWebView2Controller4) PutAllowExternalDrop(value bool) error {

    hr, _, err := i.Vtbl.PutAllowExternalDrop.Call(
        uintptr(unsafe.Pointer(i)),
        uintptr(boolToInt(value)),
    )
    if windows.Handle(hr) != windows.S_OK {
        return syscall.Errno(hr)
    }
    return err
}

And then I found MicrosoftEdge/WebView2Feedback issue 278 https://github.com/MicrosoftEdge/WebView2Feedback/issues/278 which gives me a thought.

Should I add some scripts into HTML template that disable dragover and drop events?

And I did add these scripts to my root HTML page

    <script>
        window.addEventListener('dragover',function(e){e.preventDefault();});
        window.addEventListener('drop',function(e){e.preventDefault();});
    </script>

Amazingly, it did stopped DnD Events on window. Though I still have the output warning as usual.

So I guess: the reason for failed to set AllowExternalDrag to false might be caused by some HTML elements that has hidden DnD events registered on start up, so there's no chance to disable it after registered listeners?

leaanthony commented 1 month ago

Ah brilliant! We can inject that for those flags if the main webview2 API is buggy.

barats commented 1 month ago

As for the second issue Wails backend runtime.OnFileDrop(ctx, func(x, y int, paths []string) doesn't work

I found that drop events handling method is a little bit different on platforms.

On macOS function processMessage in v2/internal/frontend/desktop/darwin/frontend.go is like :

if message == "DomReady" {
        if f.frontendOptions.OnDomReady != nil {
            f.frontendOptions.OnDomReady(f.ctx)
        }
        return
    }

    if message == "runtime:ready" {
        cmd := fmt.Sprintf("window.wails.setCSSDragProperties('%s', '%s');", f.frontendOptions.CSSDragProperty, f.frontendOptions.CSSDragValue)
        f.ExecJS(cmd)

        if f.frontendOptions.DragAndDrop != nil && f.frontendOptions.DragAndDrop.EnableFileDrop {
            f.ExecJS("window.wails.flags.enableWailsDragAndDrop = true;")
        }

        return
    }

On Linux function processMessage in v2/internal/frontend/desktop/linux/frontend.go is like :

if message == "runtime:ready" {
        cmd := fmt.Sprintf(
            "window.wails.setCSSDragProperties('%s', '%s');\n"+
                "window.wails.setCSSDropProperties('%s', '%s');\n"+
                "window.wails.flags.deferDragToMouseMove = true;",
            f.frontendOptions.CSSDragProperty,
            f.frontendOptions.CSSDragValue,
            f.frontendOptions.DragAndDrop.CSSDropProperty,
            f.frontendOptions.DragAndDrop.CSSDropValue,
        )

        f.ExecJS(cmd)

        if f.frontendOptions.Frameless && f.frontendOptions.DisableResize == false {
            f.ExecJS("window.wails.flags.enableResize = true;")
        }

        if f.frontendOptions.DragAndDrop.EnableFileDrop {
            f.ExecJS("window.wails.flags.enableWailsDragAndDrop = true;")
        }

But it seems very different on windows, function processMessage in v2/internal/frontend/desktop/windows/frontend.go is like :

if message == "drag" {
        if !f.mainWindow.IsFullScreen() {
            err := f.startDrag()
            if err != nil {
                f.logger.Error(err.Error())
            }
        }
        return
    }

    if message == "runtime:ready" {
        cmd := fmt.Sprintf(
            "window.wails.setCSSDragProperties('%s', '%s');\n"+
                "window.wails.setCSSDropProperties('%s', '%s');",
            f.frontendOptions.CSSDragProperty,
            f.frontendOptions.CSSDragValue,
            f.frontendOptions.DragAndDrop.CSSDropProperty,
            f.frontendOptions.DragAndDrop.CSSDropValue,
        )

        f.ExecJS(cmd)
        return
    }

I don't quite get it, seems that it's missing wails flags settings for events maybe?

@leaanthony

leaanthony commented 1 month ago

We're currently looking at DnD 👍

barats commented 1 month ago

If AllowExternalDrag is not disabled, WebView will automatically open the files that are dragged into it. But frontend projects can not handle full path of file, so I have to disable WebView DnD and handle files at the backend.

Truly sad.....

I compiled my project in Ubuntu and find out that you can NOT disable DnD on WebView and deal with events on backend.

If u disable DnD handling on WebView, things will happen on different platform like this:

  1. Everything's fine on macOS platform, you still able to drag files into app window and get EventsOn triggered at backend.
  2. Win10: You CAN drag and drop files into app window, but EventsOn won't be triggered at backend.
  3. Ubuntu 22.04: You CAN NOT drag and drop files into window, EventsOn won't be triggered at backend either.

Did I just make a terrible mistake? or It is what WebView's behave on different platform?

@leaanthony

barats commented 1 month ago

@leaanthony

I just open-sourced my app that uses Wails. Due to the webview-thing related to this issue, I have to disable DnD support in first release. Hope this issue could be fixed soon, I’m looking forward to it. Many thanks ahead.

BTW, my app is called Resizem and could be found here. https://github.com/barats/resizem

I also would love to see that my app could be collected and displayed at Wails website. Thank u so much for developing such an amazing framework.

barats commented 1 month ago

I released my app Resizem yesterday.

Hopefully, wish my app could be added to wails community showcase and collected in awesome-wails list. I drafted two PRs in wails repos and awesome-wails repo.

https://github.com/wailsapp/wails/pull/3813

https://github.com/wailsapp/awesome-wails/pull/60