Operating system or device, Godot version, GPU Model and driver (if graphics related):
Issue description:
System clipboard contents cannot be pasted in controls such as LineEdit. The game has its own clipboard contents and it is not shared with the system.
OS.get_clipboard() stays empty unless we copy text from the game itself.
This is confusing for users because HTML input fields do share their clipboard with the system.
Steps to reproduce:
LineEdit.php -S when I'm in a hurry or too lazy, to avoid file:// issues)LineEdit.Isn't this a security concern? Maybe HTML input fields do share input (because they are handled by the browser itself, not the web app), but an exported Godot game is seen like a Javascript web app AFAIK, which means LineEdit is not seen like an HTML input field. Such things should not be able to just look at your clipboard, login name, filesystem or stuff like this without consent. For this reason it would even be possible that, even if working, this feature would be limited to specific cases or would pop a window on the user's browser before returning anything (which would freeze the game as it is now btw).
Some info: https://tutorialzine.com/2016/10/quick-tip-accessing-the-clipboard-with-javascript
Thanks @Zylann for the link and the concern!
Clipboard access has been granted to web apps by browser makers, and a godot exported game is a web app like any other. Why should it deprive itself of a feature that the rest of the web enjoys?
It is a privacy concern, but clipboard contents have always been considered fair game because it's their very ubiquitousness that makes them useful.
I'm not sure how to implement that feature (or fix that bug, whatever), nor where the related code is. It is a critical component of my game, though, and it makes me a sad panda. Any help would be appreciated.
@Goutte well, I'm not saying it should be the way I described, but the resources I looked up by doing a search imply that it actually IS like that. But I could be wrong, we are in 2017 now :p
I just tested the Selection API in a fiddle, and it seems to be working without prompting for any permissions. Good for us!
Inquiring furthermore, I found an interesting byt of code here.
Maybe @reduz can help us ? It's been four years, though.
Many of the comments in OS_JavaScript, like that one, are remnants from OS_Android, from which that implementation was copied as a base.
The issue with clipboard sync is pasting. Godot needs the OS clipboard data during the keydown event, but we only get the that data in the paste event, which occurs after the keydown event. So it has to be hacked. Selection API doesn't apply to us because we render text manually using FreeType + WebGL
Would that help if support for the paste event was added to emscripten ?
I can't find it in its list of events, nor in its issues.
Could we figure out the currently focused control node from os_javascript.cpp, if emscripten had paste support ?
No need for Emscripten APIs, JavaScript can be used directly, similar as already done for blur, focus, mouseover and mouseleave.
The currently focused Control receives the Ctrl+V input event in its _gui_input callback and handles pasting there if the node class allows text input.
Thanks so much for the invaluable help, @eska014 !
Would it be appropriate to trigger a MainLoop::NOTIFICATION_WM_PASTE in the fashion of mouseleave and others ?
Since such notifications don't seem to be able to transport parameters, I'm not sure.
So far, I've got :
paste eventThere's no need to implement copy/paste, this is implemented per Control class in _gui_input. What needs to happen is a call to OS::set_clipboard, passing in the data of the actual operating system's clipboard, overriding Godot's internal clipboard. This needs to happen before _gui_input is called.
The actual operating system's clipboard can be read from the paste event, but it occurs too late.
Additionally, that event is only fired when hitting Ctrl+V, so it can't work for right click → Paste either.
document.execCommand('paste') might work, but is only available to WebExtensions.
The new Async Clipboard API might work, but isn't available yet.
This is partially addressed in #29298, but there are some limitations as described in that PR.
Sorry to necro this issue, particularly because I have no code to contribute. Just looking to bump this issue, noting that now with the focus on web export for the in-browser editor feature, it may be an appropriate time to readdress the clipboard issue.
Personally I want to use godot for a browser-based company-internal application (not a game per se), but lack of reliable/cross-browser clipboard support is a gating issue.
Regardless, thank you to the creators and contributors for this fine project!
@bfishman I'm not sure if it can be fixed completely, given how browsers have hardened their clipboard security recently. Do Unity and UE4 web exports suffer from the same problem?
@bfishman did you see #29298 linked above? Clipboard support in HTML5 is currently implemented the best we can on browser that provides that feature. There isn't much we can do to improve that as of now.
@Faless Should we close this as "fixed as best we can" then?
@Faless Should we close this as "fixed as best we can" then?
Yeah, I think we should, I thought there was room for improvements in 4.0 since deferred input reporting would fix the first-paste issue, but that causes a whole set of new problems (most OS actions are only allowed during DOM input callbacks).
Closing.
@Faless thanks for the reply. I'll explore implementing my own 'hack' to keep the engine's clipboard in sync with the OS.
I don't really understand the intricacies of this yet so pardon the potentially naive question -- do you think it's possible to trigger a copy or paste event using an in-engine GUI button (as opposed to ctrl+v or ctrl)? Obviously not a global solution but it would be enough of a workaround for my use case (many of the potential users aren't power users and may actually find a copy/paste button more useful than the normal shortcuts)
do you think it's possible to trigger a copy or paste event using an in-engine GUI button
For browser that supports the Clipboard API readText function (chrome) yes. Just call OS.get_clipboard() during the pressed signal of your button.