aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarlos Garcia Campos <cgarcia@igalia.com>2013-03-21 21:00:18 +0800
committerClaudio Saavedra <csaavedra@igalia.com>2013-08-29 03:25:29 +0800
commitb5754ac85db00de0183dbd13004917d5eb9c06a6 (patch)
tree3358120b3d8181fa906b857add572719e5be5d35
parent1d9f2c94024756ee68abba6eaff1078a52c6e57b (diff)
downloadgsoc2013-epiphany-b5754ac85db00de0183dbd13004917d5eb9c06a6.tar
gsoc2013-epiphany-b5754ac85db00de0183dbd13004917d5eb9c06a6.tar.gz
gsoc2013-epiphany-b5754ac85db00de0183dbd13004917d5eb9c06a6.tar.bz2
gsoc2013-epiphany-b5754ac85db00de0183dbd13004917d5eb9c06a6.tar.lz
gsoc2013-epiphany-b5754ac85db00de0183dbd13004917d5eb9c06a6.tar.xz
gsoc2013-epiphany-b5754ac85db00de0183dbd13004917d5eb9c06a6.tar.zst
gsoc2013-epiphany-b5754ac85db00de0183dbd13004917d5eb9c06a6.zip
Make ephy_web_view_has_modified_forms() asynchronous
https://bugzilla.gnome.org/show_bug.cgi?id=695642
-rw-r--r--embed/ephy-web-view.c73
-rw-r--r--embed/ephy-web-view.h8
-rw-r--r--src/ephy-window.c192
3 files changed, 203 insertions, 70 deletions
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index f39546b9d..57ceab62f 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -2545,6 +2545,26 @@ ephy_web_view_set_typed_address (EphyWebView *view,
g_object_notify (G_OBJECT (view), "typed-address");
}
+#ifdef HAVE_WEBKIT2
+static void
+has_modified_forms_cb (GDBusProxy *web_extension,
+ GAsyncResult *result,
+ GTask *task)
+{
+ GVariant *return_value;
+ gboolean retval = FALSE;
+
+ return_value = g_dbus_proxy_call_finish (web_extension, result, NULL);
+ if (return_value) {
+ g_variant_get (return_value, "(b)", &retval);
+ g_variant_unref (return_value);
+ }
+
+ g_task_return_boolean (task, retval);
+ g_object_unref (task);
+}
+#endif
+
/**
* ephy_web_view_has_modified_forms:
* @view: an #EphyWebView
@@ -2559,33 +2579,46 @@ ephy_web_view_set_typed_address (EphyWebView *view,
*
* Return value: %TRUE if @view has user-modified forms
**/
-gboolean
-ephy_web_view_has_modified_forms (EphyWebView *view)
+void
+ephy_web_view_has_modified_forms (EphyWebView *view,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- return FALSE;
-#if 0
+ GTask *task = g_task_new (view, cancellable, callback, user_data);
+#ifdef HAVE_WEBKIT2
GDBusProxy *web_extension;
- GVariant *result;
- gboolean retval = FALSE;
- /* FIXME: This should be async */
web_extension = ephy_embed_shell_get_web_extension_proxy (ephy_embed_shell_get_default ());
- if (!web_extension)
- return FALSE;
- result = g_dbus_proxy_call_sync (web_extension,
- "HasModifiedForms",
- g_variant_new ("(t)", webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- NULL);
+ if (web_extension) {
+ g_dbus_proxy_call (web_extension,
+ "HasModifiedForms",
+ g_variant_new ("(t)", webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ (GAsyncReadyCallback)has_modified_forms_cb,
+ g_object_ref (task));
+ } else {
+ g_task_return_boolean (task, FALSE);
+ }
+#else
+ WebKitDOMDocument *document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
+
+ g_task_return_boolean (task, ephy_web_dom_utils_has_modified_forms (document));
+#endif
+ g_object_unref (task);
+}
- g_variant_get (result, "(b)", &retval);
- g_variant_unref (result);
+gboolean
+ephy_web_view_has_modified_forms_finish (EphyWebView *view,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (g_task_is_valid (result, view), FALSE);
- return retval;
-#endif
+ return g_task_propagate_boolean (G_TASK (result), error);
}
/**
diff --git a/embed/ephy-web-view.h b/embed/ephy-web-view.h
index a24f96269..2e0b0672c 100644
--- a/embed/ephy-web-view.h
+++ b/embed/ephy-web-view.h
@@ -144,7 +144,13 @@ const char * ephy_web_view_get_typed_address (EphyWebView
void ephy_web_view_set_typed_address (EphyWebView *view,
const char *address);
gboolean ephy_web_view_get_is_blank (EphyWebView *view);
-gboolean ephy_web_view_has_modified_forms (EphyWebView *view);
+void ephy_web_view_has_modified_forms (EphyWebView *view,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean ephy_web_view_has_modified_forms_finish (EphyWebView *view,
+ GAsyncResult *result,
+ GError **error);
void ephy_web_view_get_security_level (EphyWebView *view,
EphyWebViewSecurityLevel *level,
GTlsCertificate **certificate,
diff --git a/src/ephy-window.c b/src/ephy-window.c
index 643d8e4e3..62a874108 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -386,6 +386,8 @@ struct _EphyWindowPrivate
guint key_theme_is_emacs : 1;
guint updating_address : 1;
guint show_lock : 1;
+ guint force_close : 1;
+ guint checking_modified_forms : 1;
};
enum
@@ -469,25 +471,19 @@ construct_confirm_close_dialog (EphyWindow *window,
static gboolean
confirm_close_with_modified_forms (EphyWindow *window)
{
- if (g_settings_get_boolean (EPHY_SETTINGS_MAIN,
- EPHY_PREFS_WARN_ON_CLOSE_UNSUBMITTED_DATA))
- {
- GtkWidget *dialog;
- int response;
+ GtkWidget *dialog;
+ int response;
- dialog = construct_confirm_close_dialog (window,
- _("There are unsubmitted changes to form elements"),
- _("If you close the document anyway, "
- "you will lose that information."),
- _("Close _Document"));
- response = gtk_dialog_run (GTK_DIALOG (dialog));
+ dialog = construct_confirm_close_dialog (window,
+ _("There are unsubmitted changes to form elements"),
+ _("If you close the document anyway, "
+ "you will lose that information."),
+ _("Close _Document"));
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
+ gtk_widget_destroy (dialog);
- return response == GTK_RESPONSE_ACCEPT;
- }
-
- return TRUE;
+ return response == GTK_RESPONSE_ACCEPT;
}
static gboolean
@@ -3187,6 +3183,33 @@ notebook_page_removed_cb (EphyNotebook *notebook,
}
static void
+ephy_window_close_tab (EphyWindow *window,
+ EphyEmbed *tab)
+{
+ gtk_widget_destroy (GTK_WIDGET (tab));
+
+ /* If that was the last tab, destroy the window. */
+ if (gtk_notebook_get_n_pages (window->priv->notebook) == 0)
+ {
+ gtk_widget_destroy (GTK_WIDGET (window));
+ }
+}
+
+static void
+tab_has_modified_forms_cb (EphyWebView *view,
+ GAsyncResult *result,
+ EphyWindow *window)
+{
+ gboolean has_modified_forms;
+
+ has_modified_forms = ephy_web_view_has_modified_forms_finish (view, result, NULL);
+ if (!has_modified_forms || confirm_close_with_modified_forms (window))
+ {
+ ephy_window_close_tab (window, EPHY_GET_EMBED_FROM_EPHY_WEB_VIEW (view));
+ }
+}
+
+static void
notebook_page_close_request_cb (EphyNotebook *notebook,
EphyEmbed *embed,
EphyWindow *window)
@@ -3207,18 +3230,18 @@ notebook_page_close_request_cb (EphyNotebook *notebook,
}
}
- if ((!ephy_web_view_has_modified_forms (ephy_embed_get_web_view (embed)) ||
- confirm_close_with_modified_forms (window)))
+ if (g_settings_get_boolean (EPHY_SETTINGS_MAIN,
+ EPHY_PREFS_WARN_ON_CLOSE_UNSUBMITTED_DATA))
{
- gtk_widget_destroy (GTK_WIDGET (embed));
+ ephy_web_view_has_modified_forms (ephy_embed_get_web_view (embed),
+ NULL,
+ (GAsyncReadyCallback)tab_has_modified_forms_cb,
+ window);
}
-
- /* If that was the last tab, destroy the window. */
- if (gtk_notebook_get_n_pages (priv->notebook) == 0)
+ else
{
- gtk_widget_destroy (GTK_WIDGET (window));
+ ephy_window_close_tab (window, embed);
}
-
}
static GtkWidget *
@@ -4401,6 +4424,94 @@ ephy_window_is_on_current_workspace (EphyWindow *window)
return wnck_window_is_on_workspace (wnck_window, workspace);
}
+typedef struct {
+ EphyWindow *window;
+ GCancellable *cancellable;
+
+ guint embeds_to_check;
+ EphyEmbed *modified_embed;
+} ModifiedFormsData;
+
+static void
+modified_forms_data_free (ModifiedFormsData *data)
+{
+ g_object_unref (data->cancellable);
+
+ g_slice_free (ModifiedFormsData, data);
+}
+
+static void
+continue_window_close_after_modified_forms_check (ModifiedFormsData *data)
+{
+ gboolean should_close;
+
+ data->window->priv->checking_modified_forms = FALSE;
+
+ if (data->modified_embed)
+ {
+ /* jump to the first tab with modified forms */
+ impl_set_active_child (EPHY_EMBED_CONTAINER (data->window),
+ data->modified_embed);
+ if (!confirm_close_with_modified_forms (data->window))
+ return;
+ }
+
+ data->window->priv->force_close = TRUE;
+ should_close = ephy_window_close (data->window);
+ data->window->priv->force_close = FALSE;
+ if (should_close)
+ gtk_widget_destroy (GTK_WIDGET (data->window));
+}
+
+static void
+has_modified_forms_cb (EphyWebView *view,
+ GAsyncResult *result,
+ ModifiedFormsData *data)
+{
+ gboolean has_modified_forms;
+
+ data->embeds_to_check--;
+ has_modified_forms = ephy_web_view_has_modified_forms_finish (view, result, NULL);
+ if (has_modified_forms)
+ {
+ /* Cancel all others */
+ g_cancellable_cancel (data->cancellable);
+ data->modified_embed = EPHY_GET_EMBED_FROM_EPHY_WEB_VIEW (view);
+ }
+
+ if (data->embeds_to_check > 0)
+ return;
+
+ continue_window_close_after_modified_forms_check (data);
+ modified_forms_data_free (data);
+}
+
+static void
+ephy_window_check_modified_forms (EphyWindow *window)
+{
+ GList *tabs, *l;
+ ModifiedFormsData *data;
+
+ window->priv->checking_modified_forms = TRUE;
+
+ data = g_slice_new0 (ModifiedFormsData);
+ data->window = window;
+ data->cancellable = g_cancellable_new ();
+ data->embeds_to_check = gtk_notebook_get_n_pages (window->priv->notebook);
+
+ tabs = impl_get_children (EPHY_EMBED_CONTAINER (window));
+ for (l = tabs; l != NULL; l = l->next)
+ {
+ EphyEmbed *embed = (EphyEmbed *) l->data;
+
+ ephy_web_view_has_modified_forms (ephy_embed_get_web_view (embed),
+ data->cancellable,
+ (GAsyncReadyCallback)has_modified_forms_cb,
+ data);
+ }
+ g_list_free (tabs);
+}
+
/**
* ephy_window_close:
* @window: an #EphyWindow
@@ -4414,45 +4525,28 @@ ephy_window_is_on_current_workspace (EphyWindow *window)
gboolean
ephy_window_close (EphyWindow *window)
{
- EphyEmbed *modified_embed = NULL;
- GList *tabs, *l;
- gboolean modified = FALSE;
-
/* We ignore the delete_event if the disable_quit lockdown has been set
*/
if (g_settings_get_boolean (EPHY_SETTINGS_LOCKDOWN,
EPHY_PREFS_LOCKDOWN_QUIT)) return FALSE;
- tabs = impl_get_children (EPHY_EMBED_CONTAINER (window));
- for (l = tabs; l != NULL; l = l->next)
- {
- EphyEmbed *embed = (EphyEmbed *) l->data;
-
- g_return_val_if_fail (EPHY_IS_EMBED (embed), FALSE);
-
- if (ephy_web_view_has_modified_forms (ephy_embed_get_web_view (embed)))
- {
- modified = TRUE;
- modified_embed = embed;
- break;
- }
+ if (window->priv->checking_modified_forms) {
+ /* stop window close */
+ return FALSE;
}
- g_list_free (tabs);
- if (modified)
+ if (g_settings_get_boolean (EPHY_SETTINGS_MAIN,
+ EPHY_PREFS_WARN_ON_CLOSE_UNSUBMITTED_DATA))
{
- /* jump to the first tab with modified forms */
- impl_set_active_child (EPHY_EMBED_CONTAINER (window),
- modified_embed);
-
- if (confirm_close_with_modified_forms (window) == FALSE)
+ if (!window->priv->force_close &&
+ gtk_notebook_get_n_pages (window->priv->notebook) > 0)
{
+ ephy_window_check_modified_forms (window);
/* stop window close */
return FALSE;
}
}
-
if (window_has_ongoing_downloads (window) && confirm_close_with_downloads (window) == FALSE)
{
/* stop window close */