emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 9324efa: Make `xwidget-display-event' a special event as well


From: Po Lu
Subject: master 9324efa: Make `xwidget-display-event' a special event as well
Date: Sun, 21 Nov 2021 21:47:42 -0500 (EST)

branch: master
commit 9324efac480df3cd78af112da2b12a0d2bd18e02
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Make `xwidget-display-event' a special event as well
    
    * 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 | 10 ++++++++--
 etc/NEWS                  |  4 ++--
 lisp/xwidget.el           | 17 ++++++++++++++---
 src/keyboard.c            |  2 +-
 src/xwidget.c             | 34 +++++++++++++++++++++++++---------
 5 files changed, 50 insertions(+), 17 deletions(-)

diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index 5fd7b55..c12a97c 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -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
diff --git a/etc/NEWS b/etc/NEWS
index bfea4da..6fa5de0 100644
--- 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'.
diff --git a/lisp/xwidget.el b/lisp/xwidget.el
index 160da67..cf4396f 100644
--- a/lisp/xwidget.el
+++ b/lisp/xwidget.el
@@ -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."
diff --git a/src/keyboard.c b/src/keyboard.c
index 982854c..c98175a 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -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
diff --git a/src/xwidget.c b/src/xwidget.c
index d88270d..5da2aa1 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -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);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]