]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix hang when displaying xwidget script dialog
authorPo Lu <luangruo@yahoo.com>
Mon, 8 Nov 2021 05:22:11 +0000 (06:22 +0100)
committerLars Ingebrigtsen <larsi@gnus.org>
Mon, 8 Nov 2021 05:25:02 +0000 (06:25 +0100)
* src/xwidget.c (webkit_script_dialog_cb): New function.
(Fmake_xwidget): Attach script callback signal (bug#51674).

src/xwidget.c

index f95f5f1d7f71f3901fad7693b2ad266289eb25c5..ecb973f485f057257cb5d759c026e3e1cee74e59 100644 (file)
@@ -50,6 +50,8 @@ static Lisp_Object x_window_to_xwv_map;
 static gboolean offscreen_damage_event (GtkWidget *, GdkEvent *, gpointer);
 static void synthesize_focus_in_event (GtkWidget *);
 static GdkDevice *find_suitable_keyboard (struct frame *);
+static gboolean webkit_script_dialog_cb (WebKitWebView *, WebKitScriptDialog *,
+                                        gpointer);
 #endif
 
 static struct xwidget *
@@ -240,6 +242,10 @@ fails.  */)
                            "create",
                            G_CALLBACK (webkit_create_cb),
                            xw);
+         g_signal_connect (G_OBJECT (xw->widget_osr),
+                           "script-dialog",
+                           G_CALLBACK (webkit_script_dialog_cb),
+                           NULL);
         }
 
       g_signal_connect (G_OBJECT (xw->widgetwindow_osr), "damage-event",
@@ -1242,6 +1248,66 @@ webkit_decide_policy_cb (WebKitWebView *webView,
     return FALSE;
   }
 }
+
+static gboolean
+webkit_script_dialog_cb (WebKitWebView *webview,
+                        WebKitScriptDialog *script_dialog,
+                        gpointer user)
+{
+  struct frame *f = SELECTED_FRAME ();
+  WebKitScriptDialogType type;
+  GtkWidget *widget;
+  GtkWidget *dialog;
+  GtkWidget *entry;
+  GtkWidget *content_area;
+  const gchar *content;
+  const gchar *message;
+  gint result;
+
+  /* Return TRUE to prevent WebKit from showing the default script
+     dialog in the offscreen window, which runs a nested main loop
+     Emacs can't respond to, and as such can't pass X events to.  */
+  if (!FRAME_WINDOW_P (f))
+    return TRUE;
+
+  type = webkit_script_dialog_get_dialog_type (script_dialog);;
+  widget = FRAME_GTK_OUTER_WIDGET (f);
+  content = webkit_script_dialog_get_message (script_dialog);
+
+  if (type == WEBKIT_SCRIPT_DIALOG_ALERT)
+    dialog = gtk_dialog_new_with_buttons (content, GTK_WINDOW (widget),
+                                         GTK_DIALOG_MODAL,
+                                         "Dismiss", 1, NULL);
+  else
+    dialog = gtk_dialog_new_with_buttons (content, GTK_WINDOW (widget),
+                                         GTK_DIALOG_MODAL,
+                                         "OK", 0, "Cancel", 1, NULL);
+
+  if (type == WEBKIT_SCRIPT_DIALOG_PROMPT)
+    {
+      entry = gtk_entry_new ();
+      message = webkit_script_dialog_prompt_get_default_text (script_dialog);
+      content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+      gtk_widget_show (entry);
+      gtk_entry_set_text (GTK_ENTRY (entry), message);
+      gtk_container_add (GTK_CONTAINER (content_area), entry);
+    }
+
+  result = gtk_dialog_run (GTK_DIALOG (dialog));
+
+  if (type == WEBKIT_SCRIPT_DIALOG_CONFIRM
+      || type == WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM)
+    webkit_script_dialog_confirm_set_confirmed (script_dialog, result == 0);
+
+  if (type == WEBKIT_SCRIPT_DIALOG_PROMPT)
+    webkit_script_dialog_prompt_set_text (script_dialog,
+                                         gtk_entry_get_text (GTK_ENTRY (entry)));
+
+  gtk_widget_destroy (GTK_WIDGET (dialog));
+
+  return TRUE;
+}
 #endif /* USE_GTK */