[epiphany] Add support for using multiple web processes
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany] Add support for using multiple web processes
- Date: Wed, 5 Feb 2014 17:35:57 +0000 (UTC)
commit 31bc1fe6ccbe53dfd14822d44fc9563a32799316
Author: Carlos Garcia Campos <cgarcia igalia com>
Date: Thu Jan 30 17:02:05 2014 +0100
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
data/org.gnome.epiphany.gschema.xml | 5 +
embed/Makefile.am | 4 +-
embed/ephy-embed-shell.c | 237 +++++++++++-------
embed/ephy-embed-shell.h | 1 -
embed/ephy-web-extension-proxy.c | 400 ++++++++++++++++++++++++++++++
embed/ephy-web-extension-proxy.h | 100 ++++++++
embed/ephy-web-view.c | 249 +++++++++++++++----
embed/ephy-web-view.h | 17 ++
embed/web-extension/ephy-web-extension.c | 64 +++++-
lib/ephy-prefs.h | 7 +
src/window-commands.c | 98 +-------
11 files changed, 957 insertions(+), 225 deletions(-)
---
diff --git a/data/org.gnome.epiphany.gschema.xml b/data/org.gnome.epiphany.gschema.xml
index f03cfef..af140a7 100644
--- a/data/org.gnome.epiphany.gschema.xml
+++ b/data/org.gnome.epiphany.gschema.xml
@@ -66,6 +66,11 @@
<summary>Whether to delay loading of tabs that are not immediately visible on
session restore</summary>
<description>When this option is set to true, tabs will not start loading until the
user switches to them, upon session restore.</description>
</key>
+ <key name="process-model" enum="org.gnome.Epiphany.EphyPrefsProcessModel">
+ <default>'shared-secondary-process'</default>
+ <summary>Process model</summary>
+ <description>This option allows to set the process model used. Use
'shared-secondary-process' to use a single web process shared by all the tabs and
'one-secondary-process-per-web-view' to use a different web process for each tab.</description>
+ </key>
</schema>
<schema path="/org/gnome/epiphany/ui/" id="org.gnome.Epiphany.ui">
<key name="toolbar-style" enum="org.gnome.Epiphany.EphyPrefsUIToolbarStyle">
diff --git a/embed/Makefile.am b/embed/Makefile.am
index 5f6fec3..4e79e2e 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 67dbcea..42e967f 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 02016c8..f488640 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 0000000..dc67723
--- /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 0000000..fef44d2
--- /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 f50d5c5..26ac211 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 500aaab..5c817eb 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 fae0849..d6c051f 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,
diff --git a/lib/ephy-prefs.h b/lib/ephy-prefs.h
index 5c6afb0..cf39c1b 100644
--- a/lib/ephy-prefs.h
+++ b/lib/ephy-prefs.h
@@ -67,6 +67,12 @@ typedef enum
EPHY_PREFS_STATE_HISTORY_DATE_FILTER_EVER,
} EphyPrefsStateHistoryDateFilter;
+typedef enum
+{
+ EPHY_PREFS_PROCESS_MODEL_SHARED_SECONDARY_PROCESS,
+ EPHY_PREFS_PROCESS_MODEL_ONE_SECONDARY_PROCESS_PER_WEB_VIEW
+} EphyPrefsProcessModel;
+
#define EPHY_PREFS_UI_SCHEMA "org.gnome.Epiphany.ui"
#define EPHY_PREFS_UI_ALWAYS_SHOW_TABS_BAR "always-show-tabs-bar"
#define EPHY_PREFS_UI_TOOLBAR_STYLE "toolbar-style"
@@ -123,6 +129,7 @@ typedef enum
#define EPHY_PREFS_INTERNAL_VIEW_SOURCE "internal-view-source"
#define EPHY_PREFS_RESTORE_SESSION_POLICY "restore-session-policy"
#define EPHY_PREFS_RESTORE_SESSION_DELAYING_LOADS "restore-session-delaying-loads"
+#define EPHY_PREFS_PROCESS_MODEL "process-model"
#define EPHY_PREFS_LOCKDOWN_SCHEMA "org.gnome.Epiphany.lockdown"
#define EPHY_PREFS_LOCKDOWN_FULLSCREEN "disable-fullscreen"
diff --git a/src/window-commands.c b/src/window-commands.c
index 78e1952..ed95c3f 100644
--- a/src/window-commands.c
+++ b/src/window-commands.c
@@ -571,26 +571,19 @@ download_icon_and_set_image (EphyApplicationDialogData *data)
}
static void
-download_icon_or_take_snapshot (EphyApplicationDialogData *data,
- gboolean res,
- char *uri,
- char *color)
+fill_default_application_image_cb (GObject *source,
+ GAsyncResult *async_result,
+ gpointer user_data)
{
- if (uri != NULL && uri[0] != '\0')
- data->icon_href = uri;
+ EphyApplicationDialogData *data = user_data;
+ char *uri = NULL;
+ GdkRGBA color = { 0.5, 0.5, 0.5, 0.3 };
+ gboolean res = FALSE;
- if (color != NULL && color[0] != '\0')
- {
- gdk_rgba_parse (&data->icon_rgba, color);
- }
- else
- {
- data->icon_rgba.red = 0.5;
- data->icon_rgba.green = 0.5;
- data->icon_rgba.blue = 0.5;
- data->icon_rgba.alpha = 0.3;
- }
+ ephy_web_view_get_best_web_app_icon_finish (EPHY_WEB_VIEW (source), async_result, &res, &uri, &color,
NULL);
+ data->icon_href = uri;
+ data->icon_rgba = color;
if (res)
{
download_icon_and_set_image (data);
@@ -603,49 +596,9 @@ download_icon_or_take_snapshot (EphyApplicationDialogData *data,
}
static void
-fill_default_application_image_cb (GObject *source,
- GAsyncResult *async_result,
- gpointer user_data)
-{
- EphyApplicationDialogData *data = user_data;
- GVariant *result;
- char *uri = NULL;
- char *color = NULL;
- gboolean res = FALSE;
-
- result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source),
- async_result,
- NULL);
-
- if (result)
- {
- g_variant_get (result, "(bss)", &res, &uri, &color);
- g_variant_unref (result);
- }
-
- download_icon_or_take_snapshot (data, res, uri, color);
-}
-
-static void
fill_default_application_image (EphyApplicationDialogData *data)
{
- const char *base_uri;
- GDBusProxy *web_extension;
-
- base_uri = webkit_web_view_get_uri (WEBKIT_WEB_VIEW (data->view));
-
- web_extension = ephy_embed_shell_get_web_extension_proxy (ephy_embed_shell_get_default ());
- if (web_extension)
- g_dbus_proxy_call (web_extension,
- "GetBestWebAppIcon",
- g_variant_new("(ts)", webkit_web_view_get_page_id (WEBKIT_WEB_VIEW
(data->view)), base_uri),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- fill_default_application_image_cb,
- data);
- else
- download_icon_or_take_snapshot (data, FALSE, NULL, NULL);
+ ephy_web_view_get_best_web_app_icon (data->view, NULL, fill_default_application_image_cb, data);
}
typedef struct {
@@ -720,39 +673,16 @@ fill_default_application_title_cb (GObject *source,
gpointer user_data)
{
EphyApplicationDialogData *data = user_data;
- GVariant *result;
- char *title = NULL;
-
- result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source),
- async_result,
- NULL);
-
- if (result)
- {
- g_variant_get (result, "(s)", &title);
- g_variant_unref (result);
- }
+ char *title;
+ title = ephy_web_view_get_web_app_title_finish (EPHY_WEB_VIEW (source), async_result, NULL);
set_default_application_title (data, title);
}
static void
fill_default_application_title (EphyApplicationDialogData *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,
- "GetWebAppTitle",
- g_variant_new("(t)", webkit_web_view_get_page_id (WEBKIT_WEB_VIEW
(data->view))),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- fill_default_application_title_cb,
- data);
- else
- set_default_application_title (data, NULL);
+ ephy_web_view_get_web_app_title (data->view, NULL, fill_default_application_title_cb, data);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]