aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2021-11-13 11:24:13 +0800
committerPo Lu2021-11-13 11:24:13 +0800
commiteb4567e5be17e30583baebced562cb83595643e3 (patch)
tree90cf5547cd30ee5c9552674867515b7e59386a7b /src
parent59a58328bc086bdda1d8be816778f2a74379b02f (diff)
downloademacs-eb4567e5be17e30583baebced562cb83595643e3.tar.gz
emacs-eb4567e5be17e30583baebced562cb83595643e3.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/xwidget.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/xwidget.c b/src/xwidget.c
index c1fbfedc703..fad07efb294 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -91,6 +91,9 @@ webkit_decide_policy_cb (WebKitWebView *,
91 WebKitPolicyDecisionType, 91 WebKitPolicyDecisionType,
92 gpointer); 92 gpointer);
93static GtkWidget *find_widget_at_pos (GtkWidget *, int, int, int *, int *); 93static GtkWidget *find_widget_at_pos (GtkWidget *, int, int, int *, int *);
94static gboolean run_file_chooser_cb (WebKitWebView *,
95 WebKitFileChooserRequest *,
96 gpointer);
94 97
95struct widget_search_data 98struct widget_search_data
96{ 99{
@@ -261,6 +264,10 @@ fails. */)
261 "script-dialog", 264 "script-dialog",
262 G_CALLBACK (webkit_script_dialog_cb), 265 G_CALLBACK (webkit_script_dialog_cb),
263 NULL); 266 NULL);
267 g_signal_connect (G_OBJECT (xw->widget_osr),
268 "run-file-chooser",
269 G_CALLBACK (run_file_chooser_cb),
270 NULL);
264 } 271 }
265 272
266 g_signal_connect (G_OBJECT (xw->widgetwindow_osr), "damage-event", 273 g_signal_connect (G_OBJECT (xw->widgetwindow_osr), "damage-event",
@@ -778,6 +785,70 @@ mouse_target_changed (WebKitWebView *webview,
778 define_cursors (xw, hitresult); 785 define_cursors (xw, hitresult);
779} 786}
780 787
788static gboolean
789run_file_chooser_cb (WebKitWebView *webview,
790 WebKitFileChooserRequest *request,
791 gpointer user_data)
792{
793 struct frame *f = SELECTED_FRAME ();
794 GtkWidget *chooser;
795 GtkFileFilter *filter;
796 bool select_multiple_p;
797 guint response;
798 GSList *filenames;
799 GSList *tem;
800 int i, len;
801 gchar **files;
802
803 /* Return TRUE to prevent WebKit from showing the default script
804 dialog in the offscreen window, which runs a nested main loop
805 Emacs can't respond to, and as such can't pass X events to. */
806 if (!FRAME_WINDOW_P (f))
807 return TRUE;
808
809 chooser = gtk_file_chooser_dialog_new ("Select file",
810 GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
811 GTK_FILE_CHOOSER_ACTION_OPEN,
812 "Cancel",
813 GTK_RESPONSE_CANCEL,
814 "Select",
815 GTK_RESPONSE_ACCEPT,
816 NULL);
817 filter = webkit_file_chooser_request_get_mime_types_filter (request);
818 select_multiple_p = webkit_file_chooser_request_get_select_multiple (request);
819
820 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (chooser),
821 select_multiple_p);
822 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
823 response = gtk_dialog_run (GTK_DIALOG (chooser));
824
825 if (response == GTK_RESPONSE_CANCEL)
826 {
827 gtk_widget_destroy (chooser);
828 webkit_file_chooser_request_cancel (request);
829
830 return TRUE;
831 }
832
833 filenames = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (chooser));
834 len = g_slist_length (filenames);
835 files = alloca (sizeof *files * (len + 1));
836
837 for (tem = filenames, i = 0; tem; tem = tem->next, ++i)
838 files[i] = tem->data;
839 files[len] = NULL;
840
841 g_slist_free (filenames);
842 webkit_file_chooser_request_select_files (request, (const gchar **) files);
843
844 for (i = 0; i < len; ++i)
845 g_free (files[i]);
846
847 gtk_widget_destroy (chooser);
848
849 return TRUE;
850}
851
781 852
782static void 853static void
783xwidget_button_1 (struct xwidget_view *view, 854xwidget_button_1 (struct xwidget_view *view,