[geary/mjog/558-webkit-shared-process: 6/11] Re-use WebKitGTK WebProcesses between ConversationWebView
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/mjog/558-webkit-shared-process: 6/11] Re-use WebKitGTK WebProcesses between ConversationWebView
- Date: Tue, 26 Nov 2019 08:39:35 +0000 (UTC)
commit 5b04686dbbbd22fce61474be91e858251c0e13cc
Author: Michael Gratton <mike vee net>
Date: Tue Nov 26 14:15:58 2019 +1100
Re-use WebKitGTK WebProcesses between ConversationWebView
Add a new ctor to Component.WebView and ConversationWebView to be able
to use the WebKit.WebView::related-view property at construction time.
Add new ConversationViewer::previous-web-view property to store
the per-window last created web view. Use this when constructing new
wen views in ConversationMessage to share the WebProcess.
src/client/components/components-web-view.vala | 111 +++++++++++++--------
.../conversation-viewer/conversation-message.vala | 17 +++-
.../conversation-viewer/conversation-viewer.vala | 8 ++
.../conversation-viewer/conversation-web-view.vala | 35 ++++++-
4 files changed, 121 insertions(+), 50 deletions(-)
---
diff --git a/src/client/components/components-web-view.vala b/src/client/components/components-web-view.vala
index 7d6cdcb1..c630505e 100644
--- a/src/client/components/components-web-view.vala
+++ b/src/client/components/components-web-view.vala
@@ -1,6 +1,6 @@
/*
* Copyright 2016 Software Freedom Conservancy Inc.
- * Copyright 2016 Michael Gratton <mike vee net>
+ * Copyright 2016-2019 Michael Gratton <mike vee net>
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
@@ -294,7 +294,8 @@ public abstract class Components.WebView : WebKit.WebView, Geary.BaseInterface {
protected WebView(Application.Configuration config,
- WebKit.UserContentManager? custom_manager = null) {
+ WebKit.UserContentManager? custom_manager = null,
+ WebView? related = null) {
WebKit.Settings setts = new WebKit.Settings();
setts.allow_modal_dialogs = false;
setts.default_charset = "UTF-8";
@@ -321,53 +322,31 @@ public abstract class Components.WebView : WebKit.WebView, Geary.BaseInterface {
}
Object(
- web_context: WebView.default_context,
+ settings: setts,
user_content_manager: content_manager,
- settings: setts
+ web_context: WebView.default_context
);
base_ref();
+ init(config);
+ }
- // XXX get the allow prefix from the extension somehow
-
- this.decide_policy.connect(on_decide_policy);
- this.web_process_terminated.connect((reason) => {
- warning("Web process crashed: %s", reason.to_string());
- });
-
- register_message_handler(
- COMMAND_STACK_CHANGED, on_command_stack_changed
- );
- register_message_handler(
- CONTENT_LOADED, on_content_loaded
- );
- register_message_handler(
- DOCUMENT_MODIFIED, on_document_modified
- );
- register_message_handler(
- PREFERRED_HEIGHT_CHANGED, on_preferred_height_changed
- );
- register_message_handler(
- REMOTE_IMAGE_LOAD_BLOCKED, on_remote_image_load_blocked
- );
- register_message_handler(
- SELECTION_CHANGED, on_selection_changed
+ /**
+ * Constructs a new web view with a new shared WebProcess.
+ *
+ * The new view will use the same WebProcess, settings and content
+ * manager as the given related view's.
+ *
+ * @see WebKit.WebView.with_related_view
+ */
+ protected WebView.with_related_view(Application.Configuration config,
+ WebView related) {
+ Object(
+ related_view: related,
+ settings: related.get_settings(),
+ user_content_manager: related.user_content_manager
);
-
- // Manage zoom level, ensure it's sane
- config.bind(Application.Configuration.CONVERSATION_VIEWER_ZOOM_KEY, this, "zoom_level");
- if (this.zoom_level < ZOOM_MIN) {
- this.zoom_level = ZOOM_MIN;
- } else if (this.zoom_level > ZOOM_MAX) {
- this.zoom_level = ZOOM_MAX;
- }
- this.scroll_event.connect(on_scroll_event);
-
- // Watch desktop font settings
- Settings system_settings = config.gnome_interface;
- system_settings.bind("document-font-name", this,
- "document-font", SettingsBindFlags.DEFAULT);
- system_settings.bind("monospace-font-name", this,
- "monospace-font", SettingsBindFlags.DEFAULT);
+ base_ref();
+ init(config);
}
~WebView() {
@@ -521,6 +500,50 @@ public abstract class Components.WebView : WebKit.WebView, Geary.BaseInterface {
}
}
+ private void init(Application.Configuration config) {
+ // XXX get the allow prefix from the extension somehow
+
+ this.decide_policy.connect(on_decide_policy);
+ this.web_process_terminated.connect((reason) => {
+ warning("Web process crashed: %s", reason.to_string());
+ });
+
+ register_message_handler(
+ COMMAND_STACK_CHANGED, on_command_stack_changed
+ );
+ register_message_handler(
+ CONTENT_LOADED, on_content_loaded
+ );
+ register_message_handler(
+ DOCUMENT_MODIFIED, on_document_modified
+ );
+ register_message_handler(
+ PREFERRED_HEIGHT_CHANGED, on_preferred_height_changed
+ );
+ register_message_handler(
+ REMOTE_IMAGE_LOAD_BLOCKED, on_remote_image_load_blocked
+ );
+ register_message_handler(
+ SELECTION_CHANGED, on_selection_changed
+ );
+
+ // Manage zoom level, ensure it's sane
+ config.bind(Application.Configuration.CONVERSATION_VIEWER_ZOOM_KEY, this, "zoom_level");
+ if (this.zoom_level < ZOOM_MIN) {
+ this.zoom_level = ZOOM_MIN;
+ } else if (this.zoom_level > ZOOM_MAX) {
+ this.zoom_level = ZOOM_MAX;
+ }
+ this.scroll_event.connect(on_scroll_event);
+
+ // Watch desktop font settings
+ Settings system_settings = config.gnome_interface;
+ system_settings.bind("document-font-name", this,
+ "document-font", SettingsBindFlags.DEFAULT);
+ system_settings.bind("monospace-font-name", this,
+ "monospace-font", SettingsBindFlags.DEFAULT);
+ }
+
private void handle_cid_request(WebKit.URISchemeRequest request) {
if (!handle_internal_response(request)) {
request.finish_error(new FileError.NOENT("Unknown CID"));
diff --git a/src/client/conversation-viewer/conversation-message.vala
b/src/client/conversation-viewer/conversation-message.vala
index f70c70c9..4e510ad8 100644
--- a/src/client/conversation-viewer/conversation-message.vala
+++ b/src/client/conversation-viewer/conversation-message.vala
@@ -510,7 +510,22 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
}
private void initialize_web_view() {
- this.web_view = new ConversationWebView(config);
+ var viewer = get_ancestor(typeof(ConversationViewer)) as ConversationViewer;
+
+ // Ensure we share the same WebProcess with the last one
+ // constructed if possible.
+ if (viewer != null && viewer.previous_web_view != null) {
+ this.web_view = new ConversationWebView.with_related_view(
+ this.config,
+ viewer.previous_web_view
+ );
+ } else {
+ this.web_view = new ConversationWebView(this.config);
+ }
+ if (viewer != null) {
+ viewer.previous_web_view = this.web_view;
+ }
+
this.web_view.context_menu.connect(on_context_menu);
this.web_view.deceptive_link_clicked.connect(on_deceptive_link_clicked);
this.web_view.link_activated.connect((link) => {
diff --git a/src/client/conversation-viewer/conversation-viewer.vala
b/src/client/conversation-viewer/conversation-viewer.vala
index 3d2a0226..8157e140 100644
--- a/src/client/conversation-viewer/conversation-viewer.vala
+++ b/src/client/conversation-viewer/conversation-viewer.vala
@@ -24,6 +24,14 @@ public class ConversationViewer : Gtk.Stack, Geary.BaseInterface {
get; private set; default = null;
}
+ /**
+ * The most recent web view created in this viewer.
+ *
+ * Keep the last created web view around so others can share the
+ * same WebKitGTK WebProcess.
+ */
+ internal ConversationWebView? previous_web_view { get; set; default = null; }
+
private Application.Configuration config;
private Gee.Set<Geary.App.Conversation>? selection_while_composing = null;
diff --git a/src/client/conversation-viewer/conversation-web-view.vala
b/src/client/conversation-viewer/conversation-web-view.vala
index 27a2cf34..a164c016 100644
--- a/src/client/conversation-viewer/conversation-web-view.vala
+++ b/src/client/conversation-viewer/conversation-web-view.vala
@@ -56,16 +56,33 @@ public class ConversationWebView : Components.WebView {
);
+ /**
+ * Constructs a new web view for displaying an email message body.
+ *
+ * A new WebKitGTK WebProcess will be constructed for this view.
+ */
public ConversationWebView(Application.Configuration config) {
base(config);
+ init();
+
+ // These only need to be added when creating a new WebProcess,
+ // not when sharing one
this.user_content_manager.add_script(ConversationWebView.app_script);
this.user_content_manager.add_style_sheet(ConversationWebView.app_stylesheet);
+ }
- register_message_handler(
- DECEPTIVE_LINK_CLICKED, on_deceptive_link_clicked
- );
-
- this.notify["preferred-height"].connect(() => queue_resize());
+ /**
+ * Constructs a new web view for displaying an email message body.
+ *
+ * The WebKitGTK WebProcess will be shared with the related view's
+ * process.
+ */
+ internal ConversationWebView.with_related_view(
+ Application.Configuration config,
+ ConversationWebView related
+ ) {
+ base.with_related_view(config, related);
+ init();
}
/**
@@ -195,6 +212,14 @@ public class ConversationWebView : Components.WebView {
minimum_height = natural_height = 0;
}
+ private void init() {
+ register_message_handler(
+ DECEPTIVE_LINK_CLICKED, on_deceptive_link_clicked
+ );
+
+ this.notify["preferred-height"].connect(() => queue_resize());
+ }
+
private void on_deceptive_link_clicked(WebKit.JavascriptResult result) {
try {
JSC.Value object = result.get_js_value();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]