emacs-diffs
[Top][All Lists]
Advanced

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

master eb4567e: Fix file chooser hangs inside xwidget-webkit


From: Po Lu
Subject: master eb4567e: Fix file chooser hangs inside xwidget-webkit
Date: Fri, 12 Nov 2021 22:25:12 -0500 (EST)

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

    Fix file chooser hangs inside xwidget-webkit
    
    * src/xwidget.c (run_file_chooser_cb): New function that runs
    a nested event loop instead of acting asynchronously.
    (Fmake_xwidget): Attach file chooser signal.
---
 src/xwidget.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/src/xwidget.c b/src/xwidget.c
index c1fbfed..fad07ef 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -91,6 +91,9 @@ webkit_decide_policy_cb (WebKitWebView *,
                          WebKitPolicyDecisionType,
                          gpointer);
 static GtkWidget *find_widget_at_pos (GtkWidget *, int, int, int *, int *);
+static gboolean run_file_chooser_cb (WebKitWebView *,
+                                    WebKitFileChooserRequest *,
+                                    gpointer);
 
 struct widget_search_data
 {
@@ -261,6 +264,10 @@ fails.  */)
                            "script-dialog",
                            G_CALLBACK (webkit_script_dialog_cb),
                            NULL);
+         g_signal_connect (G_OBJECT (xw->widget_osr),
+                           "run-file-chooser",
+                           G_CALLBACK (run_file_chooser_cb),
+                           NULL);
         }
 
       g_signal_connect (G_OBJECT (xw->widgetwindow_osr), "damage-event",
@@ -778,6 +785,70 @@ mouse_target_changed (WebKitWebView *webview,
   define_cursors (xw, hitresult);
 }
 
+static gboolean
+run_file_chooser_cb (WebKitWebView *webview,
+                    WebKitFileChooserRequest *request,
+                    gpointer user_data)
+{
+  struct frame *f = SELECTED_FRAME ();
+  GtkWidget *chooser;
+  GtkFileFilter *filter;
+  bool select_multiple_p;
+  guint response;
+  GSList *filenames;
+  GSList *tem;
+  int i, len;
+  gchar **files;
+
+  /* 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;
+
+  chooser = gtk_file_chooser_dialog_new ("Select file",
+                                        GTK_WINDOW (FRAME_GTK_OUTER_WIDGET 
(f)),
+                                        GTK_FILE_CHOOSER_ACTION_OPEN,
+                                        "Cancel",
+                                        GTK_RESPONSE_CANCEL,
+                                        "Select",
+                                        GTK_RESPONSE_ACCEPT,
+                                        NULL);
+  filter = webkit_file_chooser_request_get_mime_types_filter (request);
+  select_multiple_p = webkit_file_chooser_request_get_select_multiple 
(request);
+
+  gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (chooser),
+                                       select_multiple_p);
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
+  response = gtk_dialog_run (GTK_DIALOG (chooser));
+
+  if (response == GTK_RESPONSE_CANCEL)
+    {
+      gtk_widget_destroy (chooser);
+      webkit_file_chooser_request_cancel (request);
+
+      return TRUE;
+    }
+
+  filenames = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (chooser));
+  len = g_slist_length (filenames);
+  files = alloca (sizeof *files * (len + 1));
+
+  for (tem = filenames, i = 0; tem; tem = tem->next, ++i)
+    files[i] = tem->data;
+  files[len] = NULL;
+
+  g_slist_free (filenames);
+  webkit_file_chooser_request_select_files (request, (const gchar **) files);
+
+  for (i = 0; i < len; ++i)
+    g_free (files[i]);
+
+  gtk_widget_destroy (chooser);
+
+  return TRUE;
+}
+
 
 static void
 xwidget_button_1 (struct xwidget_view *view,



reply via email to

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