[webkit-gtk] Interface between embedded Javascript and the main GTK app
Gavin Smith
gavinsmith0123 at gmail.com
Fri Jan 3 07:34:28 PST 2025
On Fri, Jan 03, 2025 at 03:22:45PM +0200, Sim Tov wrote:
> Thank you very much Michael! Finally I was able to get to this project.
> The idea is to create a small GTK-based text editor with live preview for
> [djot](https://github.com/jgm/djot.js).
By coincidence I also came back to the project I was
using WebKitGTK for and used Michael's suggestion of
window.webkit.messageHandlers.foo.postMessage() for IPC.
It has seemed quite straightforward. In the UI process, I initialise
the web view object and the channel:
WebKitUserContentManager *manager1;
manager1 = webkit_web_view_get_user_content_manager (webView);
g_signal_connect (manager1, "script-message-received::channel",
G_CALLBACK (handle_script_message), NULL);
webkit_user_content_manager_register_script_message_handler (manager1,
"channel");
'handle_script_message' starts like:
void
handle_script_message (WebKitUserContentManager *manager,
WebKitJavascriptResult *js_result,
gpointer user_data)
{
JSCValue *jscValue = webkit_javascript_result_get_js_value (js_result);
char *message = jsc_value_to_string (jscValue);
It then processes the message send from the web process.
In the web process (with "web extensions" code), I can then send the
message:
void
send_js_message (WebKitWebPage *web_page, char *message)
{
WebKitFrame *frame = webkit_web_page_get_main_frame (web_page);
if (!frame)
return;
JSCContext *jsc = webkit_frame_get_js_context (frame);
if (!jsc)
return;
JSCValue *js_string = jsc_value_new_string (jsc, message);
jsc_context_set_value (jsc, "msgString", js_string);
JSCValue *jscValue = jsc_context_evaluate (jsc,
"window.webkit.messageHandlers.channel.postMessage(msgString);",
-1);
Before, I had interpolated the string into a JavaScript literal string:
asprintf (&js,
"window.webkit.messageHandlers.channel.postMessage(`%s`);", message);
but this wouldn't work if the mesage contained a backtick (`) character.
It seems a bit convoluted that you start with a "page", then get a "frame",
before getting a "context" that you can finally execute JavaScript on but
I trust that it is this way for a good reason.
(This is with the WebKitGTK 4.0 API although I gather there are newer
versions now.)
I don't know what djot is and don't know how relevant this is to your
project.
More information about the webkit-gtk
mailing list