desktop/source/app/appinit.cxx |   32 +++++++++++++++++++++++++++++++-
 static/emscripten/uno.js       |    5 +++++
 2 files changed, 36 insertions(+), 1 deletion(-)

New commits:
commit e952204b4010a80775ce63a9986506f16d8d7cb9
Author:     Stephan Bergmann <stephan.bergm...@allotropia.de>
AuthorDate: Thu Aug 15 15:18:29 2024 +0200
Commit:     Stephan Bergmann <stephan.bergm...@allotropia.de>
CommitDate: Thu Aug 15 17:16:27 2024 +0200

    Emscripten: Establish a channel between browser and LO main threads
    
    ...to be used by external code, to mitigate the issue mentioned in the 
commit
    message of cccc983eb3f0532dbf7e3edf4477ce63ec3d2795 "Emscripten: Run 
external
    code on LO's main thread":  "Alternatively, running external code on the
    browser's main thread rather than on LO's main thread could be more ideal 
in the
    sense that the external code would then have access to the browser's 
document
    object."
    
    On the browser main thread, external JS code can now await a Module.uno_main
    Promise that provides one port of a MessageChannel.  And on the LO main 
thread,
    external JS code has access to the other port of that MessageChannel as
    Module.uno_mainPort.  (And the external code is completely free in what
    onmessage handlers to set up and what form of postMessage calls to use on 
those
    two MessagePorts.)
    
    Change-Id: Iab6bc7676c744eacb70ddd9f3f80f64e9efd1cf1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171907
    Reviewed-by: Stephan Bergmann <stephan.bergm...@allotropia.de>
    Tested-by: Jenkins

diff --git a/desktop/source/app/appinit.cxx b/desktop/source/app/appinit.cxx
index 6f8bffa1146a..4490529a77ba 100644
--- a/desktop/source/app/appinit.cxx
+++ b/desktop/source/app/appinit.cxx
@@ -84,9 +84,36 @@ EM_JS(void, runUnoScriptUrl, (char16_t const * url), {
     }).then(blob => blob.text()).then(text => eval(text));
 });
 
+EM_JS(void, setupMainChannel, (), {
+    const orig = self.onmessage;
+    self.onmessage = function(e) {
+        if (e.data.cmd === "LOWA-channel") {
+            self.onmessage = orig;
+            Module.uno_mainPort = e.ports[0];
+        } else if (orig) {
+            orig(e);
+        }
+    };
+});
+
+extern "C" void resolveUnoMain() {
+    EM_ASM(
+        let sofficeMain;
+        for (const i in PThread.pthreads) {
+            const worker = PThread.pthreads[i];
+            if (worker.workerID === 1) {
+                sofficeMain = worker;
+                break;
+            }
+        }
+        const channel = new MessageChannel();
+        sofficeMain.postMessage({cmd:"LOWA-channel"}, [channel.port2]);
+        Module.uno_main$resolve(channel.port1);
+    );
+}
+
 void initUno() {
     init_unoembind_uno();
-    EM_ASM(Module.uno_init$resolve(););
     std::vector<std::u16string> urls;
     emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_VI, 
getUnoScriptUrls, &urls);
     for (auto const & url: urls) {
@@ -95,6 +122,9 @@ void initUno() {
         }
         runUnoScriptUrl(url.c_str());
     }
+    setupMainChannel();
+    EM_ASM(Module.uno_init$resolve(););
+    emscripten_async_run_in_main_runtime_thread(EM_FUNC_SIG_V, resolveUnoMain);
 }
 
 }
diff --git a/static/emscripten/uno.js b/static/emscripten/uno.js
index 7d051a24a84b..84b301f3e3b3 100644
--- a/static/emscripten/uno.js
+++ b/static/emscripten/uno.js
@@ -19,6 +19,11 @@ Module.uno_init = new Promise(function (resolve, reject) {
     Module.uno_init$reject = reject;
 });
 
+Module.uno_main = new Promise(function (resolve, reject) {
+    Module.uno_main$resolve = resolve;
+    Module.uno_main$reject = reject;
+});
+
 Module.catchUnoException = function(exception) {
     // Rethrow non-C++ exceptions (non-UNO C++ exceptions are mapped to 
css.uno.RuntimeException in
     // Module.getUnoExceptionFromCxaException):

Reply via email to