godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
88.63k stars 20.1k forks source link

HTML5 games cannot write to clipboard on Chrome #81252

Open Lunarexxy opened 1 year ago

Lunarexxy commented 1 year ago

Godot version

4.1.1

System information

Windows 10 - Chrome Version 116.0.5845.141 (Official Build) (64-bit)

Issue description

When a HTML5 game attempts to use DisplayServer.clipboard_set(str) in Chrome, this error appears.

image

While it claims to be a permission issue, I've tried forcing Chrome to allow any clipboard access, but this had no effect.

I'm guessing Godot is simply not accessing the Clipboard API in the way Chrome expects, when running DisplayServer.clipboard_set("some string")

Steps to reproduce

  1. Create a script that attempts to set the clipboard contents through DisplayServer.clipboard_set("some string")
  2. Export the game as a Web build
  3. Run it in the latest version of Chrome
  4. The console will print the error when the clipboard is set, and nothing is written to the clipboard

Minimal reproduction project

It's a bit tricky to make an MRP for this since testing it requires uploading it somewhere that allows a secure context so it can be opened in Chrome. The project where I have the issue is here, though: https://lunarexxy.itch.io/tudaily

There's a Copy to Clipboard button at the bottom of the screen which only runs DisplayServer.clipboard_set("some string"). Hopefully that will suffice.

Calinou commented 1 year ago

While it claims to be a permission issue, I've tried forcing Chrome to allow any clipboard access, but this had no effect.

There is no clipboard permission you need to enable, but web browsers only allow clipboard access immediately after an user action was performed (such as clicking something).

This is likely the issue: your project must be reacting to an user action at the time you are getting or setting clipboard data. You cannot passively listen to clipboard events while the project is running.

While your project seems to copy to clipboard after user input, it's also possible that the web browser is unable to detect clicks within the WebAssembly window (it's not a DOM element). Web browsers have historically struggled with clipboard support for anything that isn't part of the DOM.

Lunarexxy commented 1 year ago

That makes sense, thank you for the info. I did some further testing while exploring workarounds, and found that copying from a TextEdit (both via the right-click menu and Ctrl-C) had the same error, so it might affect all types of user input in the WebAssembly window.

Somewhat related, I noticed that after running DisplayServer.clipboard_set(), even if the function failed and nothing was really set, DisplayServer.clipboard_get() would still return the set string, ignoring what the user's clipboard actually contains. Is that intended behavior? (maybe it's for some kind of caching to work around some asynchronous thing?)

image

Edit: Actually, DisplayServer.clipboard_get() seems to always completely ignore what's in the user's clipboard on Web builds, except when run from the Editor. If it's called without having run DisplayServer.clipboard_set(), it just returns an empty string on both Firefox and Chrome.

alanenggb commented 9 months ago

Related to #83752

I found a barely decent workaround using JavaScriptBridge.eval to define a clipboard-reading function (that also asks the user to grant clipboard read permission), executing it when the user press the action "ui_paste", then "listen" to a global variable with the clipboard data. There are also a few shenanigans to convert the data to a texture if anyone needs (I'm using some TextureRect's in my project).

Please let me know if you found another workaround!

Minimal reproduction project: bug_clipboard_web_4.2_workaround.zip