1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-25 06:50:46 -08:00

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.
This commit is contained in:
Po Lu 2021-11-13 11:24:13 +08:00
parent 59a58328bc
commit eb4567e5be

View file

@ -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,