-
Notifications
You must be signed in to change notification settings - Fork 101
Add support for wasm32 + web #160
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
base: master
Are you sure you want to change the base?
Conversation
complexspaces
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the PR. I think the approach here makes sense for typical web applications. I'm not a web developer though 😅.
Question: Do you have the ability to test this in Safari? I know their Clipboard APIs are a bit different compared to Firefox and Chromium. I have the ability to test it myself but would need an example WASM app to run.
src/platform/wasm.rs
Outdated
| const GLOBAL_CLIPBOARD_OBJECT: &str = "__arboard_global_clipboard"; | ||
|
|
||
| pub(crate) fn new() -> Result<Self, Error> { | ||
| let window = web_sys::window().ok_or(Error::ClipboardNotSupported)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: Can this approach work in service workers/background workers? If not we can keep this hardcoded to window instead of global but that should be documented in the Clipboard documentation or similar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately web workers cannot be supported - the clipboard API is not available in web workers (see the note on this page). I will add some documentation to mention this.
src/platform/wasm.rs
Outdated
| } | ||
|
|
||
| pub(crate) fn clear(self) -> Result<(), Error> { | ||
| let _ = self.clipboard.inner.write(&js_sys::Array::default()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the various clipboard calls failing return Error::Unknown?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The calls with let _ = don't fail immediately; they return a Promise that resolves once the browser has updated the clipboard contents. Since this is a synchronous API, I just fire and forget the promise here.
The only instances in which these calls asynchronously fail (according to Mozilla docs) is if the page doesn't have permission to write to the user's clipboard. Clipboard permissions are granted with transient activation - that is, once the user interacts with the page, writing to the clipboard is allowed.
It would be nice if there was a way to report the error here. The fire and forget approach is a bit jank - but it does work for my use case, which is just handling normal copy/paste interactions with egui on the web.
|
I've gone ahead and attempted to address your feedback! The web has some security restrictions on what's possible, but this PR works perfectly for me with
I sadly don't have access to a Mac right now. However, I've put together a really simple example web app for testing. You should be able to just clone the repository and run |
|
Hi, just a quick update: I don't have the bandwidth at the moment to finish up the testing and reviewing for this PR. I apologize for the late communication but I'll need to circle back to it later, likely in October. |
|
Hello again, sorry for the radio silence. I ended up getting bogged down trying to figure out how to test this cross-platform and ensure consistent functionality. #191 describes unblocking this being merged, so I would like to ask for slightly more time to set that up. My intent is that this would sit no longer then summer. |
|
Thanks for your response! My own projects/needs have changed and I don't require this functionality right now. So, I'm happy to hear that this project is evolving but please take your time :) |
This PR implements the ability to cut, copy, and paste text on the web/WASM platforms. This allows libraries like
egui-winitto use the clipboard on the web (see emilk/egui#4270). This is accomplished in the following way:window.navigator.clipboard.write()pasteevent listener to the root HTML document, which stores theevent.clipboardData.getData("text")value into a global variable. Whenever the clipboard contents are requested from Rust, the global variable is read. Note that this means the user must actually perform a paste before the clipboard contents become visible to Rust. This is a caveat, but it's the only way that I could find to implement synchronous pasting.event.clipboardData.filesarray, whereasyncis required to read the data.