summaryrefslogtreecommitdiff
path: root/embed
diff options
context:
space:
mode:
authorCarlos Garcia Campos <cgarcia@igalia.com>2014-01-30 17:02:05 +0100
committerCarlos Garcia Campos <carlosgc@gnome.org>2014-02-05 18:35:46 +0100
commit31bc1fe6ccbe53dfd14822d44fc9563a32799316 (patch)
tree533039754f233176d6b199d9d2f4f27edaf13d89 /embed
parentaaf6422a17c7080f98d2d82d95ff6313ca500c0a (diff)
downloadepiphany-31bc1fe6ccbe53dfd14822d44fc9563a32799316.tar.gz
Add support for using multiple web processes
There's now a setting to set the process model. https://bugzilla.gnome.org/show_bug.cgi?id=723302
Diffstat (limited to 'embed')
-rw-r--r--embed/Makefile.am4
-rw-r--r--embed/ephy-embed-shell.c237
-rw-r--r--embed/ephy-embed-shell.h1
-rw-r--r--embed/ephy-web-extension-proxy.c400
-rw-r--r--embed/ephy-web-extension-proxy.h100
-rw-r--r--embed/ephy-web-view.c249
-rw-r--r--embed/ephy-web-view.h17
-rw-r--r--embed/web-extension/ephy-web-extension.c64
8 files changed, 931 insertions, 141 deletions
diff --git a/embed/Makefile.am b/embed/Makefile.am
index 5f6fec38f..4e79e2e54 100644
--- a/embed/Makefile.am
+++ b/embed/Makefile.am
@@ -22,7 +22,8 @@ INST_H_FILES = \
ephy-embed-utils.h \
ephy-find-toolbar.h \
ephy-overview.h \
- ephy-web-view.h
+ ephy-web-view.h \
+ ephy-web-extension-proxy.h
BUILT_SOURCES = \
@@ -45,6 +46,7 @@ libephyembed_la_SOURCES = \
ephy-overview.c \
ephy-embed-prefs.c \
ephy-web-view.c \
+ ephy-web-extension-proxy.c \
$(INST_H_FILES) \
$(NOINST_H_FILES)
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 67dbcea90..42e967f1f 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -34,6 +34,7 @@
#include "ephy-settings.h"
#include "ephy-snapshot-service.h"
#include "ephy-web-extension.h"
+#include "ephy-web-extension-proxy.h"
#include <glib/gi18n.h>
#include <gtk/gtk.h>
@@ -53,9 +54,10 @@ struct _EphyEmbedShellPrivate
EphyEmbedShellMode mode;
EphyFrecentStore *frecent_store;
EphyAboutHandler *about_handler;
- GDBusProxy *web_extension;
- guint web_extension_watch_name_id;
- guint web_extension_form_auth_save_signal_id;
+ GDBusConnection *bus;
+ GList *web_extensions;
+ guint web_extensions_page_created_signal_id;
+ guint web_extensions_form_auth_save_signal_id;
};
enum
@@ -63,7 +65,7 @@ enum
PREPARE_CLOSE,
RESTORED_WINDOW,
WEB_VIEW_CREATED,
- FORM_AUTH_DATA_SAVE_REQUESTED,
+ PAGE_CREATED,
LAST_SIGNAL
};
@@ -98,6 +100,24 @@ ephy_embed_shell_dispose (GObject *object)
G_OBJECT_CLASS (ephy_embed_shell_parent_class)->dispose (object);
}
+static gint
+web_extension_compare (EphyWebExtensionProxy *proxy,
+ const char *name_owner)
+{
+ return g_strcmp0 (ephy_web_extension_proxy_get_name_owner (proxy), name_owner);
+}
+
+static EphyWebExtensionProxy *
+ephy_embed_shell_find_web_extension (EphyEmbedShell *shell,
+ const char *name_owner)
+{
+ GList *l;
+
+ l = g_list_find_custom (shell->priv->web_extensions, name_owner, (GCompareFunc)web_extension_compare);
+
+ return l ? EPHY_WEB_EXTENSION_PROXY (l->data) : NULL;
+}
+
static void
web_extension_form_auth_save_requested (GDBusConnection *connection,
const char *sender_name,
@@ -107,85 +127,70 @@ web_extension_form_auth_save_requested (GDBusConnection *connection,
GVariant *parameters,
EphyEmbedShell *shell)
{
+ EphyWebExtensionProxy *web_extension;
guint request_id;
guint64 page_id;
const char *hostname;
const char *username;
g_variant_get (parameters, "(ut&s&s)", &request_id, &page_id, &hostname, &username);
- g_signal_emit (shell, signals[FORM_AUTH_DATA_SAVE_REQUESTED], 0,
- request_id, page_id, hostname, username);
+ web_extension = ephy_embed_shell_find_web_extension (shell, sender_name);
+ if (!web_extension)
+ return;
+ ephy_web_extension_proxy_form_auth_save_requested (web_extension, request_id, page_id, hostname, username);
}
static void
-web_extension_proxy_created_cb (GDBusProxy *proxy,
- GAsyncResult *result,
- EphyEmbedShell *shell)
-{
- GError *error = NULL;
+web_extension_page_created (GDBusConnection *connection,
+ const char *sender_name,
+ const char *object_path,
+ const char *interface_name,
+ const char *signal_name,
+ GVariant *parameters,
+ EphyEmbedShell *shell)
+{
+ EphyWebExtensionProxy *web_extension;
+ guint64 page_id;
- shell->priv->web_extension = g_dbus_proxy_new_finish (result, &error);
- if (!shell->priv->web_extension) {
- g_warning ("Error creating web extension proxy: %s\n", error->message);
- g_error_free (error);
- } else {
- shell->priv->web_extension_form_auth_save_signal_id =
- g_dbus_connection_signal_subscribe (g_dbus_proxy_get_connection (shell->priv->web_extension),
- g_dbus_proxy_get_name (shell->priv->web_extension),
- EPHY_WEB_EXTENSION_INTERFACE,
- "FormAuthDataSaveConfirmationRequired",
- EPHY_WEB_EXTENSION_OBJECT_PATH,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- (GDBusSignalCallback)web_extension_form_auth_save_requested,
- shell,
- NULL);
- }
-}
+ g_variant_get (parameters, "(t)", &page_id);
-static void
-web_extension_appeared_cb (GDBusConnection *connection,
- const gchar *name,
- const gchar *name_owner,
- EphyEmbedShell *shell)
-{
- g_dbus_proxy_new (connection,
- G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
- G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
- NULL,
- name,
- EPHY_WEB_EXTENSION_OBJECT_PATH,
- EPHY_WEB_EXTENSION_INTERFACE,
- NULL,
- (GAsyncReadyCallback)web_extension_proxy_created_cb,
- shell);
+ web_extension = ephy_embed_shell_find_web_extension (shell, sender_name);
+ if (!web_extension)
+ return;
+ g_signal_emit (shell, signals[PAGE_CREATED], 0, page_id, web_extension);
}
static void
-web_extension_vanished_cb (GDBusConnection *connection,
- const gchar *name,
- EphyEmbedShell *shell)
+web_extension_destroyed (EphyEmbedShell *shell,
+ GObject *web_extension)
{
- g_clear_object (&shell->priv->web_extension);
+ shell->priv->web_extensions = g_list_remove (shell->priv->web_extensions, web_extension);
}
static void
-ephy_embed_shell_watch_web_extension (EphyEmbedShell *shell)
+ephy_embed_shell_watch_web_extension (EphyEmbedShell *shell,
+ const char *web_extension_id)
{
+ EphyWebExtensionProxy *web_extension;
char *service_name;
- service_name = g_strdup_printf ("%s-%u", EPHY_WEB_EXTENSION_SERVICE_NAME, getpid ());
- shell->priv->web_extension_watch_name_id =
- g_bus_watch_name (G_BUS_TYPE_SESSION,
- service_name,
- G_BUS_NAME_WATCHER_FLAGS_NONE,
- (GBusNameAppearedCallback) web_extension_appeared_cb,
- (GBusNameVanishedCallback) web_extension_vanished_cb,
- shell, NULL);
+ if (!shell->priv->bus)
+ return;
+
+ service_name = g_strdup_printf ("%s-%s", EPHY_WEB_EXTENSION_SERVICE_NAME, web_extension_id);
+ web_extension = ephy_web_extension_proxy_new (shell->priv->bus, service_name);
+ shell->priv->web_extensions = g_list_prepend (shell->priv->web_extensions, web_extension);
+ g_object_weak_ref (G_OBJECT (web_extension), (GWeakNotify)web_extension_destroyed, shell);
g_free (service_name);
}
+static void
+ephy_embed_shell_unwatch_web_extension (EphyWebExtensionProxy *web_extension,
+ EphyEmbedShell *shell)
+{
+ g_object_weak_unref (G_OBJECT (web_extension), (GWeakNotify)web_extension_destroyed, shell);
+}
+
/**
* ephy_embed_shell_get_global_history_service:
* @shell: the #EphyEmbedShell
@@ -304,16 +309,73 @@ initialize_web_extensions (WebKitWebContext* web_context,
{
GVariant *user_data;
gboolean private_profile;
+ char *web_extension_id;
+ static guint web_extension_count = 0;
webkit_web_context_set_web_extensions_directory (web_context, EPHY_WEB_EXTENSIONS_DIR);
- ephy_embed_shell_watch_web_extension (shell);
+
+ web_extension_id = g_strdup_printf ("%u-%u", getpid (), ++web_extension_count);
+ ephy_embed_shell_watch_web_extension (shell, web_extension_id);
private_profile = EPHY_EMBED_SHELL_MODE_HAS_PRIVATE_PROFILE (shell->priv->mode);
- user_data = g_variant_new ("(usb)", getpid (), ephy_dot_dir (), private_profile);
+ user_data = g_variant_new ("(ssb)", web_extension_id, ephy_dot_dir (), private_profile);
webkit_web_context_set_web_extensions_initialization_user_data (web_context, user_data);
}
static void
+ephy_embed_shell_setup_web_extensions_connection (EphyEmbedShell *shell)
+{
+ GError *error = NULL;
+
+ shell->priv->bus = g_application_get_dbus_connection (G_APPLICATION (shell));
+ if (!shell->priv->bus) {
+ g_warning ("Application not connected to session bus: %s\n", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ shell->priv->web_extensions_page_created_signal_id =
+ g_dbus_connection_signal_subscribe (shell->priv->bus,
+ NULL,
+ EPHY_WEB_EXTENSION_INTERFACE,
+ "PageCreated",
+ EPHY_WEB_EXTENSION_OBJECT_PATH,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ (GDBusSignalCallback)web_extension_page_created,
+ shell,
+ NULL);
+ shell->priv->web_extensions_form_auth_save_signal_id =
+ g_dbus_connection_signal_subscribe (shell->priv->bus,
+ NULL,
+ EPHY_WEB_EXTENSION_INTERFACE,
+ "FormAuthDataSaveConfirmationRequired",
+ EPHY_WEB_EXTENSION_OBJECT_PATH,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ (GDBusSignalCallback)web_extension_form_auth_save_requested,
+ shell,
+ NULL);
+}
+
+static void
+ephy_embed_shell_setup_process_model (EphyEmbedShell *shell,
+ WebKitWebContext *web_context)
+{
+ EphyPrefsProcessModel process_model;
+
+ process_model = g_settings_get_enum (EPHY_SETTINGS_MAIN, EPHY_PREFS_PROCESS_MODEL);
+ switch (process_model) {
+ case EPHY_PREFS_PROCESS_MODEL_SHARED_SECONDARY_PROCESS:
+ webkit_web_context_set_process_model (web_context, WEBKIT_PROCESS_MODEL_SHARED_SECONDARY_PROCESS);
+ break;
+ case EPHY_PREFS_PROCESS_MODEL_ONE_SECONDARY_PROCESS_PER_WEB_VIEW:
+ webkit_web_context_set_process_model (web_context, WEBKIT_PROCESS_MODEL_ONE_SECONDARY_PROCESS_PER_WEB_VIEW);
+ break;
+ }
+}
+
+static void
ephy_embed_shell_startup (GApplication* application)
{
EphyEmbedShell *shell = EPHY_EMBED_SHELL (application);
@@ -328,7 +390,11 @@ ephy_embed_shell_startup (GApplication* application)
/* We're not remoting, setup the Web Context. */
mode = shell->priv->mode;
+
+ ephy_embed_shell_setup_web_extensions_connection (shell);
+
web_context = webkit_web_context_get_default ();
+ ephy_embed_shell_setup_process_model (shell, web_context);
g_signal_connect (web_context, "initialize-web-extensions",
G_CALLBACK (initialize_web_extensions),
shell);
@@ -369,18 +435,17 @@ ephy_embed_shell_shutdown (GApplication* application)
G_APPLICATION_CLASS (ephy_embed_shell_parent_class)->shutdown (application);
- if (priv->web_extension_watch_name_id > 0) {
- g_bus_unwatch_name (priv->web_extension_watch_name_id);
- priv->web_extension_watch_name_id = 0;
+ if (priv->web_extensions_page_created_signal_id > 0) {
+ g_dbus_connection_signal_unsubscribe (priv->bus, priv->web_extensions_page_created_signal_id);
+ priv->web_extensions_page_created_signal_id = 0;
}
- if (priv->web_extension_form_auth_save_signal_id > 0) {
- g_dbus_connection_signal_unsubscribe (g_dbus_proxy_get_connection (priv->web_extension),
- priv->web_extension_form_auth_save_signal_id);
- priv->web_extension_form_auth_save_signal_id = 0;
+ if (priv->web_extensions_form_auth_save_signal_id > 0) {
+ g_dbus_connection_signal_unsubscribe (priv->bus, priv->web_extensions_form_auth_save_signal_id);
+ priv->web_extensions_form_auth_save_signal_id = 0;
}
- g_clear_object (&priv->web_extension);
+ g_list_foreach (priv->web_extensions, (GFunc)ephy_embed_shell_unwatch_web_extension, application);
ephy_embed_prefs_shutdown ();
}
@@ -507,29 +572,23 @@ ephy_embed_shell_class_init (EphyEmbedShellClass *klass)
G_TYPE_NONE, 1,
EPHY_TYPE_WEB_VIEW);
- /*
- * EphyEmbedShell::form-auth-data-save-requested:
+ /**
+ * EphyEmbedShell::page-created:
* @shell: the #EphyEmbedShell
- * @request_id: the identifier of the request
- * @page_id: the identifier of the web page
- * @hostname: the hostname
- * @username: the username
+ * @page_id: the identifier of the web page created
+ * @web_extension: the #EphyWebExtensionProxy
*
- * Emitted when a web page requests confirmation to save
- * the form authentication data for the given @hostname and
- * @username
- **/
- signals[FORM_AUTH_DATA_SAVE_REQUESTED] =
- g_signal_new ("form-auth-data-save-requested",
+ * Emitted when a web page is created in the web process.
+ */
+ signals[PAGE_CREATED] =
+ g_signal_new ("page-created",
EPHY_TYPE_EMBED_SHELL,
G_SIGNAL_RUN_FIRST,
0, NULL, NULL,
g_cclosure_marshal_generic,
- G_TYPE_NONE, 4,
- G_TYPE_UINT,
+ G_TYPE_NONE, 2,
G_TYPE_UINT64,
- G_TYPE_STRING,
- G_TYPE_STRING);
+ EPHY_TYPE_WEB_EXTENSION_PROXY);
g_type_class_add_private (object_class, sizeof (EphyEmbedShellPrivate));
}
@@ -728,14 +787,6 @@ ephy_embed_shell_launch_handler (EphyEmbedShell *shell,
return ret;
}
-GDBusProxy *
-ephy_embed_shell_get_web_extension_proxy (EphyEmbedShell *shell)
-{
- g_return_val_if_fail (EPHY_IS_EMBED_SHELL (shell), NULL);
-
- return shell->priv->web_extension;
-}
-
/**
* ephy_embed_shell_clear_cache:
* @shell: an #EphyEmbedShell
diff --git a/embed/ephy-embed-shell.h b/embed/ephy-embed-shell.h
index 02016c819..f48864039 100644
--- a/embed/ephy-embed-shell.h
+++ b/embed/ephy-embed-shell.h
@@ -89,7 +89,6 @@ gboolean ephy_embed_shell_launch_handler (EphyEmbedShell
const char *mime_type,
guint32 user_time);
void ephy_embed_shell_clear_cache (EphyEmbedShell *shell);
-GDBusProxy *ephy_embed_shell_get_web_extension_proxy (EphyEmbedShell *shell);
G_END_DECLS
diff --git a/embed/ephy-web-extension-proxy.c b/embed/ephy-web-extension-proxy.c
new file mode 100644
index 000000000..dc67723dc
--- /dev/null
+++ b/embed/ephy-web-extension-proxy.c
@@ -0,0 +1,400 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Copyright © 2014 Igalia S.L.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <config.h>
+#include "ephy-web-extension-proxy.h"
+
+#include "ephy-web-extension.h"
+
+struct _EphyWebExtensionProxyPrivate
+{
+ GDBusProxy *proxy;
+ gchar *name_owner;
+ guint watch_name_id;
+ guint form_auth_save_signal_id;
+};
+
+enum
+{
+ FORM_AUTH_DATA_SAVE_REQUESTED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (EphyWebExtensionProxy, ephy_web_extension_proxy, G_TYPE_OBJECT)
+
+static void
+ephy_web_extension_proxy_finalize (GObject *object)
+{
+ EphyWebExtensionProxyPrivate *priv = EPHY_WEB_EXTENSION_PROXY (object)->priv;
+
+ g_clear_object (&priv->proxy);
+
+ G_OBJECT_CLASS (ephy_web_extension_proxy_parent_class)->finalize (object);
+}
+
+static void
+ephy_web_extension_proxy_dispose (GObject *object)
+{
+ EphyWebExtensionProxyPrivate *priv = EPHY_WEB_EXTENSION_PROXY (object)->priv;
+
+ if (priv->watch_name_id > 0) {
+ g_bus_unwatch_name (priv->watch_name_id);
+ priv->watch_name_id = 0;
+ }
+
+ g_clear_pointer (&priv->name_owner, g_free);
+
+ G_OBJECT_CLASS (ephy_web_extension_proxy_parent_class)->dispose (object);
+}
+
+static void
+ephy_web_extension_proxy_init (EphyWebExtensionProxy *web_extension)
+{
+ web_extension->priv = G_TYPE_INSTANCE_GET_PRIVATE (web_extension, EPHY_TYPE_WEB_EXTENSION_PROXY, EphyWebExtensionProxyPrivate);
+}
+
+static void
+ephy_web_extension_proxy_class_init (EphyWebExtensionProxyClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = ephy_web_extension_proxy_finalize;
+ object_class->dispose = ephy_web_extension_proxy_dispose;
+
+ /**
+ * EphyWebExtensionProxy::form-auth-data-save-requested:
+ * @web_extension: the #EphyWebExtensionProxy
+ * @request_id: the identifier of the request
+ * @page_id: the identifier of the web page
+ * @hostname: the hostname
+ * @username: the username
+ *
+ * Emitted when a web page requests confirmation to save
+ * the form authentication data for the given @hostname and
+ * @username
+ **/
+ signals[FORM_AUTH_DATA_SAVE_REQUESTED] =
+ g_signal_new ("form-auth-data-save-requested",
+ EPHY_TYPE_WEB_EXTENSION_PROXY,
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE, 4,
+ G_TYPE_UINT,
+ G_TYPE_UINT64,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+
+ g_type_class_add_private (object_class, sizeof (EphyWebExtensionProxyPrivate));
+}
+
+static void
+web_extension_proxy_created_cb (GDBusProxy *proxy,
+ GAsyncResult *result,
+ EphyWebExtensionProxy *web_extension)
+{
+ GError *error = NULL;
+
+ web_extension->priv->proxy = g_dbus_proxy_new_finish (result, &error);
+ if (!web_extension->priv->proxy) {
+ g_warning ("Error creating web extension proxy: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+web_extension_appeared_cb (GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ EphyWebExtensionProxy *web_extension)
+{
+ web_extension->priv->name_owner = g_strdup (name_owner);
+ g_dbus_proxy_new (connection,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ NULL,
+ name,
+ EPHY_WEB_EXTENSION_OBJECT_PATH,
+ EPHY_WEB_EXTENSION_INTERFACE,
+ NULL,
+ (GAsyncReadyCallback)web_extension_proxy_created_cb,
+ web_extension);
+}
+
+static void
+ephy_web_extension_proxy_watch_name (EphyWebExtensionProxy *web_extension,
+ GDBusConnection* bus,
+ const char *service_name)
+{
+ EphyWebExtensionProxyPrivate *priv = web_extension->priv;
+
+ priv->watch_name_id =
+ g_bus_watch_name_on_connection (bus,
+ service_name,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ (GBusNameAppearedCallback)web_extension_appeared_cb,
+ NULL,
+ web_extension,
+ (GDestroyNotify)g_object_unref);
+}
+
+EphyWebExtensionProxy *
+ephy_web_extension_proxy_new (GDBusConnection *bus,
+ const char *service_name)
+{
+ EphyWebExtensionProxy *web_extension;
+
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (bus), NULL);
+ g_return_val_if_fail (service_name != NULL, NULL);
+
+ web_extension = g_object_new (EPHY_TYPE_WEB_EXTENSION_PROXY, NULL);
+ ephy_web_extension_proxy_watch_name (web_extension, bus, service_name);
+
+ return web_extension;
+}
+
+const char *
+ephy_web_extension_proxy_get_name_owner (EphyWebExtensionProxy *web_extension)
+{
+ g_return_val_if_fail (EPHY_IS_WEB_EXTENSION_PROXY (web_extension), NULL);
+
+ return web_extension->priv->name_owner;
+}
+
+void
+ephy_web_extension_proxy_form_auth_save_requested (EphyWebExtensionProxy *web_extension,
+ guint request_id,
+ guint64 page_id,
+ const char *hostname,
+ const char *username)
+{
+ g_return_if_fail (EPHY_IS_WEB_EXTENSION_PROXY (web_extension));
+
+ g_signal_emit (web_extension, signals[FORM_AUTH_DATA_SAVE_REQUESTED], 0,
+ request_id, page_id, hostname, username);
+}
+
+void
+ephy_web_extension_proxy_form_auth_data_save_confirmation_response (EphyWebExtensionProxy *web_extension,
+ guint request_id,
+ gboolean response)
+{
+ g_return_if_fail (EPHY_IS_WEB_EXTENSION_PROXY (web_extension));
+
+ if (!web_extension->priv->proxy)
+ return;
+
+ g_dbus_proxy_call (web_extension->priv->proxy,
+ "FormAuthDataSaveConfirmationResponse",
+ g_variant_new ("(ub)", request_id, response),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, NULL, NULL);
+}
+
+static void
+has_modified_forms_cb (GDBusProxy *proxy,
+ GAsyncResult *result,
+ GTask *task)
+{
+ GVariant *return_value;
+ gboolean retval = FALSE;
+
+ return_value = g_dbus_proxy_call_finish (proxy, 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);
+}
+
+void
+ephy_web_extension_proxy_web_page_has_modified_forms (EphyWebExtensionProxy *web_extension,
+ guint64 page_id,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+
+ g_return_if_fail (EPHY_IS_WEB_EXTENSION_PROXY (web_extension));
+
+ task = g_task_new (web_extension, cancellable, callback, user_data);
+
+ if (web_extension->priv->proxy) {
+ g_dbus_proxy_call (web_extension->priv->proxy,
+ "HasModifiedForms",
+ g_variant_new ("(t)", page_id),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ (GAsyncReadyCallback)has_modified_forms_cb,
+ g_object_ref (task));
+ } else {
+ g_task_return_boolean (task, FALSE);
+ }
+
+ g_object_unref (task);
+}
+
+gboolean
+ephy_web_extension_proxy_web_page_has_modified_forms_finish (EphyWebExtensionProxy *web_extension,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (g_task_is_valid (result, web_extension), FALSE);
+
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+static void
+get_best_web_app_icon_cb (GDBusProxy *proxy,
+ GAsyncResult *result,
+ GTask *task)
+{
+ GVariant *retval;
+ GError *error = NULL;
+
+ retval = g_dbus_proxy_call_finish (proxy, result, &error);
+ if (!retval) {
+ g_task_return_error (task, error);
+ } else {
+ g_task_return_pointer (task, retval, (GDestroyNotify)g_variant_unref);
+ }
+ g_object_unref (task);
+}
+
+void
+ephy_web_extension_proxy_get_best_web_app_icon (EphyWebExtensionProxy *web_extension,
+ guint64 page_id,
+ const char *base_uri,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+
+ g_return_if_fail (EPHY_IS_WEB_EXTENSION_PROXY (web_extension));
+
+ task = g_task_new (web_extension, cancellable, callback, user_data);
+
+ if (web_extension->priv->proxy) {
+ g_dbus_proxy_call (web_extension->priv->proxy,
+ "GetBestWebAppIcon",
+ g_variant_new("(ts)", page_id, base_uri),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ (GAsyncReadyCallback)get_best_web_app_icon_cb,
+ g_object_ref (task));
+ } else {
+ g_task_return_boolean (task, FALSE);
+ }
+
+ g_object_unref (task);
+}
+
+gboolean
+ephy_web_extension_proxy_get_best_web_app_icon_finish (EphyWebExtensionProxy *web_extension,
+ GAsyncResult *result,
+ gboolean *icon_result,
+ char **icon_uri,
+ char **icon_color,
+ GError **error)
+{
+ GVariant *variant;
+ GTask *task = G_TASK (result);
+
+ g_return_val_if_fail (g_task_is_valid (result, web_extension), FALSE);
+
+ variant = g_task_propagate_pointer (task, error);
+ if (!variant)
+ return FALSE;
+
+ g_variant_get (variant, "(bss)", icon_result, icon_uri, icon_color);
+ g_variant_unref (variant);
+
+ return TRUE;
+}
+
+static void
+get_web_app_title_cb (GDBusProxy *proxy,
+ GAsyncResult *result,
+ GTask *task)
+{
+ GVariant *retval;
+ GError *error = NULL;
+
+ retval = g_dbus_proxy_call_finish (proxy, result, &error);
+ if (!retval) {
+ g_task_return_error (task, error);
+ } else {
+ char *title;
+
+ g_variant_get (retval, "(s)", &title);
+ g_task_return_pointer (task, title, (GDestroyNotify)g_free);
+ g_variant_unref (retval);
+ }
+ g_object_unref (task);
+}
+
+void
+ephy_web_extension_proxy_get_web_app_title (EphyWebExtensionProxy *web_extension,
+ guint64 page_id,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+
+ g_return_if_fail (EPHY_IS_WEB_EXTENSION_PROXY (web_extension));
+
+ task = g_task_new (web_extension, cancellable, callback, user_data);
+
+ if (web_extension->priv->proxy) {
+ g_dbus_proxy_call (web_extension->priv->proxy,
+ "GetWebAppTitle",
+ g_variant_new("(t)", page_id),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ (GAsyncReadyCallback)get_web_app_title_cb,
+ g_object_ref (task));
+ } else {
+ g_task_return_pointer (task, NULL, NULL);
+ }
+
+ g_object_unref (task);
+}
+
+char *
+ephy_web_extension_proxy_get_web_app_title_finish (EphyWebExtensionProxy *web_extension,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (g_task_is_valid (result, web_extension), FALSE);
+
+ return g_task_propagate_pointer (G_TASK (result), error);
+}
diff --git a/embed/ephy-web-extension-proxy.h b/embed/ephy-web-extension-proxy.h
new file mode 100644
index 000000000..fef44d2a7
--- /dev/null
+++ b/embed/ephy-web-extension-proxy.h
@@ -0,0 +1,100 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Copyright © 2014 Igalia S.L.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if !defined (__EPHY_EPIPHANY_H_INSIDE__) && !defined (EPIPHANY_COMPILATION)
+#error "Only <epiphany/epiphany.h> can be included directly."
+#endif
+
+#ifndef EPHY_WEB_EXTENSION_PROXY_H
+#define EPHY_WEB_EXTENSION_PROXY_H
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_WEB_EXTENSION_PROXY (ephy_web_extension_proxy_get_type ())
+#define EPHY_WEB_EXTENSION_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_WEB_EXTENSION_PROXY, EphyWebExtensionProxy))
+#define EPHY_IS_WEB_EXTENSION_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_WEB_EXTENSION_PROXY))
+#define EPHY_WEB_EXTENSION_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_WEB_EXTENSION_PROXY, EphyWebExtensionProxyClass))
+#define EPHY_IS_WEB_EXTENSION_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_WEB_EXTENSION_PROXY))
+#define EPHY_WEB_EXTENSION_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_WEB_EXTENSION_PROXY, EphyWebExtensionProxyClass))
+
+typedef struct _EphyWebExtensionProxyClass EphyWebExtensionProxyClass;
+typedef struct _EphyWebExtensionProxy EphyWebExtensionProxy;
+typedef struct _EphyWebExtensionProxyPrivate EphyWebExtensionProxyPrivate;
+
+struct _EphyWebExtensionProxy
+{
+ GObject parent;
+
+ /*< private >*/
+ EphyWebExtensionProxyPrivate *priv;
+};
+
+struct _EphyWebExtensionProxyClass
+{
+ GObjectClass parent_class;
+};
+
+GType ephy_web_extension_proxy_get_type (void);
+
+EphyWebExtensionProxy *ephy_web_extension_proxy_new (GDBusConnection *bus,
+ const char *service_name);
+const char * ephy_web_extension_proxy_get_name_owner (EphyWebExtensionProxy *web_extension);
+void ephy_web_extension_proxy_form_auth_save_requested (EphyWebExtensionProxy *web_extension,
+ guint request_id,
+ guint64 page_id,
+ const char *hostname,
+ const char *username);
+void ephy_web_extension_proxy_form_auth_data_save_confirmation_response (EphyWebExtensionProxy *web_extension,
+ guint request_id,
+ gboolean response);
+void ephy_web_extension_proxy_web_page_has_modified_forms (EphyWebExtensionProxy *web_extension,
+ guint64 page_id,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean ephy_web_extension_proxy_web_page_has_modified_forms_finish (EphyWebExtensionProxy *web_extension,
+ GAsyncResult *result,
+ GError **error);
+void ephy_web_extension_proxy_get_best_web_app_icon (EphyWebExtensionProxy *web_extension,
+ guint64 page_id,
+ const char *base_uri,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean ephy_web_extension_proxy_get_best_web_app_icon_finish (EphyWebExtensionProxy *web_extension,
+ GAsyncResult *result,
+ gboolean *icon_result,
+ char **icon_uri,
+ char **icon_color,
+ GError **error);
+void ephy_web_extension_proxy_get_web_app_title (EphyWebExtensionProxy *web_extension,
+ guint64 page_id,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+char *ephy_web_extension_proxy_get_web_app_title_finish (EphyWebExtensionProxy *web_extension,
+ GAsyncResult *result,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* !EPHY_WEB_EXTENSION_PROXY_H */
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index f50d5c5ed..26ac21190 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -43,6 +43,7 @@
#include "ephy-string.h"
#include "ephy-web-app-utils.h"
#include "ephy-web-dom-utils.h"
+#include "ephy-web-extension-proxy.h"
#include "ephy-zoom.h"
#include <gio/gio.h>
@@ -111,6 +112,9 @@ struct _EphyWebViewPrivate {
/* TLS information. */
GTlsCertificate *certificate;
GTlsCertificateFlags tls_errors;
+
+ /* Web Extension */
+ EphyWebExtensionProxy *web_extension;
};
typedef struct {
@@ -607,50 +611,71 @@ icon_changed_cb (EphyWebView *view,
_ephy_web_view_update_icon (view);
}
+typedef struct {
+ EphyWebView *web_view;
+ guint request_id;
+} FormAuthRequestData;
+
static void
form_auth_data_save_confirmation_response (GtkInfoBar *info_bar,
gint response_id,
- gpointer user_data)
+ FormAuthRequestData *data)
{
- GDBusProxy *web_extension;
- guint request_id = GPOINTER_TO_INT (user_data);
-
gtk_widget_destroy (GTK_WIDGET (info_bar));
- web_extension = ephy_embed_shell_get_web_extension_proxy (ephy_embed_shell_get_default ());
- if (!web_extension)
- return;
+ if (data->web_view->priv->web_extension) {
+ ephy_web_extension_proxy_form_auth_data_save_confirmation_response (data->web_view->priv->web_extension,
+ data->request_id,
+ response_id == GTK_RESPONSE_YES);
+ }
- g_dbus_proxy_call (web_extension,
- "FormAuthDataSaveConfirmationResponse",
- g_variant_new ("(ub)", request_id, response_id == GTK_RESPONSE_YES),
- G_DBUS_CALL_FLAGS_NONE,
- -1, NULL, NULL, NULL);
+ g_slice_free (FormAuthRequestData, data);
}
static void
-form_auth_data_save_requested (EphyEmbedShell *shell,
+form_auth_data_save_requested (EphyWebExtensionProxy *web_extension,
guint request_id,
guint64 page_id,
const char *hostname,
const char *username,
- WebKitWebView *web_view)
+ EphyWebView *web_view)
{
GtkWidget *info_bar;
+ FormAuthRequestData *data;
- if (webkit_web_view_get_page_id (web_view) != page_id)
- return;
+ g_assert (webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view)) == page_id);
- info_bar = ephy_web_view_create_form_auth_save_confirmation_info_bar (EPHY_WEB_VIEW (web_view),
- hostname, username);
+ info_bar = ephy_web_view_create_form_auth_save_confirmation_info_bar (web_view, hostname, username);
+ data = g_slice_new (FormAuthRequestData);
+ data->web_view = web_view;
+ data->request_id = request_id;
g_signal_connect (info_bar, "response",
G_CALLBACK (form_auth_data_save_confirmation_response),
- GINT_TO_POINTER (request_id));
+ data);
gtk_widget_show (info_bar);
}
static void
+page_created_cb (EphyEmbedShell *shell,
+ guint64 page_id,
+ EphyWebExtensionProxy *web_extension,
+ EphyWebView *web_view)
+{
+ EphyWebViewPrivate *priv = web_view->priv;
+
+ if (webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view)) != page_id)
+ return;
+
+ priv->web_extension = web_extension;
+ g_object_add_weak_pointer (G_OBJECT (priv->web_extension), (gpointer *)&priv->web_extension);
+
+ g_signal_connect (priv->web_extension, "form-auth-data-save-requested",
+ G_CALLBACK (form_auth_data_save_requested),
+ web_view);
+}
+
+static void
ephy_web_view_dispose (GObject *object)
{
EphyWebViewPrivate *priv = EPHY_WEB_VIEW (object)->priv;
@@ -2001,8 +2026,8 @@ ephy_web_view_init (EphyWebView *web_view)
G_CALLBACK (ge_popup_blocked_cb),
NULL);
- g_signal_connect (ephy_embed_shell_get_default (), "form-auth-data-save-requested",
- G_CALLBACK (form_auth_data_save_requested),
+ g_signal_connect (ephy_embed_shell_get_default (), "page-created",
+ G_CALLBACK (page_created_cb),
web_view);
}
@@ -2575,19 +2600,13 @@ ephy_web_view_set_typed_address (EphyWebView *view,
}
static void
-has_modified_forms_cb (GDBusProxy *web_extension,
+has_modified_forms_cb (EphyWebExtensionProxy *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);
- }
+ gboolean retval;
+ retval = ephy_web_extension_proxy_web_page_has_modified_forms_finish (web_extension, result, NULL);
g_task_return_boolean (task, retval);
g_object_unref (task);
}
@@ -2612,19 +2631,18 @@ ephy_web_view_has_modified_forms (EphyWebView *view,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GTask *task = g_task_new (view, cancellable, callback, user_data);
- GDBusProxy *web_extension;
-
- web_extension = ephy_embed_shell_get_web_extension_proxy (ephy_embed_shell_get_default ());
- 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));
+ GTask *task;
+
+ g_return_if_fail (EPHY_IS_WEB_VIEW (view));
+
+ task = g_task_new (view, cancellable, callback, user_data);
+
+ if (view->priv->web_extension) {
+ ephy_web_extension_proxy_web_page_has_modified_forms (view->priv->web_extension,
+ webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
+ cancellable,
+ (GAsyncReadyCallback)has_modified_forms_cb,
+ g_object_ref (task));
} else {
g_task_return_boolean (task, FALSE);
}
@@ -2642,6 +2660,151 @@ ephy_web_view_has_modified_forms_finish (EphyWebView *view,
return g_task_propagate_boolean (G_TASK (result), error);
}
+typedef struct {
+ gboolean icon_result;
+ char *icon_uri;
+ char *icon_color;
+} GetBestWebAppIconAsyncData;
+
+static void
+get_best_web_app_icon_async_data_free (GetBestWebAppIconAsyncData *data)
+{
+ g_free (data->icon_uri);
+ g_free (data->icon_color);
+
+ g_slice_free (GetBestWebAppIconAsyncData, data);
+}
+
+static void
+get_best_web_app_icon_cb (EphyWebExtensionProxy *web_extension,
+ GAsyncResult *result,
+ GTask *task)
+{
+ gboolean retval = FALSE;
+ char *uri = NULL;
+ char *color = NULL;
+ GError *error = NULL;
+
+ if (!ephy_web_extension_proxy_get_best_web_app_icon_finish (web_extension, result, &retval, &uri, &color, &error)) {
+ g_task_return_error (task, error);
+ } else {
+ GetBestWebAppIconAsyncData *data = g_slice_new0 (GetBestWebAppIconAsyncData);
+
+ data->icon_result = retval;
+ data->icon_uri = uri;
+ data->icon_color = color;
+ g_task_return_pointer (task, data, (GDestroyNotify)get_best_web_app_icon_async_data_free);
+ }
+ g_object_unref (task);
+}
+
+void
+ephy_web_view_get_best_web_app_icon (EphyWebView *view,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+
+ g_return_if_fail (EPHY_IS_WEB_VIEW (view));
+
+ task = g_task_new (view, cancellable, callback, user_data);
+
+ if (view->priv->web_extension) {
+ ephy_web_extension_proxy_get_best_web_app_icon (view->priv->web_extension,
+ webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
+ webkit_web_view_get_uri (WEBKIT_WEB_VIEW (view)),
+ cancellable,
+ (GAsyncReadyCallback)get_best_web_app_icon_cb,
+ g_object_ref (task));
+ } else {
+ g_task_return_boolean (task, FALSE);
+ }
+
+ g_object_unref (task);
+}
+
+gboolean
+ephy_web_view_get_best_web_app_icon_finish (EphyWebView *view,
+ GAsyncResult *result,
+ gboolean *icon_result,
+ char **icon_uri,
+ GdkRGBA *icon_color,
+ GError **error)
+{
+ GetBestWebAppIconAsyncData *data;
+ GTask *task = G_TASK (result);
+
+ g_return_val_if_fail (g_task_is_valid (result, view), FALSE);
+
+ data = g_task_propagate_pointer (task, error);
+ if (!data)
+ return FALSE;
+
+ if (data->icon_uri != NULL && data->icon_uri[0] != '\0') {
+ *icon_uri = data->icon_uri;
+ data->icon_uri = NULL;
+ }
+
+ if (data->icon_color != NULL && data->icon_color[0] != '\0')
+ gdk_rgba_parse (icon_color, data->icon_color);
+
+ get_best_web_app_icon_async_data_free (data);
+
+ return TRUE;
+}
+
+static void
+get_web_app_title_cb (EphyWebExtensionProxy *web_extension,
+ GAsyncResult *result,
+ GTask *task)
+{
+ char *retval;
+ GError *error = NULL;
+
+ retval = ephy_web_extension_proxy_get_web_app_title_finish (web_extension, result, &error);
+ if (!retval)
+ g_task_return_error (task, error);
+ else
+ g_task_return_pointer (task, retval, (GDestroyNotify)g_free);
+ g_object_unref (task);
+}
+
+void
+ephy_web_view_get_web_app_title (EphyWebView *view,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+
+ g_return_if_fail (EPHY_IS_WEB_VIEW (view));
+
+ task = g_task_new (view, cancellable, callback, user_data);
+
+ if (view->priv->web_extension) {
+ ephy_web_extension_proxy_get_web_app_title (view->priv->web_extension,
+ webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
+ cancellable,
+ (GAsyncReadyCallback)get_web_app_title_cb,
+ g_object_ref (task));
+ } else {
+ g_task_return_pointer (task, NULL, NULL);
+ }
+
+ g_object_unref (task);
+}
+
+char *
+ephy_web_view_get_web_app_title_finish (EphyWebView *view,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (g_task_is_valid (result, view), NULL);
+
+ return g_task_propagate_pointer (G_TASK (result), error);
+}
+
/**
* ephy_web_view_get_security_level:
* @view: an #EphyWebView
diff --git a/embed/ephy-web-view.h b/embed/ephy-web-view.h
index 500aaab0f..5c817eb49 100644
--- a/embed/ephy-web-view.h
+++ b/embed/ephy-web-view.h
@@ -160,6 +160,23 @@ void ephy_web_view_load_error_page (EphyWebView
const char *uri,
EphyWebViewErrorPage page,
GError *error);
+void ephy_web_view_get_best_web_app_icon (EphyWebView *view,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean ephy_web_view_get_best_web_app_icon_finish (EphyWebView *view,
+ GAsyncResult *result,
+ gboolean *icon_result,
+ char **icon_uri,
+ GdkRGBA *icon_color,
+ GError **error);
+void ephy_web_view_get_web_app_title (EphyWebView *view,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+char *ephy_web_view_get_web_app_title_finish (EphyWebView *view,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
diff --git a/embed/web-extension/ephy-web-extension.c b/embed/web-extension/ephy-web-extension.c
index fae08492c..d6c051fc0 100644
--- a/embed/web-extension/ephy-web-extension.c
+++ b/embed/web-extension/ephy-web-extension.c
@@ -40,10 +40,14 @@
static UriTester *uri_tester;
static EphyFormAuthDataCache *form_auth_data_cache;
static GDBusConnection *dbus_connection;
+static GArray *page_created_signals_pending;
static const char introspection_xml[] =
"<node>"
" <interface name='org.gnome.Epiphany.WebExtension'>"
+ " <signal name='PageCreated'>"
+ " <arg type='t' name='page_id' direction='out'/>"
+ " </signal>"
" <method name='HasModifiedForms'>"
" <arg type='t' name='page_id' direction='in'/>"
" <arg type='b' name='has_modified_forms' direction='out'/>"
@@ -945,10 +949,63 @@ web_page_document_loaded (WebKitWebPage *web_page,
}
static void
+emit_page_created (guint64 page_id)
+{
+ GError *error = NULL;
+
+ g_dbus_connection_emit_signal (dbus_connection,
+ NULL,
+ EPHY_WEB_EXTENSION_OBJECT_PATH,
+ EPHY_WEB_EXTENSION_INTERFACE,
+ "PageCreated",
+ g_variant_new ("(t)", page_id),
+ &error);
+ if (error) {
+ g_warning ("Error emitting signal PageCreated: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+emit_page_created_signals_pending (void)
+{
+ guint i;
+
+ if (!page_created_signals_pending)
+ return;
+
+ for (i = 0; i < page_created_signals_pending->len; i++) {
+ guint64 page_id;
+
+ page_id = g_array_index (page_created_signals_pending, guint64, i);
+ emit_page_created (page_id);
+ }
+
+ g_array_free (page_created_signals_pending, TRUE);
+ page_created_signals_pending = NULL;
+}
+
+static void
+queue_page_created_signal_emission (guint64 page_id)
+{
+ if (!page_created_signals_pending)
+ page_created_signals_pending = g_array_new (FALSE, FALSE, sizeof (guint64));
+ page_created_signals_pending = g_array_append_val (page_created_signals_pending, page_id);
+}
+
+static void
web_page_created_callback (WebKitWebExtension *extension,
WebKitWebPage *web_page,
gpointer user_data)
{
+ guint64 page_id;
+
+ page_id = webkit_web_page_get_id (web_page);
+ if (dbus_connection)
+ emit_page_created (page_id);
+ else
+ queue_page_created_signal_emission (page_id);
+
g_signal_connect_object (web_page, "send-request",
G_CALLBACK (web_page_send_request),
NULL, 0);
@@ -1090,6 +1147,7 @@ bus_acquired_cb (GDBusConnection *connection,
} else {
dbus_connection = connection;
g_object_add_weak_pointer (G_OBJECT (connection), (gpointer *)&dbus_connection);
+ emit_page_created_signals_pending ();
}
}
@@ -1098,11 +1156,11 @@ webkit_web_extension_initialize_with_user_data (WebKitWebExtension *extension,
GVariant *user_data)
{
char *service_name;
- guint extension_id;
+ const char *extension_id;
const char *dot_dir;
gboolean private_profile;
- g_variant_get (user_data, "(u&sb)", &extension_id, &dot_dir, &private_profile);
+ g_variant_get (user_data, "(&s&sb)", &extension_id, &dot_dir, &private_profile);
ephy_debug_init ();
uri_tester = uri_tester_new (dot_dir);
@@ -1113,7 +1171,7 @@ webkit_web_extension_initialize_with_user_data (WebKitWebExtension *extension,
G_CALLBACK (web_page_created_callback),
NULL);
- service_name = g_strdup_printf ("%s-%u", EPHY_WEB_EXTENSION_SERVICE_NAME, extension_id);
+ service_name = g_strdup_printf ("%s-%s", EPHY_WEB_EXTENSION_SERVICE_NAME, extension_id);
g_bus_own_name (G_BUS_TYPE_SESSION,
service_name,
G_BUS_NAME_OWNER_FLAGS_NONE,