# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1679699079 0 # Node ID d84182f0054ee596807d99ab4c8674faa1790938 # Parent 7d6773c474d08c816ab5ad2b67b6a8b87cec5ad9 GTK4: Support for dw_html_javascript_add() and DW_SIGNAL_HTML_MESSAGE. Also add support for the stable WebKitGTK 6.0 for GTK4. They changed a lot including the package name, add USE_WEBKIT6 for this. diff -r 7d6773c474d0 -r d84182f0054e configure --- a/configure Fri Mar 24 17:35:53 2023 +0000 +++ b/configure Fri Mar 24 23:04:39 2023 +0000 @@ -7151,8 +7151,9 @@ fi if test x"$GTK_LIBS" != x; then DW_DIR=gtk4 - # WebKit2GTK built for GTK4 becomes 5.0 - WEBKIT_PKG="webkit2gtk-5.0" + # WebKit2GTK built for GTK4 becomes 5.0 or 6.0 + WEBKIT_PKG="webkitgtk-6.0" + WEBKIT_ALT_PKG="webkit2gtk-5.0" fi else # Put the GTK2 test here since --with-gtk2 is mutually @@ -7208,6 +7209,11 @@ printf "%s\n" "#define USE_WEBKIT2 1" >>confdefs.h fi + if test "$WEBKIT_PKG" = "webkitgtk-6.0"; then + +printf "%s\n" "#define USE_WEBKIT6 1" >>confdefs.h + + fi fi if test x"$RPATH" != x; then RPATH="-Wl,-R$RPATH" diff -r 7d6773c474d0 -r d84182f0054e configure.ac --- a/configure.ac Fri Mar 24 17:35:53 2023 +0000 +++ b/configure.ac Fri Mar 24 23:04:39 2023 +0000 @@ -231,8 +231,9 @@ fi if test x"$GTK_LIBS" != x; then DW_DIR=gtk4 - # WebKit2GTK built for GTK4 becomes 5.0 - WEBKIT_PKG="webkit2gtk-5.0" + # WebKit2GTK built for GTK4 becomes 5.0 or 6.0 + WEBKIT_PKG="webkitgtk-6.0" + WEBKIT_ALT_PKG="webkit2gtk-5.0" fi else # Put the GTK2 test here since --with-gtk2 is mutually @@ -282,6 +283,9 @@ if test "$WEBKIT_PKG" = "webkit2gtk-4.0"; then AC_DEFINE(USE_WEBKIT2,1,Uses WebKit 2) fi + if test "$WEBKIT_PKG" = "webkitgtk-6.0"; then + AC_DEFINE(USE_WEBKIT6,1,Uses WebKit 6) + fi fi if test x"$RPATH" != x; then RPATH="-Wl,-R$RPATH" diff -r 7d6773c474d0 -r d84182f0054e dwconfig.h.in --- a/dwconfig.h.in Fri Mar 24 17:35:53 2023 +0000 +++ b/dwconfig.h.in Fri Mar 24 23:04:39 2023 +0000 @@ -106,5 +106,8 @@ /* Uses WebKit 2 */ #undef USE_WEBKIT2 +/* Uses WebKit 6 */ +#undef USE_WEBKIT6 + /* Define to 1 if the X Window System is missing or not being used. */ #undef X_DISPLAY_MISSING diff -r 7d6773c474d0 -r d84182f0054e gtk4/dw.c --- a/gtk4/dw.c Fri Mar 24 17:35:53 2023 +0000 +++ b/gtk4/dw.c Fri Mar 24 23:04:39 2023 +0000 @@ -34,8 +34,12 @@ #endif #ifdef USE_WEBKIT +#ifdef USE_WEBKIT6 +#include +#else #include #endif +#endif #include @@ -477,6 +481,11 @@ #ifdef USE_WEBKIT static void _dw_html_result_event(GObject *object, GAsyncResult *result, gpointer script_data); static void _dw_html_changed_event(WebKitWebView *web_view, WebKitLoadEvent load_event, gpointer data); +#ifdef USE_WEBKIT6 +static void _dw_html_message_event(WebKitUserContentManager *manager, JSCValue *result, gpointer *data); +#else +static void _dw_html_message_event(WebKitUserContentManager *manager, WebKitJavascriptResult *result, gpointer *data); +#endif #endif static void _dw_signal_disconnect(gpointer data, GClosure *closure); static void _dw_event_coordinates_to_window(GtkWidget *widget, double *x, double *y); @@ -522,7 +531,7 @@ } DWSignalHandler; -/* A list of signal forwarders, to account for paramater differences. */ +/* A list of signal forwarders, to account for parameter differences. */ static DWSignalList DWSignalTranslate[] = { { _dw_configure_event, DW_SIGNAL_CONFIGURE, "resize", NULL }, { _dw_key_press_event, DW_SIGNAL_KEY_PRESS, "key-pressed", _dw_key_setup }, @@ -544,6 +553,7 @@ #ifdef USE_WEBKIT { _dw_html_changed_event, DW_SIGNAL_HTML_CHANGED, "load-changed", NULL }, { _dw_html_result_event, DW_SIGNAL_HTML_RESULT, "", _dw_html_setup }, + { _dw_html_message_event, DW_SIGNAL_HTML_MESSAGE, "", _dw_html_setup }, #endif { NULL, "", "", NULL } }; @@ -674,7 +684,9 @@ static void _dw_html_result_event(GObject *object, GAsyncResult *result, gpointer script_data) { pthread_t saved_thread = _dw_thread; +#ifndef USE_WEBKIT6 WebKitJavascriptResult *js_result; +#endif JSCValue *value; GError *error = NULL; int (*htmlresultfunc)(HWND, int, char *, void *, void *) = NULL; @@ -684,10 +696,8 @@ _dw_thread = (pthread_t)-1; if(handlerdata) { - DWSignalHandler work; void *params[3] = { GINT_TO_POINTER(handlerdata-1), 0, object }; - - work = _dw_get_signal_handler(params); + DWSignalHandler work = _dw_get_signal_handler(params); if(work.window) { @@ -696,7 +706,11 @@ } } +#ifdef USE_WEBKIT6 + if(!(value = webkit_web_view_evaluate_javascript_finish(WEBKIT_WEB_VIEW(object), result, &error))) +#else if(!(js_result = webkit_web_view_run_javascript_finish(WEBKIT_WEB_VIEW(object), result, &error))) +#endif { if(htmlresultfunc) htmlresultfunc((HWND)object, DW_ERROR_UNKNOWN, error->message, script_data, user_data); @@ -705,7 +719,9 @@ return; } +#ifndef USE_WEBKIT6 value = webkit_javascript_result_get_js_value(js_result); +#endif if(jsc_value_is_string(value)) { gchar *str_value = jsc_value_to_string(value); @@ -722,10 +738,53 @@ } else if(htmlresultfunc) htmlresultfunc((HWND)object, DW_ERROR_UNKNOWN, NULL, script_data, user_data); +#ifndef USE_WEBKIT6 webkit_javascript_result_unref (js_result); +#endif _dw_thread = saved_thread; } +#ifdef USE_WEBKIT6 +static void _dw_html_message_event(WebKitUserContentManager *manager, JSCValue *result, gpointer *data) +#else +static void _dw_html_message_event(WebKitUserContentManager *manager, WebKitJavascriptResult *result, gpointer *data) +#endif +{ + HWND window = (HWND)data[0]; + int (*htmlmessagefunc)(HWND, char *, char *, void *) = NULL; + void *user_data = NULL; + gchar *name = (gchar *)data[1]; + gint handlerdata; + + if(window && (handlerdata = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(window), "_dw_html_message_id")))) + { + void *params[3] = { GINT_TO_POINTER(handlerdata-1), 0, window }; + DWSignalHandler work = _dw_get_signal_handler(params); + + if(work.window) + { + htmlmessagefunc = work.func; + user_data = work.data; + } + } + + if(jsc_value_is_string(result)) + { + gchar *str_value = jsc_value_to_string(result); + JSCException *exception = jsc_context_get_exception(jsc_value_get_context(result)); + + if(htmlmessagefunc && !exception) + htmlmessagefunc(window, name, str_value, user_data); + + g_free(str_value); + + if(!exception) + return; + } + if(htmlmessagefunc) + htmlmessagefunc(window, name, NULL, user_data); +} + static void _dw_html_changed_event(WebKitWebView *web_view, WebKitLoadEvent load_event, gpointer data) { DWSignalHandler work = _dw_get_signal_handler(data); @@ -10518,14 +10577,76 @@ #ifdef USE_WEBKIT WebKitWebView *web_view; - if((web_view = _dw_html_web_view(handle))) + if(script && (web_view = _dw_html_web_view(handle))) +#ifdef USE_WEBKIT6 + webkit_web_view_evaluate_javascript(web_view, script, strlen(script), NULL, NULL, NULL, _dw_html_result_event, scriptdata); +#else webkit_web_view_run_javascript(web_view, script, NULL, _dw_html_result_event, scriptdata); +#endif return DW_ERROR_NONE; #else return DW_ERROR_UNKNOWN; #endif } +/* Free the name when the signal disconnects */ +void _dw_html_message_disconnect(gpointer gdata, GClosure *closure) +{ + gpointer *data = (gpointer *)gdata; + + if(data) + { + gchar *name = (gchar *)data[1]; + + if(name) + g_free(name); + free(data); + } +} + +/* + * Install a javascript function with name that can call native code. + * Parameters: + * handle: Handle to the HTML window. + * name: Javascript function name. + * Notes: A DW_SIGNAL_HTML_MESSAGE event will be raised with scriptdata. + * Returns: + * DW_ERROR_NONE (0) on success. + */ +int API dw_html_javascript_add(HWND handle, const char *name) +{ +#ifdef USE_WEBKIT + WebKitWebView *web_view= _dw_html_web_view(handle); + WebKitUserContentManager *manager; + + if(web_view && (manager = webkit_web_view_get_user_content_manager(web_view)) && name) + { + /* Script to inject that will call the handler we are adding */ + gchar *script = g_strdup_printf("function %s(body) {window.webkit.messageHandlers.%s.postMessage(body);}", + name, name); + gchar *signal = g_strdup_printf("script-message-received::%s", name); + WebKitUserScript *userscript = webkit_user_script_new(script, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, + WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_START, NULL, NULL); + gpointer *data = calloc(sizeof(gpointer), 2); + + data[0] = handle; + data[1] = g_strdup(name); + g_signal_connect_data(manager, signal, G_CALLBACK(_dw_html_message_event), data, _dw_html_message_disconnect, 0); + webkit_user_content_manager_register_script_message_handler(manager, name +#if USE_WEBKIT6 + , NULL +#endif + ); + webkit_user_content_manager_add_script(manager, userscript); + + g_free(script); + g_free(signal); + return DW_ERROR_NONE; + } +#endif + return DW_ERROR_UNKNOWN; +} + /* * Create a new HTML window (widget) to be packed. * Parameters: @@ -11090,14 +11211,26 @@ #ifdef USE_WEBKIT GObject *_dw_html_setup(struct _dw_signal_list *signal, GObject *object, void *sigfunc, void *discfunc, void *data) { - if(WEBKIT_IS_WEB_VIEW(object) && strcmp(signal->name, DW_SIGNAL_HTML_RESULT) == 0) - { - /* We don't actually need a signal handler here... just need to assign the handler ID - * Since the handler is created in dw_html_javasript_run() - */ - int sigid = _dw_set_signal_handler(object, (HWND)object, sigfunc, data, signal->func, discfunc); - g_object_set_data(object, "_dw_html_result_id", GINT_TO_POINTER(sigid+1)); - return NULL; + if(WEBKIT_IS_WEB_VIEW(object)) + { + if(strcmp(signal->name, DW_SIGNAL_HTML_RESULT) == 0) + { + /* We don't actually need a signal handler here... just need to assign the handler ID + * Since the handler is created in dw_html_javasript_run() + */ + int sigid = _dw_set_signal_handler(object, (HWND)object, sigfunc, data, signal->func, discfunc); + g_object_set_data(object, "_dw_html_result_id", GINT_TO_POINTER(sigid+1)); + return NULL; + } + else if(strcmp(signal->name, DW_SIGNAL_HTML_MESSAGE) == 0) + { + /* We don't actually need a signal handler here... just need to assign the handler ID + * Since the handler is created in dw_html_javasript_add() + */ + int sigid = _dw_set_signal_handler(object, (HWND)object, sigfunc, data, signal->func, discfunc); + g_object_set_data(object, "_dw_html_message_id", GINT_TO_POINTER(sigid+1)); + return NULL; + } } return object; } diff -r 7d6773c474d0 -r d84182f0054e mac/dw.m --- a/mac/dw.m Fri Mar 24 17:35:53 2023 +0000 +++ b/mac/dw.m Fri Mar 24 23:04:39 2023 +0000 @@ -9514,7 +9514,6 @@ return DW_ERROR_UNKNOWN; } - /* * Create a new HTML window (widget) to be packed. * Not available under OS/2, eCS