Skip to content

Improve support for SharedArrayBuffer in Webviews#3927

Merged
mhsmith merged 7 commits intobeeware:mainfrom
freakboy3742:sharedArrayBuffer
Nov 27, 2025
Merged

Improve support for SharedArrayBuffer in Webviews#3927
mhsmith merged 7 commits intobeeware:mainfrom
freakboy3742:sharedArrayBuffer

Conversation

@freakboy3742
Copy link
Copy Markdown
Member

SharedArrayBuffer is needed to support running PyScript in a webview; but it is disabled by default by WebKit for security reasons.

This PR enables SharedArrayBuffer support by:

  1. Using an undocumented environment variable for GTK
  2. Adding COOP and COEP headers to the Positron web server

It also adds handlers for Cocoa and iOS webviews to support displaying dialogs. This isn't needed for SharedArrayBuffer itself - but it was needed to test SharedArrayBuffer support.

There's no new unit tests for this because it depends on Pos

To test - generate a "static" Positron app with the following static content:

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Shared Array Test</title>
    </head>
    <body>
        <h1>Hello World</h1>
        <p id="message"></p>
        <p>Cross Origin Isolated:<span id="coi"></span></p>
        <p>Secure context:<span id="sc"></span></p>
        <button onclick="alert(confirm('foo'));">Press me</button>
        <script>
            try {
                console.log("Hello world")
                new SharedArrayBuffer(4, {maxByteLength: 8});
                console.log("Yeah");
                alert("Yeah!");
                document.getElementById("message").textContent = "YEAH";
            }
            catch (_) {
                console.log("SharedArrayBuffer not supported");
                alert("SharedArrayBuffer not supported");
                document.getElementById("message").textContent = "SharedArrayBuffer not supported";
            }
            document.getElementById("coi").textContent = window.crossOriginIsolated;
            document.getElementById("sc").textContent = window.isSecureContext;
        </script>
    </body>
</html>

On startup, this should:

  1. Display a dialog saying "Yeah!"
  2. When the dialog is dismissed, the page content should be updated to say "Yeah!";
  3. Cross Origin Isolated and Secure Context should both report True
  4. The "Press button" button show display a confirmation dialog; if you select OK, a second alert saying "True" should be displayed; if you select Cancel, the second alert will say "False".

PR Checklist:

  • All new features have been tested
  • All new features have been documented
  • I have read the CONTRIBUTING.md file
  • I will abide by the code of conduct

@freakboy3742
Copy link
Copy Markdown
Member Author

I've tested this on macOS, Windows, GTK, and iOS, and it works. It's still failing on Android - both because of dialogs, and because it's not detecting cross-origin isolation.

@freakboy3742 freakboy3742 requested a review from mhsmith November 27, 2025 07:37
@WebReflection
Copy link
Copy Markdown

@freakboy3742 this is awesome, thank you!

Just to be sure we are aligned:

@WebReflection
Copy link
Copy Markdown

forgot to mention ... we might also not need specific headers (although that's likely better) if the ServiceWorker approach can actually run ... we can use this file (has to be loaded locally as Service Worker cannot be hosted anywhere else) https://github.com/WebReflection/mini-coi/blob/main/mini-coi-fd.js and on the page, as first thing on the <head> you can use:

<script src="./mini-coi-fd.js"></script>

notes

  • this must be the first non module and synchronous script or it will fail
  • the Service Worker is initialized only if SharedArrayBuffer is not usable/working
  • the server won't need anything special on its end, the the ServiceWorker that takes over

Of course native support is preferable, but maybe this option makes sense for Android WebView in case all other attempts failed.

I hope any of this will help solving the feature all over the place + with SharedArrayBuffer in place we won't need alert or prompt, we can idle any worker at any time without blocking the device/UI but of course users might abuse prompt out there for quickly asking details to users so it'd be great to have all these possibilities in.

@freakboy3742
Copy link
Copy Markdown
Member Author

@freakboy3742 this is awesome, thank you!

Just to be sure we are aligned:

  • "when in Rome" ... alert, confirm and prompt should be possible (all 3 of them)

Understood - the underlying problem here is that Toga doesn't have the analog of prompt() yet, so there's no easy drop-in for displaying the dialog. #2896 is the ticket tracking the feature request. It won't be difficult to implement - it just needs to be a priority, and it hasn't been a low priority historically.

Toga's WebView uses the native platform web view, which isn't Chromium by default on Android... but android.webview.WebView is... feature poor, shall we say :-) . The story for sharedArrayBuffer specificall doesn't look promising.

I don't know what other options exist on Android that are exposed as a widget that is ready to use; if we need to deploy to Android, then we might need to do some research.

  • when SharedArrayBuffer is forced to 1 there is no need/reason to set these headers but I understand the security risk/implication so the best combination of all features are indeed a desirable goal

Understood - but in this case, it's more about a single source base targeting multiple platforms.

@mhsmith mhsmith merged commit 85f4eee into beeware:main Nov 27, 2025
110 of 111 checks passed
@freakboy3742
Copy link
Copy Markdown
Member Author

forgot to mention ... we might also not need specific headers (although that's likely better) if the ServiceWorker approach can actually run

Understood - but I think that fits in the category of things that would be added to the project manually after the stub has been generated. The current intention is that Positron is a "generate once and then modify" bootstrapping wizard, rather than a standalone "generate complete app from configuration" tool.

That said, it's not out of the question to turn it into a "complete app" tool, if that's a use case that is warranted.

@freakboy3742 freakboy3742 deleted the sharedArrayBuffer branch November 27, 2025 23:20
@WebReflection
Copy link
Copy Markdown

FYI I've commented in there: https://issues.chromium.org/issues/40914606#comment16

we have a workaround to make PyScript work out of the blue even on Android WebViews so it feels like a matter of using the right template after crossOringinIsolated check, SharedArrayBuffer check and, last but not least, Android WebView check ... not sure we need to use ugly User Agent sniffing in there but if there are no other options, we might force that to work, as long as Service Worker works in Android WebView, because if that's also not the case then we're doomed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants