]> git.eshelyaron.com Git - emacs.git/commitdiff
Make `xwidget-display-event' a special event as well
authorPo Lu <luangruo@yahoo.com>
Mon, 22 Nov 2021 02:42:46 +0000 (10:42 +0800)
committerPo Lu <luangruo@yahoo.com>
Mon, 22 Nov 2021 02:47:29 +0000 (10:47 +0800)
* doc/lispref/commands.texi (Xwidget Events): Document that
`xwidget-display-event' is a special event, and that it should
be handled through callbacks.

* etc/NEWS: Update NEWS entry.

* lisp/xwidget.el (xwidget-webkit-new-session)
(xwidget-webkit-import-widget): Attach display callback.
(xwidget-webkit-display-event): Call display callback instead.
(xwidget-webkit-display-callback): New function.

* src/keyboard.c (make_lispy_event): Store
source information for XWIDGET_DISPLAY_EVENT correctly.

* src/xwidget.c (store_xwidget_display_event): Store
source of the display request.
(webkit_ready_to_show): Store source if available.
(webkit_create_cb_1): Store source if available.
(kill_xwidget): Remove dead widget from internal_xwidget_list.

doc/lispref/commands.texi
etc/NEWS
lisp/xwidget.el
src/keyboard.c
src/xwidget.c

index 5fd7b55a60b4e67a03e13a1a7e0d12e2f62d3be0..c12a97cc7df79fc3729269586a63f74e6b168fbe 100644 (file)
@@ -1950,9 +1950,15 @@ internally by @code{xwidget-webkit-execute-script}.
 @end table
 
 @cindex @code{xwidget-display-event} event
-@item (xwidget-display-event @var{xwidget})
+@item (xwidget-display-event @var{xwidget} @var{source})
 This event is sent whenever an xwidget requests that another xwidget
-be displayed.  @var{xwidget} is the xwidget that should be displayed.
+be displayed.  @var{xwidget} is the xwidget that should be displayed,
+and @var{source} is the xwidget that asked to display @var{xwidget}.
+
+It is also a special event which should be handled through callbacks.
+You can add such a callback by setting the @code{display-callback} of
+@var{source}'s property list, which should be a function that accepts
+@var{xwidget} and @var{source} as arguments.
 
 @var{xwidget}'s buffer will be set to a temporary buffer.  When
 displaying the widget, care should be taken to replace the buffer with
index bfea4da8b9ea0b6075db7b47a7851e4eb7f8a24a..6fa5de0116dbb7c862db1a93cb0e6a99e6e36558 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -927,8 +927,8 @@ commits to the load.
 +++
 *** New event type 'xwidget-display-event'.
 These events are sent whenever an xwidget requests that Emacs display
-another xwidget.  The only argument to this event is the xwidget that
-should be displayed.
+another xwidget.  The only arguments to this event are the xwidget
+that should be displayed, and the xwidget that asked to display it.
 
 +++
 *** New function 'xwidget-webkit-set-cookie-storage-file'.
index 160da67cb21510031fc781892edf980ca7fa3878..cf4396fec2dfebaeb2232d4fdc19650526c31d82 100644 (file)
@@ -818,6 +818,7 @@ For example, use this to display an anchor."
       (xwidget-webkit-set-cookie-storage-file
        xw (expand-file-name xwidget-webkit-cookie-file)))
     (xwidget-put xw 'callback callback)
+    (xwidget-put xw 'display-callback #'xwidget-webkit-display-callback)
     (xwidget-webkit-mode)
     (xwidget-webkit-goto-uri (xwidget-webkit-last-session) url)))
 
@@ -840,16 +841,26 @@ Return the buffer."
         (put-text-property (point-min) (point-max)
                            'display (list 'xwidget :xwidget xwidget)))
       (xwidget-put xwidget 'callback callback)
+      (xwidget-put xwidget 'display-callback
+                   #'xwidget-webkit-display-callback)
       (set-xwidget-buffer xwidget buffer)
       (xwidget-webkit-mode))
     buffer))
 
 (defun xwidget-webkit-display-event (event)
-  "Import the xwidget inside EVENT and display it."
+  "Trigger display callback for EVENT."
   (interactive "e")
-  (display-buffer (xwidget-webkit-import-widget (nth 1 event))))
+  (let ((xwidget (cadr event))
+        (source (caddr event)))
+    (when (xwidget-get source 'display-callback)
+      (funcall (xwidget-get source 'display-callback)
+               xwidget source))))
 
-(global-set-key [xwidget-display-event] 'xwidget-webkit-display-event)
+(defun xwidget-webkit-display-callback (xwidget _source)
+  "Import XWIDGET and display it."
+  (display-buffer (xwidget-webkit-import-widget xwidget)))
+
+(define-key special-event-map [xwidget-display-event] 'xwidget-webkit-display-event)
 
 (defun xwidget-webkit-goto-url (url)
   "Goto URL with xwidget webkit."
index 982854c41e1a8224c3d78d27edaca972f47756e6..c98175aea0da1f389b37059f6ae0eefd41418f32 100644 (file)
@@ -6141,7 +6141,7 @@ make_lispy_event (struct input_event *event)
       return Fcons (Qxwidget_event, event->arg);
 
     case XWIDGET_DISPLAY_EVENT:
-      return list2 (Qxwidget_display_event, event->arg);
+      return Fcons (Qxwidget_display_event, event->arg);
 #endif
 
 #ifdef USE_FILE_NOTIFY
index d88270dbe97d4e8dde46f820d96ced59ce931e27..5da2aa1743bac5eda5fce0805abb24efb9a67e2d 100644 (file)
@@ -1316,16 +1316,18 @@ store_xwidget_js_callback_event (struct xwidget *xw,
 
 #ifdef USE_GTK
 static void
-store_xwidget_display_event (struct xwidget *xw)
+store_xwidget_display_event (struct xwidget *xw,
+                            struct xwidget *src)
 {
   struct input_event evt;
-  Lisp_Object val;
+  Lisp_Object val, src_val;
 
   XSETXWIDGET (val, xw);
+  XSETXWIDGET (src_val, src);
   EVENT_INIT (evt);
   evt.kind = XWIDGET_DISPLAY_EVENT;
   evt.frame_or_window = Qnil;
-  evt.arg = val;
+  evt.arg = list2 (val, src_val);
   kbd_buffer_store_event (&evt);
 }
 
@@ -1335,6 +1337,9 @@ webkit_ready_to_show (WebKitWebView *new_view,
 {
   Lisp_Object tem;
   struct xwidget *xw;
+  struct xwidget *src;
+
+  src = find_xwidget_for_offscreen_window (GDK_WINDOW (user_data));
 
   for (tem = internal_xwidget_list; CONSP (tem); tem = XCDR (tem))
     {
@@ -1344,14 +1349,21 @@ webkit_ready_to_show (WebKitWebView *new_view,
 
          if (EQ (xw->type, Qwebkit)
              && WEBKIT_WEB_VIEW (xw->widget_osr) == new_view)
-           store_xwidget_display_event (xw);
+           {
+             /* The source widget was destroyed before we had a
+                chance to display the new widget.  */
+             if (!src)
+               kill_xwidget (xw);
+             else
+               store_xwidget_display_event (xw, src);
+           }
        }
     }
 }
 
 static GtkWidget *
 webkit_create_cb_1 (WebKitWebView *webview,
-                   struct xwidget_view *xv)
+                   struct xwidget *xv)
 {
   Lisp_Object related;
   Lisp_Object xwidget;
@@ -1369,7 +1381,8 @@ webkit_create_cb_1 (WebKitWebView *webview,
   widget = XXWIDGET (xwidget)->widget_osr;
 
   g_signal_connect (G_OBJECT (widget), "ready-to-show",
-                   G_CALLBACK (webkit_ready_to_show), NULL);
+                   G_CALLBACK (webkit_ready_to_show),
+                   gtk_widget_get_window (xv->widgetwindow_osr));
 
   return widget;
 }
@@ -1591,7 +1604,7 @@ webkit_decide_policy_cb (WebKitWebView *webView,
       newview = WEBKIT_WEB_VIEW (XXWIDGET (new_xwidget)->widget_osr);
       webkit_web_view_load_request (newview, request);
 
-      store_xwidget_display_event (XXWIDGET (new_xwidget));
+      store_xwidget_display_event (XXWIDGET (new_xwidget), xw);
       return TRUE;
     }
   case WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION:
@@ -3106,6 +3119,11 @@ kill_frame_xwidget_views (struct frame *f)
 static void
 kill_xwidget (struct xwidget *xw)
 {
+  Lisp_Object val;
+  XSETXWIDGET (val, xw);
+
+  internal_xwidget_list = Fdelq (val, internal_xwidget_list);
+  Vxwidget_list = Fcopy_sequence (internal_xwidget_list);
 #ifdef USE_GTK
   xw->buffer = Qnil;
 
@@ -3145,8 +3163,6 @@ kill_buffer_xwidgets (Lisp_Object buffer)
   for (tail = Fget_buffer_xwidgets (buffer); CONSP (tail); tail = XCDR (tail))
     {
       xwidget = XCAR (tail);
-      internal_xwidget_list = Fdelq (xwidget, internal_xwidget_list);
-      Vxwidget_list = Fcopy_sequence (internal_xwidget_list);
       {
         CHECK_LIVE_XWIDGET (xwidget);
         struct xwidget *xw = XXWIDGET (xwidget);