-
-
Notifications
You must be signed in to change notification settings - Fork 10.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Emscripten: Handling "external" clipboard #7851
Comments
Who is detecting the event? Is that a paste event emitted from the browser? or it is your app querying key for ctrl+v press and then doing an asynchronous query for clipboard data? Could you e.g. preemptively do this query every time an InputText is activated (via polling |
The detection is from the ImGui side, something like this if (ImGui::GetIO().KeyCtrl && ImGui::IsKeyPressed(ImGuiKey_V))
I didn't think about doing it preemptively. But I know that Firefox does a little popup when you try do do a paste from Javascript to allow/disallow pasting: ![]() If you want to try it yourself, you can use Firefox and go there and click on Paste after copying something in the clipboard outside the browser... So if I were to do it preemptively then I would end up with these popups even if you are not trying to copy the clipboard. |
In that case we may need to design a new API replacement for |
Clearly somebody already noticed the issue raised by this ticket :)
I don't mind looking into your suggestion. Any code I could look at that does something somewhat similar? Thanks |
Nope I cannot think of an example. I believe the caller would probably need to get a unique id (eg a simple sequential integer) and use that when creating and polling the request. Request would naturally elapse if it stops being polled. |
I will spend some cycles on this and report back. Thank you! |
Just wanted to let you know that I am looking into this. I was able to build a prototype with the async API fairly easily (far easier than I thought). I am bumping into some issues with the "Paste" popup displayed by Safari and Firefox as a security measure because they kill event propagation, so the keys (ex: CTRL + V) remained stuck down forever because I never get the "up" event :( You can try for yourself with this 100% pure HTML/javascript test case. I am looking into this as well as other ways of doing this entirely... |
Sorry, |
@Maksons I did not know about this project but in the end I am looking at similar ways of going around the problem. Note that I tried his/her demo and it does not really work on macOS due to the "paste" event being generated by "Meta + V" (and so it appears in the log window, but it does not get pasted in the Clipboard demo window). It is definitely NOT an easy problem to make it work cross browser and cross platform... That is what I am trying to achieve as best I can. Note that the async API for paste I have right now works quite well with Chrome and Edge (this async paste API is not offered in the project you linked to). And I have found ways to make it work decently with Safari and Firefox. |
Hi @ocornut. I spent the last couple of weeks at this problem and I think I have a result that I am quite pleased with. First of all, the asynchronous API that I implemented in the library only works decently in Chrome and Edge (although you still get a warning the first time you use it). In Firefox and Safari, you get this "Paste" popup window which swallows all keyboard events. Although I added code to detect this situation, the fact that any other code using this API now needs to handle this asynchronicity API is burdensome and hard to implement. In fact, I have even deprecated this API to simplify the code of the library as well... I went a completely different route and instead "embrace" the browser/OS API: what this means is now I am relying on the "paste" (as well as "copy" and "cut") events raised by the browser. And it just works in pretty much any browser I have tried it in, with no (for Windows)/minimal (for macOS) changes to ImGui. Of course, there is a "catch": in order to receive these events you must be using the proper keyboard shortcuts for the platform it is running on. As a result this means that
Of course my library now automatically detects the runtime platform and offer an API to access it: Note that if on macOS, you decide to still keep the PC/Linux keyboard shortcuts, it means that paste from the OS clipboard won't work, but everything else works including copy TO clipboard (I have tested on Safari with this scenario). I personally think this is the right way to go: on macOS, users are used to the macOS shortcuts (and I believe you mentioned it in another thread as something you wanted to do). On PC/Linux, there is no change so it just works transparently... So I am just curious what you think of the solution. I have a build done with a not-yet released version of emscripten-glfw so you can try it for yourself. In this demo, the code added is this in if(emscripten_glfw_is_apple_platform())
{
ImGuiIO& io = ImGui::GetIO();
io.ConfigMacOSXBehaviors = true;
printf("Detected macOS platform: GetSuperPlusKeyTimeout [%d, %d]\n",
emscripten::glfw3::GetSuperPlusKeyTimeout(),
emscripten::glfw3::GetSuperPlusKeyRepeatTimeout());
io.KeyRepeatDelay = static_cast<float>(emscripten::glfw3::GetSuperPlusKeyTimeout()) / 1000.f;
io.KeyRepeatRate = static_cast<float>(emscripten::glfw3::GetSuperPlusKeyRepeatTimeout()) / 1000.f;
} The I also implemented another version of openURL which works without blocking popups which you can try by clicking any link in the demo... void ImGui_ImplGlfw_EmscriptenOpenURL(char const* url)
{
if(url)
emscripten::glfw3::OpenURL(url);
} |
Following up on this, I have now released emscripten-glfw v3.4.0.20240817 with the changes mentioned. Once released with emscripten (unclear about timing), I will create a PR for changes in ImGui (very small PR). As an FYI I have updated my real live application WebGPU Shader Toy to use this latest version. You can try it out and you will see that the main editor supports copy/paste with the desktop as well as all text fields (like the one in the "Rename" popup) and this one is an The only changes in my code is this: ImGuiIO& io = ImGui::GetIO();
io.ConfigMacOSXBehaviors = emscripten::glfw3::IsRuntimePlatformApple();
// essentially disable repeat on Meta + Key
emscripten::glfw3::SetSuperPlusKeyTimeouts(10, 10);
|
Hello, |
I believe so. When using emscripten 3.1.65+ (current version is 3.1.66) it will automatically work for pc/linux and it will work for macos as soon as the changes you committed recently are released. Of course this assumes using emscripten-glfw with ImGui instead of the built-in implementation |
Version/Branch of Dear ImGui:
Version 1.91.0
Back-ends:
imgui_impl_glfw.cpp
Compiler, OS:
emscripten / browser
Full config/build information:
No response
Details:
With the release of ImGui 1.91.0 and the support for
emscripten-glfw
, as you know, the clipboard is now supported in the browser environment. For example, you can now copy the build configuration (which can try for yourself with the demo I pushed with the PR)If you copy to the clipboard by calling
glfwSetClipboardString
, then I store the string locally and push it to the external clipboard (which is why you can paste it outside the browser).If you then paste from the clipboard by calling
glfwGetClipboardString
, then the clipboard string that was stored previously is returned.In other words, copy/paste from within the application works great.
The issue comes with pasting from the "external" clipboard: the Javascript API, which is the API that I need to use is asynchronous. For this purpose, in the latest version of
emscripten-glfw
, I added a new API which reflects this API:I am using this API in my recently released WebGPU Shader Toy tool for the code editor class (
TextEditor
) because I am in control of this logic: when I detect a "Paste" event (CTRL+V), I call the asynchronous API and when I receive the result, I do the actual Paste action.Of course this does not work with
ImGui::InputText
and I wanted to ask you if you could think of a way, or giving me pointers of whether this would be possible to do in ImGui (I tried to look at Shortcut routing but I don't know if that is even the right place to start...). I would be more than happy to do a PR for the work if this is something that is possible at all. Otherwise I could implement an entirely new control for my project.Thank you
Screenshots/Video:
No response
Minimal, Complete and Verifiable Example code:
No response
The text was updated successfully, but these errors were encountered: