Merge lp:~midori/midori/twoWebKittens into lp:midori

Proposed by Cris Dywan
Status: Merged
Approved by: Paweł Forysiuk
Approved revision: 6601
Merged at revision: 6629
Proposed branch: lp:~midori/midori/twoWebKittens
Merge into: lp:midori
Diff against target: 1007 lines (+373/-87)
16 files modified
CMakeLists.txt (+3/-0)
extensions/adblock/extension.vala (+40/-16)
extensions/adblock/subscriptions.vala (+5/-1)
extensions/notes.vala (+2/-0)
extensions/open-with.vala (+4/-9)
katze/midori-paths.vala (+22/-6)
katze/midori-uri.vala (+92/-0)
midori/midori-app.c (+1/-1)
midori/midori-browser.c (+39/-18)
midori/midori-historycompletion.vala (+2/-2)
midori/midori-searchcompletion.vala (+2/-2)
midori/midori-tab.vala (+37/-0)
midori/midori-view.c (+111/-32)
midori/midori-view.h (+5/-0)
midori/webkit2gtk-3.0.vapi (+7/-0)
midori/webkitgtk-3.0.vapi (+1/-0)
To merge this branch: bzr merge lp:~midori/midori/twoWebKittens
Reviewer Review Type Date Requested Status
Paweł Forysiuk Approve
gue5t gue5t Approve
Review via email: mp+208984@code.launchpad.net

Commit message

Make trunk build with WebKit2 again

Support editing actions with WebKit2
Set cache and cookies correctly in Midori.Paths
Disable WebExtension with WebKitGTK+ 2.3.91
Opt in to multiple rendering processes
Implement new windows opening with WebKit2
Make View Source work with WebKit2

To post a comment you must log in.
Revision history for this message
gue5t gue5t (gue5t) wrote :

View source doesn't seem to respect the editor set in preferences.

Multiple processes do spawn, but it doesn't seem they're ever cleaned up. Closing the last tab over and over seems to result in more and more processes sitting around.

I don't think these are regressions, though, and wk2 is still behind the half-broken-incomplete switch.

review: Approve
Revision history for this message
Cris Dywan (kalikiana) wrote :

There's a TODO for view source - it does something unlike before.

The processes are spawned by WebKitGTK+ I don't think we have any control over it - unless there's a bug more generally in our ref counting of tabs which would trigger this but in that case it would probably mean a memory leak in WebKit1 also.

lp:~midori/midori/twoWebKittens updated
6599. By Cris Dywan

Use HAVE_WEBKIT2_3_91 to guard WebKit.WebView.with_related_view

6600. By Cris Dywan

Move Copy and Select All menu items out of the selection clause

Revision history for this message
Paweł Forysiuk (tuxator) :
review: Approve
lp:~midori/midori/twoWebKittens updated
6601. By Cris Dywan

Merge lp:midori

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2014-03-04 14:41:28 +0000
3+++ CMakeLists.txt 2014-03-26 21:12:29 +0000
4@@ -216,6 +216,9 @@
5 set(EXTRA_VAPIS ${EXTRA_VAPIS} "${CMAKE_SOURCE_DIR}/midori/webkit2gtk-3.0.vapi")
6 set(VALAFLAGS ${VALAFLAGS} -D HAVE_GTK3)
7 set(VALAFLAGS ${VALAFLAGS} -D HAVE_WEBKIT2)
8+ if (${DEPS_GTK_webkit2gtk-3.0_VERSION} VERSION_GREATER "2.3.90")
9+ set(VALAFLAGS ${VALAFLAGS} -D HAVE_WEBKIT2_3_91)
10+ endif ()
11 elseif (USE_GTK3)
12 pkg_check_modules(DEPS_GTK REQUIRED
13 gtk+-3.0>=3.0.0
14
15=== modified file 'extensions/adblock/extension.vala'
16--- extensions/adblock/extension.vala 2014-03-18 16:57:25 +0000
17+++ extensions/adblock/extension.vala 2014-03-26 21:12:29 +0000
18@@ -56,7 +56,8 @@
19 #endif
20
21 #if HAVE_WEBKIT2
22- public Extension (WebKit.WebExtension web_extension) {
23+#if !HAVE_WEBKIT2_3_91
24+ public Extension.WebExtension (WebKit.WebExtension web_extension) {
25 init ();
26 web_extension.page_created.connect (page_created);
27 }
28@@ -68,7 +69,9 @@
29 bool send_request (WebKit.WebPage web_page, WebKit.URIRequest request, WebKit.URIResponse? redirected_response) {
30 return request_handled (request.uri, web_page.uri);
31 }
32-#else
33+#endif
34+#endif
35+
36 public Extension () {
37 GLib.Object (name: _("Advertisement blocker"),
38 description: _("Block advertisements according to a filter list"),
39@@ -84,6 +87,21 @@
40 }
41
42 void extension_activated (Midori.App app) {
43+#if HAVE_WEBKIT2
44+ string cache_dir = Environment.get_user_cache_dir ();
45+ string wk2path = Path.build_path (Path.DIR_SEPARATOR_S, cache_dir, "wk2ext");
46+ Midori.Paths.mkdir_with_parents (wk2path);
47+ string filename = "libadblock." + GLib.Module.SUFFIX;
48+ var wk2link = File.new_for_path (wk2path).get_child (filename);
49+ var library = File.new_for_path (Midori.Paths.get_lib_path (PACKAGE_NAME)).get_child (filename);
50+ try {
51+ wk2link.make_symbolic_link (library.get_path ());
52+ } catch (IOError.EXISTS exist_error) {
53+ /* It's no error if the file already exists. */
54+ } catch (Error error) {
55+ critical ("Failed to create WebKit2 link: %s", error.message);
56+ }
57+#endif
58 init ();
59 foreach (var browser in app.get_browsers ())
60 browser_added (browser);
61@@ -120,15 +138,19 @@
62 }
63
64 void tab_added (Midori.View view) {
65+ view.navigation_requested.connect (navigation_requested);
66+#if !HAVE_WEBKIT2
67 view.web_view.resource_request_starting.connect (resource_requested);
68- view.web_view.navigation_policy_decision_requested.connect (navigation_requested);
69+#endif
70 view.notify["load-status"].connect (load_status_changed);
71 view.context_menu.connect (context_menu);
72 }
73
74 void tab_removed (Midori.View view) {
75+#if !HAVE_WEBKIT2
76 view.web_view.resource_request_starting.disconnect (resource_requested);
77- view.web_view.navigation_policy_decision_requested.disconnect (navigation_requested);
78+#endif
79+ view.navigation_requested.disconnect (navigation_requested);
80 view.notify["load-status"].disconnect (load_status_changed);
81 view.context_menu.disconnect (context_menu);
82 }
83@@ -160,6 +182,7 @@
84 menu.add (action);
85 }
86
87+#if !HAVE_WEBKIT2
88 void resource_requested (WebKit.WebView web_view, WebKit.WebFrame frame,
89 WebKit.WebResource resource, WebKit.NetworkRequest request, WebKit.NetworkResponse? response) {
90
91@@ -167,13 +190,10 @@
92 request.set_uri ("about:blank");
93 }
94 }
95-
96- bool navigation_requested (WebKit.WebFrame frame, WebKit.NetworkRequest request,
97- WebKit.WebNavigationAction action, WebKit.WebPolicyDecision decision) {
98-
99- string uri = request.uri;
100+#endif
101+
102+ bool navigation_requested (Midori.Tab tab, string uri) {
103 if (uri.has_prefix ("abp:")) {
104- decision.ignore ();
105 string parsed_uri = parse_subscription_uri (uri);
106 manager.add_subscription (parsed_uri);
107 return true;
108@@ -318,7 +338,6 @@
109 if (style != null)
110 view.inject_stylesheet (style);
111 }
112-#endif
113
114 internal void init () {
115 hider_selectors = new StringBuilder ();
116@@ -351,7 +370,12 @@
117 }
118
119 void load_config () {
120+#if HAVE_WEBKIT2
121+ string config_dir = Path.build_filename (Environment.get_user_config_dir (), "midori", "extensions", "libadblock." + GLib.Module.SUFFIX);
122+ Midori.Paths.mkdir_with_parents (config_dir);
123+#else
124 string config_dir = Midori.Paths.get_extension_config_dir ("adblock");
125+#endif
126 string presets = Midori.Paths.get_extension_preset_filename ("adblock", "config");
127 string filename = Path.build_filename (config_dir, "config");
128 config = new Config (filename, presets);
129@@ -451,17 +475,18 @@
130 }
131
132 #if HAVE_WEBKIT2
133+#if !HAVE_WEBKIT2_3_91
134 Adblock.Extension? filter;
135 public static void webkit_web_extension_initialize (WebKit.WebExtension web_extension) {
136- filter = new Adblock.Extension (web_extension);
137+ filter = new Adblock.Extension.WebExtension (web_extension);
138 }
139-#else
140+#endif
141+#endif
142+
143 public Midori.Extension extension_init () {
144 return new Adblock.Extension ();
145 }
146-#endif
147
148-#if !HAVE_WEBKIT2
149 static string? tmp_folder = null;
150 string get_test_file (string contents) {
151 if (tmp_folder == null)
152@@ -833,5 +858,4 @@
153 Test.add_func ("/extensions/adblock2/update", test_subscription_update);
154 Test.add_func ("/extensions/adblock2/subsparse", test_subscription_uri_parsing);
155 }
156-#endif
157
158
159=== modified file 'extensions/adblock/subscriptions.vala'
160--- extensions/adblock/subscriptions.vala 2014-03-20 20:09:34 +0000
161+++ extensions/adblock/subscriptions.vala 2014-03-26 21:12:29 +0000
162@@ -40,7 +40,9 @@
163 public Options optslist;
164 public Whitelist whitelist;
165 public Element element;
166+#if !HAVE_WEBKIT2
167 WebKit.Download? download;
168+#endif
169
170 public Subscription (string uri) {
171 debug_parse = "adblock:parse" in (Environment.get_variable ("MIDORI_DEBUG") ?? "");
172@@ -289,6 +291,7 @@
173 }
174 }
175
176+#if !HAVE_WEBKIT2
177 void download_status (ParamSpec pspec) {
178 if (download.get_status () != WebKit.DownloadStatus.FINISHED)
179 return;
180@@ -300,6 +303,7 @@
181 warning ("Error parsing %s: %s", uri, error.message);
182 }
183 }
184+#endif
185
186 public void parse () throws Error
187 {
188@@ -340,8 +344,8 @@
189 download.destination_uri = destination_uri;
190 download.notify["status"].connect (download_status);
191 download.start ();
192+ }
193 #endif
194- }
195 return;
196 }
197
198
199=== modified file 'extensions/notes.vala'
200--- extensions/notes.vala 2014-03-20 21:42:55 +0000
201+++ extensions/notes.vala 2014-03-26 21:12:29 +0000
202@@ -390,8 +390,10 @@
203 }
204
205 void add_menu_items (Midori.Tab tab, WebKit.HitTestResult hit_test_result, Midori.ContextAction menu) {
206+#if !HAVE_WEBKIT2
207 if ((hit_test_result.context & WebKit.HitTestResultContext.SELECTION) == 0)
208 return;
209+#endif
210
211 var view = tab as Midori.View;
212 var action = new Gtk.Action ("Notes", _("Copy selection as note"), null, null);
213
214=== modified file 'extensions/open-with.vala'
215--- extensions/open-with.vala 2014-03-06 22:05:06 +0000
216+++ extensions/open-with.vala 2014-03-26 21:12:29 +0000
217@@ -615,17 +615,12 @@
218 return open_with_type (uri, get_content_type (uri, null), tab, NextStep.TRY_OPEN);
219 }
220
221- bool navigation_requested (WebKit.WebView web_view, WebKit.WebFrame frame, WebKit.NetworkRequest request,
222- WebKit.WebNavigationAction action, WebKit.WebPolicyDecision decision) {
223-
224- string uri = request.uri;
225+ bool navigation_requested (Midori.Tab tab, string uri) {
226 if (uri.has_prefix ("file://") || Midori.URI.is_http (uri) || Midori.URI.is_blank (uri))
227 return false;
228
229- decision.ignore ();
230-
231 string content_type = get_content_type (uri, null);
232- open_with_type (uri, content_type, web_view, NextStep.TRY_OPEN);
233+ open_with_type (uri, content_type, tab, NextStep.TRY_OPEN);
234 return true;
235 }
236
237@@ -769,13 +764,13 @@
238 }
239
240 public void tab_added (Midori.Browser browser, Midori.View view) {
241- view.web_view.navigation_policy_decision_requested.connect_after (navigation_requested);
242+ view.navigation_requested.connect_after (navigation_requested);
243 view.open_uri.connect (open_uri);
244 view.context_menu.connect (context_menu);
245 }
246
247 public void tab_removed (Midori.Browser browser, Midori.View view) {
248- view.web_view.navigation_policy_decision_requested.disconnect (navigation_requested);
249+ view.navigation_requested.disconnect (navigation_requested);
250 view.open_uri.disconnect (open_uri);
251 view.context_menu.disconnect (context_menu);
252 }
253
254=== modified file 'katze/midori-paths.vala'
255--- katze/midori-paths.vala 2014-03-25 00:00:40 +0000
256+++ katze/midori-paths.vala 2014-03-26 21:12:29 +0000
257@@ -133,6 +133,11 @@
258 tmp_dir = get_runtime_dir ();
259 }
260 else {
261+#if HAVE_WEBKIT2_3_91
262+ /* Allow WebKit to spawn more than one rendering process */
263+ if (!("wk2:no-multi-render-process" in (Environment.get_variable ("MIDORI_DEBUG") ?? "")))
264+ WebKit.WebContext.get_default ().set_process_model (WebKit.ProcessModel.MULTIPLE_SECONDARY_PROCESSES);
265+#endif
266 string? real_config = config != null && !Path.is_absolute (config)
267 ? Path.build_filename (Environment.get_current_dir (), config) : config;
268 config_dir = real_config ?? Path.build_path (Path.DIR_SEPARATOR_S,
269@@ -140,16 +145,23 @@
270 cache_dir = Path.build_path (Path.DIR_SEPARATOR_S,
271 Environment.get_user_cache_dir (), PACKAGE_NAME);
272 user_data_dir = Environment.get_user_data_dir ();
273+ tmp_dir = get_runtime_dir ();
274+ }
275 #if HAVE_WEBKIT2
276+ if (cache_dir != null) {
277+ /* Cache and extension dir MUST be set no later than here to work */
278+ WebKit.WebContext.get_default ().set_web_extensions_directory (
279+ Path.build_path (Path.DIR_SEPARATOR_S, cache_dir, "wk2ext"));
280 WebKit.WebContext.get_default ().set_disk_cache_directory (
281 Path.build_path (Path.DIR_SEPARATOR_S, cache_dir, "web"));
282+ }
283
284+ if (config_dir != null) {
285 var cookie_manager = WebKit.WebContext.get_default ().get_cookie_manager ();
286- cookie_manager.set_persistent_storage (Path.build_filename (config, "cookies.db"),
287+ cookie_manager.set_persistent_storage (Path.build_filename (config_dir, "cookies.db"),
288 WebKit.CookiePersistentStorage.SQLITE);
289+ }
290 #endif
291- tmp_dir = get_runtime_dir ();
292- }
293 if (user_data_dir != null) {
294 string folder = Path.build_filename (user_data_dir, "webkit", "icondatabase");
295 #if HAVE_WEBKIT2
296@@ -451,6 +463,12 @@
297 remove_path (Path.build_filename (user_data_dir, "webkit", "icondatabase"));
298 }
299
300+ /**
301+ * Looks up a pixbuf for the given @uri. If @widget is given a generic
302+ * file icon is used in case there's no icon.
303+ *
304+ * Deprecated: 0.5.8: Use Midori.URI.Icon or Midori.URI.get_icon instead.
305+ **/
306 public static Gdk.Pixbuf? get_icon (string? uri, Gtk.Widget? widget) {
307 if (!Midori.URI.is_resource (uri))
308 return null;
309@@ -461,9 +479,7 @@
310 else
311 icon_width = icon_height = 0 /* maximum size */;
312 #if HAVE_WEBKIT2
313- /* TODO async
314- var database = WebKit.WebContext.get_default ().get_favicon_database ();
315- database.get_favicon.begin (uri, null); */
316+ /* There is no sync API for WebKit2 */
317 #else
318 Gdk.Pixbuf? pixbuf = WebKit.get_favicon_database ()
319 .try_get_favicon_pixbuf (uri, icon_width, icon_height);
320
321=== modified file 'katze/midori-uri.vala'
322--- katze/midori-uri.vala 2014-02-22 23:19:22 +0000
323+++ katze/midori-uri.vala 2014-03-26 21:12:29 +0000
324@@ -222,5 +222,97 @@
325 fork_uri = uri;
326 return fork_uri != uri;
327 }
328+
329+ /**
330+ * Returns a Glib.Icon for the given @uri.
331+ *
332+ * Since: 0.5.8
333+ **/
334+ public static async GLib.Icon? get_icon (string uri, Cancellable? cancellable=null) throws Error {
335+#if HAVE_WEBKIT2
336+ var database = WebKit.WebContext.get_default ().get_favicon_database ();
337+ var surface = yield database.get_favicon (uri, cancellable);
338+ var image = (Cairo.ImageSurface)surface;
339+ var pixbuf = Gdk.pixbuf_get_from_surface (image, 0, 0, image.get_width (), image.get_height ());
340+#else
341+ var database = WebKit.get_favicon_database ();
342+ var pixbuf = yield database.get_favicon_pixbuf (uri, 0, 0, cancellable);
343+#endif
344+ return pixbuf as GLib.Icon;
345+ }
346+
347+ /**
348+ * Returns a Glib.Icon for the given @uri or falls back to @fallback.
349+ *
350+ * Since: 0.5.8
351+ **/
352+ public static async GLib.Icon? get_icon_fallback (string uri, GLib.Icon? fallback=null, Cancellable? cancellable=null) {
353+ try {
354+ return yield get_icon (uri, cancellable);
355+ } catch (Error error) {
356+ debug ("Icon failed to load: %s", error.message);
357+ return fallback;
358+ }
359+ }
360+
361+ /**
362+ * A Glib.Icon subclass that loads the icon for a given URI.
363+ * In the case of an error @fallback will be used.
364+ *
365+ * Since: 0.5.8
366+ **/
367+ public class Icon : InitiallyUnowned, GLib.Icon, LoadableIcon {
368+ public string uri { get; private set; }
369+ public GLib.Icon? fallback { get; private set; }
370+ InputStream? stream = null;
371+ public Icon (string website_uri, GLib.Icon? fallback=null) {
372+ uri = website_uri;
373+ /* TODO: Use fallback */
374+ this.fallback = fallback;
375+ }
376+ public bool equal (GLib.Icon? other) {
377+ return other is Icon && (other as Icon).uri == uri;
378+ }
379+ public uint hash () {
380+ return uri.hash ();
381+ }
382+ public InputStream load (int size, out string? type = null, Cancellable? cancellable = null) throws Error {
383+ /* Implementation notes:
384+ GTK+ up to GTK+ 3.10 loads any GLib.Icon synchronously
385+ Favicons may be cached but usually trigger loading here
386+ Only one async code path in favour of consistent results
387+ */
388+ if (stream != null) {
389+ type = "image/png";
390+ return stream;
391+ }
392+ load_async.begin (size, cancellable, (obj, res)=>{
393+ try {
394+ stream = load_async.end (res);
395+ }
396+ catch (Error error) {
397+ debug ("Icon failed to load: %s", error.message);
398+ }
399+ });
400+ throw new FileError.EXIST ("Triggered load - no data yet");
401+ }
402+
403+ public async InputStream load_async (int size, Cancellable? cancellable = null, out string? type = null) throws Error {
404+ type = "image/png";
405+ if (stream != null)
406+ return stream;
407+ var icon = yield get_icon (uri, cancellable);
408+ if (icon != null && icon is Gdk.Pixbuf) {
409+ var pixbuf = icon as Gdk.Pixbuf;
410+ // TODO: scale it to "size" here
411+ uint8[] buffer;
412+ pixbuf.save_to_buffer (out buffer, "png");
413+ stream = new MemoryInputStream.from_data (buffer, null);
414+ }
415+ else
416+ throw new FileError.EXIST ("No icon available");
417+ return stream;
418+ }
419+ }
420 }
421 }
422
423=== modified file 'midori/midori-app.c'
424--- midori/midori-app.c 2014-03-20 20:30:46 +0000
425+++ midori/midori-app.c 2014-03-26 21:12:29 +0000
426@@ -1254,7 +1254,7 @@
427 midori_debug (const gchar* token)
428 {
429 static const gchar* debug_token = NULL;
430- const gchar* debug_tokens = "adblock:match adblock:parse adblock:time adblock:element adblock:css startup headers body referer cookies paths hsts unarmed db:bookmarks db:history db:tabby mouse app database ";
431+ const gchar* debug_tokens = "wk2:no-multi-render-process adblock:match adblock:parse adblock:time adblock:element adblock:css startup headers body referer cookies paths hsts unarmed db:bookmarks db:history db:tabby mouse app database ";
432 if (debug_token == NULL)
433 {
434 gchar* found_token;
435
436=== modified file 'midori/midori-browser.c'
437--- midori/midori-browser.c 2014-03-25 01:00:38 +0000
438+++ midori/midori-browser.c 2014-03-26 21:12:29 +0000
439@@ -2785,15 +2785,8 @@
440
441 if (WEBKIT_IS_WEB_VIEW (widget))
442 {
443-#ifndef HAVE_WEBKIT2
444- WebKitWebView* view = WEBKIT_WEB_VIEW (widget);
445- can_undo = webkit_web_view_can_undo (view);
446- can_redo = webkit_web_view_can_redo (view);
447- can_cut = webkit_web_view_can_cut_clipboard (view);
448- can_copy = webkit_web_view_can_copy_clipboard (view);
449- can_paste = webkit_web_view_can_paste_clipboard (view);
450- can_select_all = TRUE;
451-#endif
452+ midori_tab_update_actions (MIDORI_TAB (widget), browser->action_group, NULL, NULL);
453+ return;
454 }
455 else if (GTK_IS_EDITABLE (widget))
456 {
457@@ -2828,9 +2821,11 @@
458 _action_undo_activate (GtkAction* action,
459 MidoriBrowser* browser)
460 {
461-#ifndef HAVE_WEBKIT2
462 GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
463 if (WEBKIT_IS_WEB_VIEW (widget))
464+#ifdef HAVE_WEBKIT2
465+ webkit_web_view_execute_editing_command (WEBKIT_WEB_VIEW (widget), WEBKIT_EDITING_COMMAND_UNDO);
466+#else
467 webkit_web_view_undo (WEBKIT_WEB_VIEW (widget));
468 #endif
469 }
470@@ -2839,9 +2834,11 @@
471 _action_redo_activate (GtkAction* action,
472 MidoriBrowser* browser)
473 {
474-#ifndef HAVE_WEBKIT2
475 GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
476 if (WEBKIT_IS_WEB_VIEW (widget))
477+#ifdef HAVE_WEBKIT2
478+ webkit_web_view_execute_editing_command (WEBKIT_WEB_VIEW (widget), WEBKIT_EDITING_COMMAND_REDO);
479+#else
480 webkit_web_view_redo (WEBKIT_WEB_VIEW (widget));
481 #endif
482 }
483@@ -2853,6 +2850,10 @@
484 GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
485 if (G_LIKELY (widget) && g_signal_lookup ("cut-clipboard", G_OBJECT_TYPE (widget)))
486 g_signal_emit_by_name (widget, "cut-clipboard");
487+#ifdef HAVE_WEBKIT2
488+ else if (WEBKIT_IS_WEB_VIEW (widget))
489+ webkit_web_view_execute_editing_command (WEBKIT_WEB_VIEW (widget), WEBKIT_EDITING_COMMAND_CUT);
490+#endif
491 }
492
493 static void
494@@ -2862,6 +2863,10 @@
495 GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
496 if (G_LIKELY (widget) && g_signal_lookup ("copy-clipboard", G_OBJECT_TYPE (widget)))
497 g_signal_emit_by_name (widget, "copy-clipboard");
498+#ifdef HAVE_WEBKIT2
499+ else if (WEBKIT_IS_WEB_VIEW (widget))
500+ webkit_web_view_execute_editing_command (WEBKIT_WEB_VIEW (widget), WEBKIT_EDITING_COMMAND_COPY);
501+#endif
502 }
503
504 static void
505@@ -2871,25 +2876,29 @@
506 GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
507 if (G_LIKELY (widget) && g_signal_lookup ("paste-clipboard", G_OBJECT_TYPE (widget)))
508 g_signal_emit_by_name (widget, "paste-clipboard");
509+#ifdef HAVE_WEBKIT2
510+ else if (WEBKIT_IS_WEB_VIEW (widget))
511+ webkit_web_view_execute_editing_command (WEBKIT_WEB_VIEW (widget), WEBKIT_EDITING_COMMAND_PASTE);
512+#endif
513 }
514
515 static void
516 _action_delete_activate (GtkAction* action,
517 MidoriBrowser* browser)
518 {
519-#ifndef HAVE_WEBKIT2
520 GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
521 if (G_LIKELY (widget))
522 {
523- if (WEBKIT_IS_WEB_VIEW (widget))
524+ if (GTK_IS_EDITABLE (widget))
525+ gtk_editable_delete_selection (GTK_EDITABLE (widget));
526+#ifndef HAVE_WEBKIT2
527+ else if (WEBKIT_IS_WEB_VIEW (widget))
528 webkit_web_view_delete_selection (WEBKIT_WEB_VIEW (widget));
529- else if (GTK_IS_EDITABLE (widget))
530- gtk_editable_delete_selection (GTK_EDITABLE (widget));
531+#endif
532 else if (GTK_IS_TEXT_VIEW (widget))
533 gtk_text_buffer_delete_selection (
534 gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget)), TRUE, FALSE);
535 }
536-#endif
537 }
538
539 static void
540@@ -2901,6 +2910,10 @@
541 {
542 if (GTK_IS_EDITABLE (widget))
543 gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
544+#ifdef HAVE_WEBKIT2
545+ else if (WEBKIT_IS_WEB_VIEW (widget))
546+ webkit_web_view_execute_editing_command (WEBKIT_WEB_VIEW (widget), WEBKIT_EDITING_COMMAND_SELECT_ALL);
547+#endif
548 else if (g_signal_lookup ("select-all", G_OBJECT_TYPE (widget)))
549 {
550 if (GTK_IS_TEXT_VIEW (widget))
551@@ -3484,11 +3497,18 @@
552 MidoriBrowser* browser,
553 gboolean use_dom)
554 {
555- GtkWidget* view;
556+ GtkWidget* view = midori_browser_get_current_tab (browser);
557+ #ifdef HAVE_WEBKIT2
558+ /* TODO: midori_view_save_source isn't async and not WebKit2-friendly */
559+ GtkWidget* source = midori_view_new_with_item (NULL, browser->settings);
560+ GtkWidget* source_view = midori_view_get_web_view (MIDORI_VIEW (source));
561+ midori_tab_set_view_source (MIDORI_TAB (source), TRUE);
562+ webkit_web_view_load_uri (WEBKIT_WEB_VIEW (source_view), midori_tab_get_uri (MIDORI_TAB (view)));
563+ midori_browser_add_tab (browser, source);
564+ #else
565 gchar* text_editor;
566 gchar* filename = NULL;
567
568- view = midori_browser_get_current_tab (browser);
569 filename = midori_view_save_source (MIDORI_VIEW (view), NULL, NULL, use_dom);
570 g_object_get (browser->settings, "text-editor", &text_editor, NULL);
571 if (!(text_editor && *text_editor))
572@@ -3512,6 +3532,7 @@
573 g_free (filename);
574 }
575 g_free (text_editor);
576+ #endif
577 }
578
579 static void
580
581=== modified file 'midori/midori-historycompletion.vala'
582--- midori/midori-historycompletion.vala 2014-02-11 23:01:05 +0000
583+++ midori/midori-historycompletion.vala 2014-03-26 21:12:29 +0000
584@@ -46,12 +46,12 @@
585 if (item is Midori.HistoryWebsite) {
586 var website = item as Midori.HistoryWebsite;
587 suggestions.append (new Suggestion (website.uri, website.title,
588- false, null, Midori.Paths.get_icon (website.uri, null)));
589+ false, null, yield Midori.URI.get_icon_fallback (website.uri, null, cancellable), this.position));
590 }
591 else if (item is Midori.HistorySearch) {
592 var search = item as Midori.HistorySearch;
593 suggestions.append (new Suggestion (search.uri, search.title + "\n" + search.uri,
594- false, "gray", Midori.Paths.get_icon (search.uri, null), this.position));
595+ false, "gray", yield Midori.URI.get_icon_fallback (search.uri, null, cancellable), this.position));
596 }
597 else
598 warn_if_reached ();
599
600=== modified file 'midori/midori-searchcompletion.vala'
601--- midori/midori-searchcompletion.vala 2014-02-11 23:01:05 +0000
602+++ midori/midori-searchcompletion.vala 2014-03-26 21:12:29 +0000
603@@ -45,11 +45,11 @@
604 item.get ("text", out desc);
605 string search_uri = URI.for_search (uri, text);
606 string search_title = _("Search with %s").printf (title);
607- Gdk.Pixbuf? pixbuf = Midori.Paths.get_icon (uri, null);
608+ Icon? icon = yield Midori.URI.get_icon_fallback (uri, null, cancellable);
609 string search_desc = search_title + "\n" + desc ?? uri;
610 /* FIXME: Theming? Win32? */
611 string background = "gray";
612- var suggestion = new Suggestion (search_uri, search_desc, false, background, pixbuf);
613+ var suggestion = new Suggestion (search_uri, search_desc, false, background, icon);
614 suggestions.append (suggestion);
615
616 n++;
617
618=== modified file 'midori/midori-tab.vala'
619--- midori/midori-tab.vala 2014-03-18 16:56:38 +0000
620+++ midori/midori-tab.vala 2014-03-26 21:12:29 +0000
621@@ -34,6 +34,7 @@
622 }
623
624 public class Tab : Gtk.VBox {
625+ public Tab related { get; set construct; }
626 public WebKit.WebView web_view { get; private set; }
627
628 private string current_uri = "about:blank";
629@@ -94,6 +95,8 @@
630 Since: 0.5.8
631 */
632 public signal bool open_uri (string uri);
633+ /* Since: 0.5.8 */
634+ public signal bool navigation_requested (string uri);
635 public signal void console_message (string message, int line, string source_id);
636 public signal void attach_inspector (WebKit.WebView inspector_view);
637 /* Emitted when an open inspector that was previously
638@@ -120,7 +123,12 @@
639 orientation = Gtk.Orientation.VERTICAL;
640 #endif
641
642+#if HAVE_WEBKIT2_3_91
643+ web_view = related != null ?
644+ new WebKit.WebView.with_related_view (related.web_view) : new WebKit.WebView ();
645+#else
646 web_view = new WebKit.WebView ();
647+#endif
648 /* Load something to avoid a bug where WebKit might not set a main frame */
649 web_view.load_uri ("");
650 }
651@@ -260,5 +268,34 @@
652 return found;
653 #endif
654 }
655+
656+ /*
657+ Updates all editing actions with regard to text selection.
658+
659+ Since: 0.5.8
660+ */
661+ public async void update_actions (Gtk.ActionGroup actions) {
662+#if HAVE_WEBKIT2
663+ try {
664+ actions.get_action ("Undo").sensitive = yield web_view.can_execute_editing_command ("Undo", null);
665+ actions.get_action ("Redo").sensitive = yield web_view.can_execute_editing_command ("Redo", null);
666+ actions.get_action ("Cut").sensitive = yield web_view.can_execute_editing_command ("Cut", null);
667+ actions.get_action ("Copy").sensitive = yield web_view.can_execute_editing_command ("Copy", null);
668+ actions.get_action ("Paste").sensitive = yield web_view.can_execute_editing_command ("Paste", null);
669+ actions.get_action ("Delete").sensitive = yield web_view.can_execute_editing_command ("Cut", null);
670+ actions.get_action ("SelectAll").sensitive = yield web_view.can_execute_editing_command ("SelectAll", null);
671+ } catch (Error error) {
672+ critical ("Failed to update actions: %s", error.message);
673+ }
674+#else
675+ actions.get_action ("Undo").sensitive = web_view.can_undo ();
676+ actions.get_action ("Redo").sensitive = web_view.can_redo ();
677+ actions.get_action ("Cut").sensitive = web_view.can_cut_clipboard ();
678+ actions.get_action ("Copy").sensitive = web_view.can_copy_clipboard ();
679+ actions.get_action ("Paste").sensitive = web_view.can_paste_clipboard ();
680+ actions.get_action ("Delete").sensitive = true;
681+ actions.get_action ("SelectAll").sensitive = true;
682+#endif
683+ }
684 }
685 }
686
687=== modified file 'midori/midori-view.c'
688--- midori/midori-view.c 2014-03-18 18:45:32 +0000
689+++ midori/midori-view.c 2014-03-26 21:12:29 +0000
690@@ -544,10 +544,24 @@
691 webkit_policy_decision_download (decision);
692 return TRUE;
693 }
694+ webkit_policy_decision_use (decision);
695+ return TRUE;
696+ }
697+ else if (decision_type == WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION)
698+ {
699+ }
700+ else if (decision_type == WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION)
701+ {
702+ }
703+ else
704+ {
705+ g_debug ("Unhandled policy decision type %d", decision_type);
706+ return FALSE;
707 }
708
709 void* request = NULL;
710- const gchar* uri = webkit_web_view_get_uri (web_view);
711+ const gchar* uri = webkit_uri_request_get_uri (
712+ webkit_navigation_policy_decision_get_request (WEBKIT_NAVIGATION_POLICY_DECISION (decision)));
713 #else
714 const gchar* uri = webkit_network_request_get_uri (request);
715 #endif
716@@ -648,6 +662,19 @@
717 g_free (result);
718 view->find_links = -1;
719 #endif
720+
721+ gboolean handled = FALSE;
722+ g_signal_emit_by_name (view, "navigation-requested", uri, &handled);
723+ if (handled)
724+ {
725+ #ifdef HAVE_WEBKIT2
726+ webkit_policy_decision_ignore (decision);
727+ #else
728+ webkit_web_policy_decision_ignore (decision);
729+ #endif
730+ return TRUE;
731+ }
732+
733 return FALSE;
734 }
735
736@@ -2246,21 +2273,7 @@
737 if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE)
738 {
739 /* Enforce update of actions - there's no "selection-changed" signal */
740- #ifndef HAVE_WEBKIT2
741- gtk_action_set_sensitive (gtk_action_group_get_action (actions, "Undo"),
742- webkit_web_view_can_undo (WEBKIT_WEB_VIEW (view->web_view)));
743- gtk_action_set_sensitive (gtk_action_group_get_action (actions, "Redo"),
744- webkit_web_view_can_redo (WEBKIT_WEB_VIEW (view->web_view)));
745- gtk_action_set_sensitive (gtk_action_group_get_action (actions, "Cut"),
746- webkit_web_view_can_cut_clipboard (WEBKIT_WEB_VIEW (view->web_view)));
747- gtk_action_set_sensitive (gtk_action_group_get_action (actions, "Copy"),
748- webkit_web_view_can_copy_clipboard (WEBKIT_WEB_VIEW (view->web_view)));
749- gtk_action_set_sensitive (gtk_action_group_get_action (actions, "Paste"),
750- webkit_web_view_can_paste_clipboard (WEBKIT_WEB_VIEW (view->web_view)));
751- gtk_action_set_sensitive (gtk_action_group_get_action (actions, "Delete"),
752- webkit_web_view_can_cut_clipboard (WEBKIT_WEB_VIEW (view->web_view)));
753- gtk_action_set_sensitive (gtk_action_group_get_action (actions, "SelectAll"), TRUE);
754- #endif
755+ midori_tab_update_actions (MIDORI_TAB (view), actions, NULL, NULL);
756 midori_context_action_add_by_name (menu, "Undo");
757 midori_context_action_add_by_name (menu, "Redo");
758 midori_context_action_add (menu, NULL);
759@@ -2348,15 +2361,6 @@
760 if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK)
761 midori_context_action_add (menu, NULL);
762
763- /* No need to have Copy twice, which is already in the editable menu */
764- if (!(context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE))
765- {
766- /* Enforce update of copy action - there's no "selection-changed" signal */
767- midori_context_action_add_by_name (menu, "Copy");
768- gtk_action_set_sensitive (gtk_action_group_get_action (actions, "Copy"),
769- webkit_web_view_can_copy_clipboard (WEBKIT_WEB_VIEW (view->web_view)));
770- }
771-
772 /* Ensure view->selected_text */
773 midori_view_has_selection (view);
774 if (midori_uri_is_valid (view->selected_text))
775@@ -2422,16 +2426,28 @@
776 midori_context_action_add_by_name (menu, "Forward");
777 midori_context_action_add_by_name (menu, "Stop");
778 midori_context_action_add_by_name (menu, "Reload");
779+ }
780+
781+ /* No need to have Copy twice, which is already in the editable menu */
782+ if (!(context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE))
783+ {
784+ midori_context_action_add (menu, NULL);
785+ /* Enforce update of actions - there's no "selection-changed" signal */
786+ midori_tab_update_actions (MIDORI_TAB (view), actions, NULL, NULL);
787+ midori_context_action_add_by_name (menu, "Copy");
788+ midori_context_action_add_by_name (menu, "SelectAll");
789+ }
790+
791+ if (context == WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT)
792+ {
793 midori_context_action_add (menu, NULL);
794 midori_context_action_add_by_name (menu, "UndoTabClose");
795-
796 #ifndef HAVE_WEBKIT2
797 WebKitWebView* web_view = WEBKIT_WEB_VIEW (view->web_view);
798 if (webkit_web_view_get_focused_frame (web_view) != webkit_web_view_get_main_frame (web_view))
799 midori_context_action_add_simple (menu, "OpenFrameInNewTab", _("Open _Frame in New Tab"), NULL, NULL,
800 midori_web_view_open_frame_in_new_tab_cb, view);
801 #endif
802-
803 midori_context_action_add_simple (menu, "OpenInNewWindow", _("Open in New _Window"), NULL, STOCK_WINDOW_NEW,
804 midori_view_tab_label_menu_window_new_cb, view);
805 midori_context_action_add_by_name (menu, "ZoomIn");
806@@ -2534,7 +2550,6 @@
807 }
808 #endif
809
810-#ifndef HAVE_WEBKIT2
811 static gboolean
812 midori_view_web_view_close_cb (WebKitWebView* web_view,
813 GtkWidget* view)
814@@ -2550,7 +2565,11 @@
815 MidoriNewView where = MIDORI_NEW_VIEW_TAB;
816 GtkWidget* new_view = GTK_WIDGET (midori_view_get_for_widget (web_view));
817
818+#ifdef HAVE_WEBKIT2
819+ WebKitWindowProperties* features = webkit_web_view_get_window_properties (WEBKIT_WEB_VIEW (web_view));
820+#else
821 WebKitWebWindowFeatures* features = webkit_web_view_get_window_features (WEBKIT_WEB_VIEW (web_view));
822+#endif
823 gboolean locationbar_visible, menubar_visible, toolbar_visible;
824 gint width, height;
825 g_object_get (features,
826@@ -2586,8 +2605,13 @@
827 GtkWidget* toplevel = gtk_widget_get_toplevel (new_view);
828 if (width > 0 && height > 0)
829 gtk_widget_set_size_request (toplevel, width, height);
830+#ifdef HAVE_WEBKIT2
831+ g_signal_connect (web_view, "close",
832+ G_CALLBACK (midori_view_web_view_close_cb), new_view);
833+#else
834 g_signal_connect (web_view, "close-web-view",
835 G_CALLBACK (midori_view_web_view_close_cb), new_view);
836+#endif
837 }
838
839 return TRUE;
840@@ -2595,26 +2619,38 @@
841
842 static GtkWidget*
843 webkit_web_view_create_web_view_cb (GtkWidget* web_view,
844+#ifndef HAVE_WEBKIT2
845 WebKitWebFrame* web_frame,
846+#endif
847 MidoriView* view)
848 {
849 MidoriView* new_view;
850
851+#ifdef HAVE_WEBKIT2
852+ const gchar* uri = webkit_web_view_get_uri (WEBKIT_WEB_VIEW (web_view));
853+#else
854+ const gchar* uri = webkit_web_frame_get_uri (web_frame);
855+#endif
856 if (view->open_new_pages_in == MIDORI_NEW_PAGE_CURRENT)
857 new_view = view;
858 else
859 {
860 KatzeItem* item = katze_item_new ();
861- item->uri = g_strdup (webkit_web_frame_get_uri (web_frame));
862- new_view = (MidoriView*)midori_view_new_with_item (item, view->settings);
863+ item->uri = g_strdup (uri);
864+ new_view = (MidoriView*)midori_view_new_from_view (view, item, NULL);
865+#ifdef HAVE_WEBKIT2
866+ g_signal_connect (new_view->web_view, "ready-to-show",
867+ G_CALLBACK (webkit_web_view_web_view_ready_cb), view);
868+#else
869 g_signal_connect (new_view->web_view, "web-view-ready",
870 G_CALLBACK (webkit_web_view_web_view_ready_cb), view);
871+#endif
872 }
873- g_object_set_data_full (G_OBJECT (new_view), "opener-uri",
874- g_strdup (webkit_web_frame_get_uri (web_frame)), g_free);
875+ g_object_set_data_full (G_OBJECT (new_view), "opener-uri", g_strdup (uri), g_free);
876 return new_view->web_view;
877 }
878
879+#ifndef HAVE_WEBKIT2
880 static gboolean
881 webkit_web_view_mime_type_decision_cb (GtkWidget* web_view,
882 WebKitWebFrame* web_frame,
883@@ -3144,14 +3180,55 @@
884 * Return value: a new #MidoriView
885 *
886 * Since: 0.4.3
887+ * Deprecated: 0.5.8: Use midori_view_new_from_view instead.
888 **/
889 GtkWidget*
890 midori_view_new_with_item (KatzeItem* item,
891 MidoriWebSettings* settings)
892 {
893+ return midori_view_new_from_view (NULL, item, settings);
894+}
895+
896+/**
897+ * midori_view_new_with_item:
898+ * @view: a predating, related #MidoriView, or %NULL
899+ * @item: a #KatzeItem, or %NULL
900+ * @settings: a #MidoriWebSettings, or %NULL
901+ *
902+ * Creates a new view, visible by default.
903+ *
904+ * If a @view is specified the returned new view will share
905+ * its settings and if applicable re-use the rendering process.
906+ *
907+ * When @view should be passed:
908+ * The new one created is a new tab/ window for the old @view
909+ * A tab was duplicated
910+ *
911+ * When @view may be passed:
912+ * Old and new view belong to the same website or group
913+ *
914+ * Don't pass a @view if:
915+ * The new view is a completely new website
916+ *
917+ * The @item may contain title, URI and minimized status and will be copied.
918+ *
919+ * Usually @settings should be passed from an existing view or browser.
920+ *
921+ * Return value: a new #MidoriView
922+ *
923+ * Since: 0.5.8
924+ **/
925+GtkWidget*
926+midori_view_new_from_view (MidoriView* related,
927+ KatzeItem* item,
928+ MidoriWebSettings* settings)
929+{
930 MidoriView* view = g_object_new (MIDORI_TYPE_VIEW,
931+ "related", MIDORI_TAB (related),
932 "title", item ? katze_item_get_name (item) : NULL,
933 NULL);
934+ if (!settings && related)
935+ settings = related->settings;
936 if (settings)
937 _midori_view_set_settings (view, settings);
938 if (item)
939@@ -3427,6 +3504,8 @@
940 midori_view_web_view_permission_request_cb, view,
941 "signal::context-menu",
942 midori_view_web_view_context_menu_cb, view,
943+ "signal::create",
944+ webkit_web_view_create_web_view_cb, view,
945 #else
946 "signal::notify::load-status",
947 midori_view_web_view_notify_load_status_cb, view,
948
949=== modified file 'midori/midori-view.h'
950--- midori/midori-view.h 2014-03-16 12:11:56 +0000
951+++ midori/midori-view.h 2014-03-26 21:12:29 +0000
952@@ -64,6 +64,11 @@
953 midori_view_new_with_item (KatzeItem* item,
954 MidoriWebSettings* settings);
955
956+GtkWidget*
957+midori_view_new_from_view (MidoriView* view,
958+ KatzeItem* item,
959+ MidoriWebSettings* settings);
960+
961 void
962 midori_view_set_settings (MidoriView* view,
963 MidoriWebSettings* settings);
964
965=== modified file 'midori/webkit2gtk-3.0.vapi'
966--- midori/webkit2gtk-3.0.vapi 2013-08-02 17:20:37 +0000
967+++ midori/webkit2gtk-3.0.vapi 2014-03-26 21:12:29 +0000
968@@ -436,6 +436,7 @@
969 public unowned string[] get_spell_checking_languages ();
970 public void register_uri_scheme (string scheme, owned WebKit.URISchemeRequestCallback callback);
971 public void set_additional_plugins_directory (string directory);
972+ public void set_process_model (WebKit.ProcessModel process_model);
973 public void set_cache_model (WebKit.CacheModel cache_model);
974 public void set_spell_checking_enabled (bool enabled);
975 public void set_spell_checking_languages (string[] languages);
976@@ -486,6 +487,7 @@
977 public class WebView : WebKit.WebViewBase, Atk.Implementor, Gtk.Buildable {
978 [CCode (has_construct_function = false, type = "GtkWidget*")]
979 public WebView ();
980+ public WebView.with_related_view (WebKit.WebView related);
981 public async bool can_execute_editing_command (string command, GLib.Cancellable? cancellable) throws GLib.Error;
982 public bool can_go_back ();
983 public bool can_go_forward ();
984@@ -594,6 +596,11 @@
985 public abstract void allow ();
986 public abstract void deny ();
987 }
988+ [CCode (cheader_filename = "webkit2/webkit2.h", cprefix = "WEBKIT_PROCESS_MODEL_")]
989+ public enum ProcessModel {
990+ SHARED_SECONDARY_PROCESS,
991+ MULTIPLE_SECONDARY_PROCESSES
992+ }
993 [CCode (cheader_filename = "webkit2/webkit2.h", cprefix = "WEBKIT_CACHE_MODEL_")]
994 public enum CacheModel {
995 DOCUMENT_VIEWER,
996
997=== modified file 'midori/webkitgtk-3.0.vapi'
998--- midori/webkitgtk-3.0.vapi 2012-12-16 18:40:10 +0000
999+++ midori/webkitgtk-3.0.vapi 2014-03-26 21:12:29 +0000
1000@@ -6,6 +6,7 @@
1001 public class FaviconDatabase : GLib.Object {
1002 public signal void icon_loaded (string frame_uri);
1003 public Gdk.Pixbuf? try_get_favicon_pixbuf (string page_uri, uint width, uint height);
1004+ public async Gdk.Pixbuf? get_favicon_pixbuf (string page_uri, uint width, uint height, GLib.Cancellable cancellable) throws GLib.Error;
1005 public void set_path (string? path);
1006 public void clear ();
1007 }

Subscribers

People subscribed via source and target branches

to all changes: