all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Qiantan Hong <qthong@stanford.edu>
To: Po Lu <luangruo@yahoo.com>, Andrew De Angelis <bobodeangelis@gmail.com>
Cc: "emacs-devel@gnu.org" <emacs-devel@gnu.org>
Subject: Re: [PATCH] Add user content APIs for WebKit Xwidgets
Date: Sun, 23 Oct 2022 09:11:39 +0000	[thread overview]
Message-ID: <B9632193-A02B-41C9-9443-C6B390A025AA@stanford.edu> (raw)
In-Reply-To: <877d10mfsw.fsf@yahoo.com>


[-- Attachment #1.1: Type: text/plain, Size: 1543 bytes --]

Hi Po,

I tried to fix these problems, and I've attached my updated patch.

Some remaining questions/issues:

1. I think that connecting signal to scriptor (now called manager)
doesn't require xw to be marked, because it is also destroyed when xw
is killed? Suppose that now I reference count correctly, manager
should be owned by xw, just like the WebKitWebContext at line 363.
2. I didn't fix the ARC assumption in NS port. I hope it can be fixed
in one batch by Andrew. Thank you Andrew!

Best,
Qiantan


> On Oct 15, 2022, at 11:41 PM, Po Lu <luangruo@yahoo.com> wrote:
>
> Qiantan Hong <qthong@stanford.edu> writes:
>
>> Yes I’m aware. I was fixing them one by one.
>
> Thanks.
>
>> It seems that existing code is connecting signal without adding the marking
>> code, guess that should be fixed too...
>
> Where?  Existing code should not connect signals to anything other than
> `widget_osr' which is destroyed upon the xwidget being killed, a
> prerequisite for being marked by GC.
>
>> Those two problems above, I don’t have any existing code to imitate, so it
>> would take a while to learn the codebase for me to be able to fix them.
>> I’m also not sure if I should just make my part conforming or also fix all existing code.
>> Is it acceptable that I submit a patch (with other problems fixed) first,
>> and work on fixing these two classes of problems later?
>
> I'd rather not install code with known memory management issues,
> especially not this close to the Emacs 29 release.


[-- Attachment #1.2: Type: text/html, Size: 2196 bytes --]

[-- Attachment #2: 0001-Implement-WebKit-user-scripts-and-script-message-han.txt --]
[-- Type: text/plain, Size: 20864 bytes --]

From fb375e5e3582a5c9cfe3d11c1036fe9affe1b12f Mon Sep 17 00:00:00 2001
From: Qiantan Hong <qhong@alum.mit.edu>
Date: Sun, 23 Oct 2022 01:55:53 -0700
Subject: [PATCH] Implement WebKit user scripts and script message handlers.

* src/xwidget.h (store_xwidget_script_message_event): store script
message event into event queue
* src/xwidget.c (store_xwidget_script_message_event):
(Fxwidget_webkit_add_user_script):
(Fxwidget_webkit_remove_all_user_scripts): user script primitives
(Fxwidget_webkit_register_script_message):
(Fxwidget_webkit_unregister_script_message): script message handler
primitives.
* src/nsxwidget.c (nsxwidget_webkit_add_user_script):
(nsxwidget_webkit_remove_all_user_scripts):
(nsxwidget_webkit_register_script_message):
(nsxwidget_webkit_unregister_script_message): NS implementation of
user script and script message handler. Changed naming of a previous
used script message handler to avoid namespace pollution.
* src/nsxwidget.h (nsxwidget_webkit_add_user_script):
(nsxwidget_webkit_remove_all_user_scripts):
(nsxwidget_webkit_register_script_message):
(nsxwidget_webkit_unregister_script_message):
* lisp/xwidget.el (xwidget-webkit-callback):
(xwidget-webkit-push-script-message-handler):
(xwidget-webkit-pop-script-message-handler): let lisp recognize and
dispatch script message events
* doc/lispref/display.texi: document user script and script message
handler
---
 doc/lispref/display.texi |  52 +++++++++++
 lisp/xwidget.el          |  36 +++++++-
 src/nsxwidget.h          |   5 +
 src/nsxwidget.m          |  80 ++++++++++++++--
 src/xwidget.c            | 192 +++++++++++++++++++++++++++++++++++++++
 src/xwidget.h            |   4 +
 6 files changed, 361 insertions(+), 8 deletions(-)

diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 15cd5518d9..48b38ff837 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -7279,6 +7279,58 @@ Xwidgets
 @var{default} was omitted.
 @end defun
 
+@defun xwidget-webkit-add-user-script xwidget script when main-frame-only
+This function adds the specified user script @code{script} to the
+browser widget specified by @var{xwidget}.
+
+User scripts are custom JavaScript code that is automatically run in
+the pages of the browser widget.  The @var{when} argument specifies
+when @var{script} is run, it can be one of the following:
+
+@table @code
+@item start
+@var{script} is run upon first loading a document.
+@item end
+@var{script} is run after a document loads.
+@end table
+
+The @var{main-frame-only} argument specifies which HTML frames run
+@var{script}.  If @var{main-frame-only} is @code{nil}, @var{script} is
+run in all HTML frames.  Otherwise, @var{script} is only run in
+top-level HTML frames.
+@end defun
+
+@defun xwidget-webkit-remove-all-user-scripts xwidget
+This functions removes all user scripts from the browser widget
+specified by @var{xwidget}.
+@end defun
+
+@defun xwidget-webkit-push-script-message-handler xwidget name handler
+This function registers @var{handler} to handle script messages with
+namespace specified by string @var{name} for the browser widget
+specified by @var{xwidget}.
+
+Script message enables JavaScript code run in browser widgets to pass
+data to Emacs.  After @var{handler} is registered with @var{name},
+running the following JavaScript code
+
+@example
+window.webkit.messageHandlers.@var{name}.postMessage(@var{JSObject});
+@end example
+
+@noindent causes @var{handler} to be called with two arguments: @var{xwidget}
+and @var{JSObject} converted to a Lisp object.
+@end defun
+
+@defun xwidget-webkit-pop-script-message-handler
+This functions removes a handler registered with namespace specified
+by string @var{name} for the browser widget specified by
+@var{xwidget}.
+
+The returned value is the removed handler function, or @code{nil} if
+no such handler is found.
+@end defun
+
 @defun xwidget-webkit-get-title xwidget
 This function returns the title of @var{xwidget} as a string.
 @end defun
diff --git a/lisp/xwidget.el b/lisp/xwidget.el
index 41a1190c64..418a9f3acc 100644
--- a/lisp/xwidget.el
+++ b/lisp/xwidget.el
@@ -485,7 +485,41 @@ xwidget-webkit-callback
            (let ((proc (nth 3 last-input-event))
                  (arg  (nth 4 last-input-event)))
              (funcall proc arg)))
-          (t (xwidget-log "unhandled event:%s" xwidget-event-type)))))
+          ((eq xwidget-event-type 'script-message)
+           (let ((name (nth 3 last-input-event))
+                 (value (nth 4 last-input-event)))
+             (let ((handler-pair (assoc name (xwidget-get xwidget 'script-message-handlers))))
+               (if handler-pair
+                   (funcall (cdr handler-pair) xwidget value)
+                 (xwidget-log "unhandled script message: %s" name)))))
+          (t (xwidget-log "unhandled event: %s" xwidget-event-type)))))
+
+(defun xwidget-webkit-push-script-message-handler (xwidget name handler)
+  "Register HANDLER to handle script messages with NAME for WebKit XWIDGET.
+
+HANDLER will be called with two arguments: the WebKit XWIDGET and
+the JavaScript object passed from the script message converted to
+a Lisp object."
+  (let ((old-alist (xwidget-get xwidget 'script-message-handlers)))
+    (unless (assoc name old-alist)
+      (xwidget-webkit-register-script-message (xwidget-webkit-current-session) name))
+    (xwidget-put xwidget 'script-message-handlers
+                 (cons (cons name handler) old-alist)))
+  name)
+
+(defun xwidget-webkit-pop-script-message-handler (xwidget name)
+  "Remove a handler registered with NAME for WebKit XWIDGET.
+
+Return the removed handler function, or NIL if no such handler is
+found."
+  (let* ((old-alist (xwidget-get xwidget 'script-message-handlers))
+         (handler-pair (assoc name old-alist)))
+    (when handler-pair
+      (let ((new-alist (delq handler-pair old-alist)))
+        (xwidget-put xwidget 'script-message-handlers new-alist)
+        (unless (assoc name new-alist)
+          (xwidget-webkit-unregister-script-message (xwidget-webkit-current-session) name)))
+      (cdr handler-pair))))
 
 (defvar bookmark-make-record-function)
 (when (memq window-system '(mac ns))
diff --git a/src/nsxwidget.h b/src/nsxwidget.h
index 666509744a..cd1dc1bc2c 100644
--- a/src/nsxwidget.h
+++ b/src/nsxwidget.h
@@ -40,6 +40,11 @@ #define NSXWIDGET_H_INCLUDED
 void nsxwidget_webkit_execute_script (struct xwidget *xw, const char *script,
                                       Lisp_Object fun);
 
+void nsxwidget_webkit_add_user_script (struct xwidget *xw, const char *script,
+                                       int injection_time_start, int main_frame_only);
+void nsxwidget_webkit_remove_all_user_scripts (struct xwidget *xw);
+Lisp_Object nsxwidget_webkit_register_script_message (struct xwidget *xw, const char *name);
+void nsxwidget_webkit_unregister_script_message (struct xwidget *xw, const char *name);
 /* Functions for xwidget model.  */
 
 #ifdef __OBJC__
diff --git a/src/nsxwidget.m b/src/nsxwidget.m
index be0eba0bcb..901277f9a3 100644
--- a/src/nsxwidget.m
+++ b/src/nsxwidget.m
@@ -88,7 +88,7 @@ - (id)initWithFrame:(CGRect)frame
         @"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)"
         @" AppleWebKit/603.3.8 (KHTML, like Gecko)"
         @" Version/11.0.1 Safari/603.3.8";
-      [scriptor addScriptMessageHandler:self name:@"keyDown"];
+      [scriptor addScriptMessageHandler:self name:@"__xwidget_internal_keyDown"];
       [scriptor addUserScript:[[WKUserScript alloc]
                                 initWithSource:xwScript
                                  injectionTime:
@@ -275,23 +275,34 @@ + (void)initialize
       @"}"
       @"function xwKeyDown(event) {"
       @"  if (event.ctrlKey && event.key == 'g') {"
-      @"    window.webkit.messageHandlers.keyDown.postMessage('C-g');"
+      @"    window.webkit.messageHandlers.__xwidget_internal_keyDown.postMessage('C-g');"
       @"  }"
       @"}"
       @"document.addEventListener('keydown', xwKeyDown);"
       ;
 }
 
+static Lisp_Object js_to_lisp (id value);
+
 /* Confirming to WKScriptMessageHandler, listens concerning keyDown in
    webkit. Currently 'C-g'.  */
 - (void)userContentController:(WKUserContentController *)userContentController
       didReceiveScriptMessage:(WKScriptMessage *)message
 {
-  if ([message.body isEqualToString:@"C-g"])
+  if ([message.name isEqualToString:@"__xwidget_internal_keyDown"])
     {
-      /* Just give up focus, no relay "C-g" to emacs, another "C-g"
-         follows will be handled by emacs.  */
-      [self.window makeFirstResponder:self.xw->xv->emacswindow];
+      if ([message.body isEqualToString:@"C-g"])
+        {
+          /* Just give up focus, no relay "C-g" to emacs, another "C-g"
+             follows will be handled by emacs.  */
+          [self.window makeFirstResponder:self.xw->xv->emacswindow];
+        }
+    }
+  else
+    {
+      store_xwidget_script_message_event (self.xw,
+                                          message.name.UTF8String,
+                                          js_to_lisp (message.body));
     }
 }
 
@@ -437,6 +448,61 @@ - (void)userContentController:(WKUserContentController *)userContentController
     }];
 }
 
+void
+nsxwidget_webkit_add_user_script (struct xwidget *xw, const char *script,
+                                  int injection_time_start, int main_frame_only)
+{
+  XwWebView *xwWebView = (XwWebView *) xw->xwWidget;
+  WKUserContentController *scriptor = xwWebView.configuration.userContentController;
+
+  NSString *javascriptString = [NSString stringWithUTF8String:script];
+  WKUserScriptInjectionTime injectionTime = injection_time_start?
+    WKUserScriptInjectionTimeAtDocumentStart : WKUserScriptInjectionTimeAtDocumentEnd;
+  WKUserScript *userScript = [[WKUserScript alloc]
+                               initWithSource: javascriptString
+                                injectionTime: injectionTime
+                               forMainFrameOnly: main_frame_only];
+  [scriptor addUserScript: userScript];
+}
+
+void
+nsxwidget_webkit_remove_all_user_scripts (struct xwidget *xw)
+{
+  XwWebView *xwWebView = (XwWebView *) xw->xwWidget;
+  WKUserContentController *scriptor = xwWebView.configuration.userContentController;
+
+  [scriptor removeAllUserScripts];
+}
+
+Lisp_Object
+nsxwidget_webkit_register_script_message (struct xwidget *xw, const char *name)
+{
+  XwWebView *xwWebView = (XwWebView *) xw->xwWidget;
+  WKUserContentController *scriptor = xwWebView.configuration.userContentController;
+
+  NSString *messageName = [NSString stringWithUTF8String:name];
+
+  @try
+    {
+      [scriptor addScriptMessageHandler:xwWebView name:messageName];
+    }
+  @catch (NSException *e)
+    {
+      error ("Failed to register WebKit script message handler");
+    }
+  return Qnil;
+}
+
+void
+nsxwidget_webkit_unregister_script_message (struct xwidget *xw, const char *name)
+{
+  XwWebView *xwWebView = (XwWebView *) xw->xwWidget;
+  WKUserContentController *scriptor = xwWebView.configuration.userContentController;
+
+  NSString *messageName = [NSString stringWithUTF8String:name];
+  [scriptor removeScriptMessageHandlerForName:messageName];
+}
+
 /* Window containing an xwidget.  */
 
 @implementation XwWindow
@@ -469,7 +535,7 @@ - (BOOL)isFlipped { return YES; }
       WKUserContentController *scriptor =
         ((XwWebView *) xw->xwWidget).configuration.userContentController;
       [scriptor removeAllUserScripts];
-      [scriptor removeScriptMessageHandlerForName:@"keyDown"];
+      [scriptor removeScriptMessageHandlerForName:@"__xwidget_internal_keyDown"];
       [scriptor release];
       if (xw->xv)
         xw->xv->model = Qnil; /* Make sure related view stale.  */
diff --git a/src/xwidget.c b/src/xwidget.c
index 8bdfab02fd..3cdd95f970 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -126,6 +126,11 @@ webkit_decide_policy_cb (WebKitWebView *,
 };
 
 static void find_widget (GtkWidget *t, struct widget_search_data *);
+
+static void webkit_script_message_cb (WebKitUserContentManager *,
+                                          WebKitJavascriptResult *,
+                                          gpointer);
+
 #endif
 
 #ifdef HAVE_PGTK
@@ -380,6 +385,9 @@ DEFUN ("make-xwidget",
 	  settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (xw->widget_osr));
 	  g_object_set (G_OBJECT (settings), "enable-developer-extras", TRUE, NULL);
 	}
+      WebKitUserContentManager *manager = webkit_user_content_manager_new ();
+      xw->widget_osr = webkit_web_view_new_with_user_content_manager (manager);
+      g_object_unref (manager);
 
       gtk_widget_set_size_request (GTK_WIDGET (xw->widget_osr), xw->width,
                                    xw->height);
@@ -2308,6 +2316,21 @@ store_xwidget_js_callback_event (struct xwidget *xw,
   kbd_buffer_store_event (&event);
 }
 
+void
+store_xwidget_script_message_event (struct xwidget *xw,
+				    const char *name,
+				    Lisp_Object body)
+{
+  struct input_event event;
+  Lisp_Object xwl;
+  XSETXWIDGET (xwl, xw);
+  EVENT_INIT (event);
+  event.kind = XWIDGET_EVENT;
+  event.frame_or_window = Qnil;
+  event.arg = list4 (Qscript_message, xwl, build_string (name), body);
+  kbd_buffer_store_event (&event);
+}
+
 
 #ifdef USE_GTK
 static void
@@ -2622,6 +2645,21 @@ webkit_decide_policy_cb (WebKitWebView *webView,
   }
 }
 
+static void
+webkit_script_message_cb (WebKitUserContentManager *manager,
+			  WebKitJavascriptResult *js_result,
+			  gpointer data)
+{
+  struct xwidget *xw = g_object_get_data (G_OBJECT (manager),
+					  XG_XWIDGET);
+  JSCValue *value = webkit_javascript_result_get_js_value (js_result);
+  const char *arg = data;
+  Lisp_Object lisp_value = webkit_js_to_lisp (value);
+  store_xwidget_script_message_event (xw, arg, lisp_value);
+
+  webkit_javascript_result_unref (js_result);
+}
+
 static gboolean
 webkit_script_dialog_cb (WebKitWebView *webview,
 			 WebKitScriptDialog *script_dialog,
@@ -3198,6 +3236,151 @@ DEFUN ("xwidget-webkit-execute-script",
   return Qnil;
 }
 
+DEFUN ("xwidget-webkit-add-user-script",
+       Fxwidget_webkit_add_user_script, Sxwidget_webkit_add_user_script,
+       4, 4, 0,
+       doc: /* Add the user script SCRIPT to the WebKit XWIDGET.
+
+WHEN is one of the following values, and specifies when the script is
+run:
+- `start', which means the script is run upon first loading a document.
+- `end', which means the script is run after a document loads.
+
+If MAIN_FRAME_ONLY is nil, SCRIPT is run in all HTML frames.
+Otherwise, SCRIPT is only run in top-level HTML frames.  */)
+  (Lisp_Object xwidget, Lisp_Object script,
+   Lisp_Object when, Lisp_Object main_frame_only)
+{
+  WEBKIT_FN_INIT ();
+  CHECK_STRING (script);
+  CHECK_SYMBOL (when);
+
+  script = ENCODE_UTF_8 (script);
+
+  Bool start;
+  if (EQ (when, Qstart))
+    start = true;
+  else if (EQ (when, Qend))
+    start = false;
+  else
+    error ("Unknown Xwidget Webkit user script injection time: %s",
+           SDATA (SYMBOL_NAME (when)));
+
+#ifdef USE_GTK
+  WebKitWebView *view = WEBKIT_WEB_VIEW (xw->widget_osr);
+  WebKitUserContentManager *manager = webkit_web_view_get_user_content_manager (view);
+
+  WebKitUserContentInjectedFrames webkit_injected_frames
+    = (!NILP (main_frame_only))
+    ? WEBKIT_USER_CONTENT_INJECT_TOP_FRAME
+    : WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES;
+  WebKitUserScriptInjectionTime webkit_injection_time = start
+    ? WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_START
+    : WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END;
+  WebKitUserScript *user_script
+    = webkit_user_script_new (SSDATA (script),
+			      webkit_injected_frames,
+			      webkit_injection_time,
+			      NULL, NULL);
+  webkit_user_content_manager_add_script (manager, user_script);
+  webkit_user_script_unref (user_script);
+#elif defined NS_IMPL_COCOA
+  nsxwidget_webkit_add_user_script (xw, SSDATA (script), injection_time_start, mfo);
+#endif
+  return Qnil;
+}
+
+DEFUN ("xwidget-webkit-remove-all-user-scripts",
+       Fxwidget_webkit_remove_all_user_scripts, Sxwidget_webkit_remove_all_user_scripts,
+       1, 1, 0,
+       doc: /* Remove all user scripts from WebKit XWIDGET.  */)
+  (Lisp_Object xwidget)
+{
+  WEBKIT_FN_INIT ();
+
+#ifdef USE_GTK
+  WebKitWebView *view = WEBKIT_WEB_VIEW (xw->widget_osr);
+  WebKitUserContentManager *manager = webkit_web_view_get_user_content_manager (view);
+
+  webkit_user_content_manager_remove_all_scripts (manager);
+#elif defined NS_IMPL_COCOA
+  nsxwidget_webkit_remove_all_user_scripts(xw);
+#endif
+  return Qnil;
+}
+
+DEFUN ("xwidget-webkit-register-script-message",
+       Fxwidget_webkit_register_script_message, Sxwidget_webkit_register_script_message,
+       2, 2, 0,
+       doc: /* Register script message with NAME in WebKit XWIDGET.
+
+This operation fails if NAME has already been registered for XWIDGET.  */)
+  (Lisp_Object xwidget, Lisp_Object name)
+{
+  WEBKIT_FN_INIT ();
+  CHECK_STRING (name);
+  char *sname = xlispstrdup (name);
+
+#ifdef USE_GTK
+  WebKitWebView *view = WEBKIT_WEB_VIEW (xw->widget_osr);
+  WebKitUserContentManager *manager = webkit_web_view_get_user_content_manager (view);
+
+  USE_SAFE_ALLOCA;
+  gchar *signal_name = SAFE_ALLOCA (strlen ("script-message-received::") + strlen (sname) + 1);
+  stpcpy (stpcpy (signal_name, "script-message-received::"), sname);
+  g_signal_connect_data (manager, signal_name, G_CALLBACK (webkit_script_message_cb),
+			 sname, (GClosureNotify) xfree, 0);
+  SAFE_FREE ();
+
+  if (webkit_user_content_manager_register_script_message_handler (manager, sname))
+    {
+      g_object_set_data (G_OBJECT (manager), XG_XWIDGET, xw);
+    }
+  else
+    {
+      g_signal_handlers_disconnect_matched (manager,
+					    G_SIGNAL_MATCH_DATA,
+					    0, 0, NULL, NULL, sname);
+      error ("Failed to register WebKit script message handler");
+    }
+#elif defined NS_IMPL_COCOA
+  nsxwidget_webkit_register_script_message (xw, sname);
+  xfree (sname);
+#endif
+  return Qnil;
+}
+
+DEFUN ("xwidget-webkit-unregister-script-message",
+       Fxwidget_webkit_unregister_script_message, Sxwidget_webkit_unregister_script_message,
+       2, 2, 0,
+       doc: /* Unregister script message with NAME in Webkit XWIDGET.  */)
+  (Lisp_Object xwidget, Lisp_Object name)
+{
+  WEBKIT_FN_INIT ();
+  CHECK_STRING (name);
+
+  USE_SAFE_ALLOCA;
+  char *sname;
+  SAFE_ALLOCA_STRING (sname, name);
+
+#ifdef USE_GTK
+  WebKitWebView *view = WEBKIT_WEB_VIEW (xw->widget_osr);
+  WebKitUserContentManager *manager
+    = webkit_web_view_get_user_content_manager (view);
+
+  webkit_user_content_manager_unregister_script_message_handler (manager, sname);
+  g_signal_handlers_disconnect_matched (manager,
+					G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DETAIL,
+					0, g_quark_from_string (sname), 0,
+					G_CALLBACK (webkit_script_message_cb), 0);
+#elif defined NS_IMPL_COCOA
+  nsxwidget_webkit_unregister_script_message(xw, sname);
+#endif
+
+  SAFE_FREE();
+  return Qnil;
+}
+
 DEFUN ("xwidget-resize", Fxwidget_resize, Sxwidget_resize, 3, 3, 0,
        doc: /* Resize XWIDGET to NEW_WIDTH, NEW_HEIGHT.  */ )
   (Lisp_Object xwidget, Lisp_Object new_width, Lisp_Object new_height)
@@ -3919,6 +4102,15 @@ syms_of_xwidget (void)
   defsubr (&Sxwidget_webkit_execute_script);
   DEFSYM (Qwebkit, "webkit");
 
+  defsubr (&Sxwidget_webkit_add_user_script);
+  DEFSYM (Qstart, "start");
+  DEFSYM (Qend, "end");
+  defsubr (&Sxwidget_webkit_remove_all_user_scripts);
+
+  DEFSYM (Qscript_message, "script-message");
+  defsubr (&Sxwidget_webkit_register_script_message);
+  defsubr (&Sxwidget_webkit_unregister_script_message);
+
   defsubr (&Sxwidget_size_request);
   defsubr (&Sdelete_xwidget_view);
 
diff --git a/src/xwidget.h b/src/xwidget.h
index 502beb6765..e835f700bc 100644
--- a/src/xwidget.h
+++ b/src/xwidget.h
@@ -203,6 +203,10 @@ #define XG_XWIDGET_VIEW "emacs_xwidget_view"
                                       Lisp_Object proc,
                                       Lisp_Object argument);
 
+void store_xwidget_script_message_event (struct xwidget *xw,
+                                         const char *name,
+                                         Lisp_Object value);
+
 extern struct xwidget *xwidget_from_id (uint32_t id);
 
 #ifdef HAVE_X_WINDOWS
-- 
2.32.1 (Apple Git-133)


  parent reply	other threads:[~2022-10-23  9:11 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-14  6:34 [PATCH] Add user content APIs for WebKit Xwidgets Qiantan Hong
2022-10-14  7:01 ` Po Lu
2022-10-14  7:12   ` Qiantan Hong
2022-10-14  7:35     ` Po Lu
2022-10-14 21:13       ` Qiantan Hong
2022-10-15  1:37         ` Qiantan Hong
2022-10-15  7:53           ` Qiantan Hong
2022-10-15 11:23             ` Po Lu
2022-10-15 18:29               ` Qiantan Hong
2022-10-16  0:26                 ` Po Lu
2022-10-15 23:33               ` Qiantan Hong
2022-10-16  4:32                 ` Po Lu
2022-10-16  6:29                   ` Qiantan Hong
2022-10-16  6:41                     ` Po Lu
2022-10-16  6:45                       ` Po Lu
2022-10-23  9:11                       ` Qiantan Hong [this message]
2022-10-23 10:58                         ` Po Lu
2022-10-23 22:16                           ` Qiantan Hong
2022-10-24  0:30                             ` Po Lu
2022-10-24  4:17                               ` Qiantan Hong
2022-10-24  5:38                                 ` Po Lu
2022-10-24  5:44                                   ` Qiantan Hong
2022-10-24  7:20                                     ` Po Lu
2022-10-16 20:51             ` [PATCH] Add user extension " Richard Stallman
2022-10-16 21:13               ` Alan Mackenzie
2022-10-18 11:58                 ` Richard Stallman
2022-10-17  5:31               ` Eli Zaretskii
2022-10-17  8:28                 ` Jean Louis
2022-10-19 17:04                   ` Richard Stallman
2022-10-19 19:06                     ` Eli Zaretskii
2022-10-20 19:46                 ` Richard Stallman
2022-10-21  5:51                   ` Eli Zaretskii
2022-10-21  6:02                     ` Po Lu
2022-10-23 19:14                     ` Richard Stallman
  -- strict thread matches above, loose matches on Subject: below --
2020-08-28  2:25 [PATCH] Add user content " Qiantan Hong
2020-08-28 14:37 ` Lars Ingebrigtsen
2020-08-28 15:41   ` Qiantan Hong
2020-08-30 13:43     ` Lars Ingebrigtsen
2020-08-29  4:07   ` Richard Stallman
2020-08-29  4:10 ` Richard Stallman
2020-08-29  4:45   ` Qiantan Hong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=B9632193-A02B-41C9-9443-C6B390A025AA@stanford.edu \
    --to=qthong@stanford.edu \
    --cc=bobodeangelis@gmail.com \
    --cc=emacs-devel@gnu.org \
    --cc=luangruo@yahoo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.