~midori/midori/gtk3WebKit2only

5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
1
/*
6159.1.1 by Cody Garver
Update dates to 2013.
2
 Copyright (C) 2011-2013 Christian Dywan <christian@twotoats.de>
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
3
4
 This library is free software; you can redistribute it and/or
5
 modify it under the terms of the GNU Lesser General Public
6
 License as published by the Free Software Foundation; either
7
 version 2.1 of the License, or (at your option) any later version.
8
9
 See the file COPYING for the full license text.
10
*/
11
12
namespace Katze {
13
    extern static string mkdir_with_parents (string pathname, int mode);
14
}
15
16
namespace Sokoke {
17
    extern static string js_script_eval (void* ctx, string script, void* error);
18
}
19
20
namespace Midori {
5292 by Christian Dywan
Introduce SpeedDialError and test invalid save messages
21
    public errordomain SpeedDialError {
22
        INVALID_MESSAGE,
23
        NO_ACTION,
24
        NO_ID,
25
        NO_URL,
26
        NO_TITLE,
27
        NO_ID2,
28
        INVALID_ACTION,
29
    }
30
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
31
    public class SpeedDial : GLib.Object {
5233 by Christian Dywan
Pass around SpeedDial and move messages in there
32
        string filename;
33
        string? html = null;
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
34
        List<Spec> thumb_queue = null;
6448.1.11 by Christian Dywan
Move WebKit2 guards to resolve warnings
35
#if !HAVE_WEBKIT2
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
36
        WebKit.WebView thumb_view = null;
37
        Spec? spec = null;
6448.1.11 by Christian Dywan
Move WebKit2 guards to resolve warnings
38
#endif
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
39
5285 by Christian Dywan
Refresh open speed dials when it changes
40
        public GLib.KeyFile keyfile;
41
        public bool close_buttons_left { get; set; default = false; }
42
        public signal void refresh ();
43
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
44
        public class Spec {
45
            public string dial_id;
46
            public string uri;
47
            public Spec (string dial_id, string uri) {
48
                this.dial_id = dial_id;
49
                this.uri = uri;
50
            }
51
        }
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
52
5233 by Christian Dywan
Pass around SpeedDial and move messages in there
53
        public SpeedDial (string new_filename, string? fallback = null) {
54
            filename = new_filename;
6228.2.1 by Christian Dywan
Improve scaled background thumbnailing and use it always
55
            thumb_queue = new GLib.List<Spec> ();
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
56
            keyfile = new GLib.KeyFile ();
57
            try {
58
                keyfile.load_from_file (filename, GLib.KeyFileFlags.NONE);
59
            }
60
            catch (GLib.Error io_error) {
61
                string json;
62
                size_t len;
63
                try {
64
                    FileUtils.get_contents (fallback ?? (filename + ".json"),
65
                                            out json, out len);
66
                }
67
                catch (GLib.Error fallback_error) {
68
                    json = "'{}'";
69
                    len = 4;
70
                }
71
72
                var script = new StringBuilder.sized (len);
73
                script.append ("var json = JSON.parse (");
74
                script.append_len (json, (ssize_t)len);
75
                script.append ("""
76
        );
77
        var keyfile = '';
78
        for (var i in json['shortcuts']) {
79
        var tile = json['shortcuts'][i];
80
        keyfile += '[Dial ' + tile['id'].substring (1) + ']\n'
81
                +  'uri=' + tile['href'] + '\n'
82
                +  'img=' + tile['img'] + '\n'
83
                +  'title=' + tile['title'] + '\n\n';
84
        }
85
        var columns = json['width'] ? json['width'] : 3;
86
        var rows = json['shortcuts'] ? json['shortcuts'].length / columns : 0;
87
        keyfile += '[settings]\n'
88
                +  'columns=' + columns + '\n'
89
                +  'rows=' + (rows > 3 ? rows : 3) + '\n\n';
90
        keyfile;
91
                    """);
92
93
                try {
94
                    keyfile.load_from_data (
95
                        Sokoke.js_script_eval (null, script.str, null),
96
                        -1, 0);
97
                }
98
                catch (GLib.Error eval_error) {
99
                    GLib.critical ("Failed to parse %s as speed dial JSON: %s",
100
                                   fallback ?? (filename + ".json"), eval_error.message);
101
                }
102
                Katze.mkdir_with_parents (
103
                    Path.build_path (Path.DIR_SEPARATOR_S,
104
                                     Environment.get_user_cache_dir (),
6048 by Christian Dywan
Consistently use PACKAGE_NAME instead of literal binary name
105
                                     PACKAGE_NAME, "thumbnails"), 0700);
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
106
107
                foreach (string tile in keyfile.get_groups ()) {
108
                    try {
109
                        string img = keyfile.get_string (tile, "img");
5283 by Christian Dywan
Fix build of unit tests: speed dial, hsts, bookmarks
110
                        keyfile.remove_key (tile, "img");
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
111
                        string uri = keyfile.get_string (tile, "uri");
112
                        if (img != null && uri[0] != '\0' && uri[0] != '#') {
113
                            uchar[] decoded = Base64.decode (img);
5277 by Christian Dywan
Merge build_thumbnail_path into Midori.SpeedDial
114
                            FileUtils.set_data (build_thumbnail_path (uri), decoded);
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
115
                        }
116
                    }
117
                    catch (GLib.Error img_error) {
118
                        /* img and uri can be missing */
119
                    }
120
                }
121
            }
122
        }
123
5292 by Christian Dywan
Introduce SpeedDialError and test invalid save messages
124
        public string get_next_free_slot (out uint count = null) {
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
125
            uint slot_count = 0;
126
            foreach (string tile in keyfile.get_groups ()) {
127
                try {
128
                    if (keyfile.has_key (tile, "uri"))
129
                        slot_count++;
130
                }
131
                catch (KeyFileError error) { }
132
            }
6448.1.8 by Christian Dywan
Resolve remaining warnings for possibly undefined out arguments
133
            count = slot_count;
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
134
135
            uint slot = 1;
136
            while (slot <= slot_count) {
137
                string tile = "Dial %u".printf (slot);
138
                if (!keyfile.has_group (tile))
5292 by Christian Dywan
Introduce SpeedDialError and test invalid save messages
139
                    return tile;
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
140
                slot++;
141
            }
5292 by Christian Dywan
Introduce SpeedDialError and test invalid save messages
142
5270 by Paweł Forysiuk
Fix slot and dial name mixups when preparing/ saving
143
            return "Dial %u".printf (slot_count + 1);
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
144
        }
145
6228.2.1 by Christian Dywan
Improve scaled background thumbnailing and use it always
146
        public void add (string uri, string title, Gdk.Pixbuf? img) {
5270 by Paweł Forysiuk
Fix slot and dial name mixups when preparing/ saving
147
            string id = get_next_free_slot ();
6228.2.1 by Christian Dywan
Improve scaled background thumbnailing and use it always
148
            uint slot = id.substring (5, -1).to_int ();
149
            try {
150
                save_message ("speed_dial-save-add %u %s".printf (slot, uri));
151
            }
152
            catch (Error error) {
153
                critical ("Failed to add speed dial thumbnail: %s", error.message);
154
            }
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
155
        }
156
6228.2.1 by Christian Dywan
Improve scaled background thumbnailing and use it always
157
        public void add_with_id (string id, string uri, string title, Gdk.Pixbuf? img) {
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
158
            keyfile.set_string (id, "uri", uri);
159
            keyfile.set_string (id, "title", title);
160
161
            Katze.mkdir_with_parents (Path.build_path (Path.DIR_SEPARATOR_S,
162
                Paths.get_cache_dir (), "thumbnails"), 0700);
5277 by Christian Dywan
Merge build_thumbnail_path into Midori.SpeedDial
163
            string filename = build_thumbnail_path (uri);
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
164
            try {
165
                img.save (filename, "png", null, "compression", "7", null);
166
            }
167
            catch (Error error) {
168
                critical ("Failed to save speed dial thumbnail: %s", error.message);
169
            }
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
170
            save ();
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
171
        }
172
5277 by Christian Dywan
Merge build_thumbnail_path into Midori.SpeedDial
173
        string build_thumbnail_path (string filename) {
174
            string thumbnail = Checksum.compute_for_string (ChecksumType.MD5, filename) + ".png";
175
            return Path.build_filename (Paths.get_cache_dir (), "thumbnails", thumbnail);
176
        }
177
5285 by Christian Dywan
Refresh open speed dials when it changes
178
        public unowned string get_html () throws Error {
5233 by Christian Dywan
Pass around SpeedDial and move messages in there
179
            bool load_missing = true;
180
181
            if (html != null)
182
                return html;
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
183
184
            string? head = null;
185
            string filename = Paths.get_res_filename ("speeddial-head.html");
186
            if (keyfile != null
187
             && FileUtils.get_contents (filename, out head, null)) {
188
                string header = head.replace ("{title}", _("Speed Dial")).
189
                    replace ("{click_to_add}", _("Click to add a shortcut")).
190
                    replace ("{enter_shortcut_address}", _("Enter shortcut address")).
191
                    replace ("{are_you_sure}", _("Are you sure you want to delete this shortcut?"));
192
                var markup = new StringBuilder (header);
193
194
                uint slot_count = 1;
5292 by Christian Dywan
Introduce SpeedDialError and test invalid save messages
195
                string dial_id = get_next_free_slot (out slot_count);
196
                uint next_slot = dial_id.substring (5, -1).to_int ();
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
197
198
                /* Try to guess the best X by X grid size */
199
                uint grid_index = 3;
200
                while ((grid_index * grid_index) < slot_count)
201
                    grid_index++;
202
203
                /* Percent width size of one slot */
204
                uint slot_size = (100 / grid_index);
205
206
                /* No editing in private/ app mode or without scripts */
207
                markup.append_printf (
208
                    "%s<style>.cross { display:none }</style>%s" +
209
                    "<style> div.shortcut { height: %d%%; width: %d%%; }</style>\n",
210
                    Paths.is_readonly () ? "" : "<noscript>",
211
                    Paths.is_readonly () ? "" : "</noscript>",
212
                    slot_size + 1, slot_size - 4);
213
214
                /* Combined width of slots should always be less than 100%.
215
                 * Use half of the remaining percentage as a margin size */
216
                uint div_factor;
217
                if (slot_size * grid_index >= 100 && grid_index > 4)
218
                    div_factor = 8;
219
                else
220
                    div_factor = 2;
221
                uint margin = (100 - ((slot_size - 4) * grid_index)) / div_factor;
222
                if (margin > 9)
223
                    margin = margin % 10;
224
225
                markup.append_printf (
226
                    "<style> body { overflow:hidden } #content { margin-left: %u%%; }</style>", margin);
227
                if (close_buttons_left)
228
                    markup.append_printf (
229
                        "<style>.cross { left: -14px }</style>");
230
231
                foreach (string tile in keyfile.get_groups ()) {
232
                    try {
233
                        string uri = keyfile.get_string (tile, "uri");
234
                        if (uri != null && uri.str ("://") != null && tile.has_prefix ("Dial ")) {
235
                            string title = keyfile.get_string (tile, "title");
5277 by Christian Dywan
Merge build_thumbnail_path into Midori.SpeedDial
236
                            string thumb_filename = build_thumbnail_path (uri);
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
237
                            uint slot = tile.substring (5, -1).to_int ();
238
                            string encoded;
239
                            try {
240
                                uint8[] thumb;
241
                                FileUtils.get_data (thumb_filename, out thumb);
242
                                encoded = Base64.encode (thumb);
243
                            }
244
                            catch (FileError error) {
245
                                encoded = null;
246
                                if (load_missing)
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
247
                                    get_thumb (tile, uri);
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
248
                            }
249
                            markup.append_printf ("""
5290 by Paweł Forysiuk
Drop dialing from keyboard in speed dial for now
250
                                <div class="shortcut" id="%u"><div class="preview">
5305 by Paweł Forysiuk
Javascript clean-up in speed dial head
251
                                <a class="cross" href="#"></a>
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
252
                                <a href="%s"><img src="data:image/png;base64,%s" title='%s'></a>
6810.1.1 by Sam Hegarty
Make title for speed dial editable inline
253
                                </div><input type="text" class="title selectable" value="%s"></div>
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
254
                                """,
5305 by Paweł Forysiuk
Javascript clean-up in speed dial head
255
                                slot, uri, encoded ?? "", title, title ?? "");
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
256
                        }
257
                        else if (tile != "settings")
258
                            keyfile.remove_group (tile);
259
                    }
260
                    catch (KeyFileError error) { }
261
                }
262
263
                markup.append_printf ("""
5290 by Paweł Forysiuk
Drop dialing from keyboard in speed dial for now
264
                    <div class="shortcut" id="%u"><div class="preview new">
5305 by Paweł Forysiuk
Javascript clean-up in speed dial head
265
                    <a class="add" href="#"></a>
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
266
                    </div><div class="title">%s</div></div>
267
                    """,
5305 by Paweł Forysiuk
Javascript clean-up in speed dial head
268
                    next_slot,  _("Click to add a shortcut"));
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
269
                markup.append_printf ("</div>\n</body>\n</html>\n");
5233 by Christian Dywan
Pass around SpeedDial and move messages in there
270
                html = markup.str;
271
            }
272
            else
273
                html = "";
274
275
            return html;
276
        }
277
278
        public void save_message (string message) throws Error {
5292 by Christian Dywan
Introduce SpeedDialError and test invalid save messages
279
            if (!message.has_prefix ("speed_dial-save-"))
280
                throw new SpeedDialError.INVALID_MESSAGE ("Invalid message '%s'", message);
281
5233 by Christian Dywan
Pass around SpeedDial and move messages in there
282
            string msg = message.substring (16, -1);
5557 by Paweł Forysiuk
Fix renaming in speed dial with spaces in title
283
            string[] parts = msg.split (" ", 3);
5292 by Christian Dywan
Introduce SpeedDialError and test invalid save messages
284
            if (parts[0] == null)
285
                throw new SpeedDialError.NO_ACTION ("No action.");
5233 by Christian Dywan
Pass around SpeedDial and move messages in there
286
            string action = parts[0];
287
5292 by Christian Dywan
Introduce SpeedDialError and test invalid save messages
288
            if (parts[1] == null)
289
                throw new SpeedDialError.NO_ID ("No ID argument.");
290
            string dial_id = "Dial " + parts[1];
5233 by Christian Dywan
Pass around SpeedDial and move messages in there
291
292
                if (action == "delete") {
293
                    string uri = keyfile.get_string (dial_id, "uri");
5277 by Christian Dywan
Merge build_thumbnail_path into Midori.SpeedDial
294
                    string file_path = build_thumbnail_path (uri);
5233 by Christian Dywan
Pass around SpeedDial and move messages in there
295
                    keyfile.remove_group (dial_id);
296
                    FileUtils.unlink (file_path);
297
                }
298
                else if (action == "add") {
5292 by Christian Dywan
Introduce SpeedDialError and test invalid save messages
299
                    if (parts[2] == null)
300
                        throw new SpeedDialError.NO_URL ("No URL argument.");
5233 by Christian Dywan
Pass around SpeedDial and move messages in there
301
                    keyfile.set_string (dial_id, "uri", parts[2]);
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
302
                    get_thumb (dial_id, parts[2]);
5233 by Christian Dywan
Pass around SpeedDial and move messages in there
303
                }
304
                else if (action == "rename") {
5292 by Christian Dywan
Introduce SpeedDialError and test invalid save messages
305
                    if (parts[2] == null)
306
                        throw new SpeedDialError.NO_TITLE ("No title argument.");
307
                    string title = parts[2];
5233 by Christian Dywan
Pass around SpeedDial and move messages in there
308
                    keyfile.set_string (dial_id, "title", title);
309
                }
310
                else if (action == "swap") {
5292 by Christian Dywan
Introduce SpeedDialError and test invalid save messages
311
                    if (parts[2] == null)
312
                        throw new SpeedDialError.NO_ID2 ("No ID2 argument.");
313
                    string dial2_id = "Dial " + parts[2];
5233 by Christian Dywan
Pass around SpeedDial and move messages in there
314
315
                    string uri = keyfile.get_string (dial_id, "uri");
316
                    string title = keyfile.get_string (dial_id, "title");
317
                    string uri2 = keyfile.get_string (dial2_id, "uri");
318
                    string title2 = keyfile.get_string (dial2_id, "title");
319
320
                    keyfile.set_string (dial_id, "uri", uri2);
321
                    keyfile.set_string (dial2_id, "uri", uri);
322
                    keyfile.set_string (dial_id, "title", title2);
323
                    keyfile.set_string (dial2_id, "title", title);
324
                }
5292 by Christian Dywan
Introduce SpeedDialError and test invalid save messages
325
                else
326
                    throw new SpeedDialError.INVALID_ACTION ("Invalid action '%s'", action);
327
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
328
            save ();
5233 by Christian Dywan
Pass around SpeedDial and move messages in there
329
        }
330
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
331
        void save () {
5233 by Christian Dywan
Pass around SpeedDial and move messages in there
332
            html = null;
333
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
334
            try {
335
                FileUtils.set_contents (filename, keyfile.to_data ());
336
            }
337
            catch (Error error) {
338
                critical ("Failed to update speed dial: %s", error.message);
339
            }
5285 by Christian Dywan
Refresh open speed dials when it changes
340
            refresh ();
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
341
        }
342
6448.1.11 by Christian Dywan
Move WebKit2 guards to resolve warnings
343
#if !HAVE_WEBKIT2
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
344
        void load_status (GLib.Object thumb_view_, ParamSpec pspec) {
6228.2.1 by Christian Dywan
Improve scaled background thumbnailing and use it always
345
            if (thumb_view.load_status != WebKit.LoadStatus.FINISHED
346
             && thumb_view.load_status != WebKit.LoadStatus.FAILED)
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
347
                return;
6228.2.1 by Christian Dywan
Improve scaled background thumbnailing and use it always
348
            thumb_view.notify["load-status"].disconnect (load_status);
349
            /* Schedule an idle to give the offscreen time to draw */
350
            Idle.add (save_thumbnail);
6448.1.11 by Christian Dywan
Move WebKit2 guards to resolve warnings
351
        }
6228.2.1 by Christian Dywan
Improve scaled background thumbnailing and use it always
352
#endif
353
6448.1.11 by Christian Dywan
Move WebKit2 guards to resolve warnings
354
#if !HAVE_WEBKIT2
6228.2.1 by Christian Dywan
Improve scaled background thumbnailing and use it always
355
        bool save_thumbnail () {
356
            return_val_if_fail (spec != null, false);
357
358
            var offscreen = (thumb_view.parent as Gtk.OffscreenWindow);
359
            var pixbuf = offscreen.get_pixbuf ();
360
            int image_width = pixbuf.get_width (), image_height = pixbuf.get_height ();
361
            int thumb_width = 240, thumb_height = 160;
362
            float image_ratio = image_width / image_height;
363
            float thumb_ratio = thumb_width / thumb_height;
364
            int x_offset, y_offset, computed_width, computed_height;
365
            if (image_ratio > thumb_ratio) {
366
                computed_width = (int)(image_height * thumb_ratio);
367
                computed_height = image_height;
368
                x_offset = (image_width - computed_width) / 2;
369
                y_offset = 0;
370
            }
371
            else {
372
                computed_width = image_width;
373
                computed_height = (int)(image_width / thumb_ratio);
374
                x_offset = 0;
375
                y_offset = 0;
376
            }
377
            var sub = pixbuf;
378
            if (y_offset + computed_height <= image_height)
379
                sub = new Gdk.Pixbuf.subpixbuf (pixbuf, x_offset, y_offset, computed_width, computed_height);
380
            var scaled = sub.scale_simple (thumb_width, thumb_height, Gdk.InterpType.TILES);
381
            add_with_id (spec.dial_id, spec.uri, thumb_view.get_title () ?? spec.uri, scaled);
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
382
383
            thumb_queue.remove (spec);
6228.2.1 by Christian Dywan
Improve scaled background thumbnailing and use it always
384
            if (thumb_queue.length () > 0) {
385
                spec = thumb_queue.nth_data (0);
386
                thumb_view.notify["load-status"].connect (load_status);
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
387
                thumb_view.load_uri (spec.uri);
388
            }
6228.2.1 by Christian Dywan
Improve scaled background thumbnailing and use it always
389
            return false;
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
390
        }
6448.1.11 by Christian Dywan
Move WebKit2 guards to resolve warnings
391
#endif
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
392
393
        void get_thumb (string dial_id, string uri) {
5771 by André Stösel
Add some #ifdef to build Midori with WebKit2 support
394
#if !HAVE_WEBKIT2
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
395
            if (thumb_view == null) {
396
                thumb_view = new WebKit.WebView ();
6228.2.1 by Christian Dywan
Improve scaled background thumbnailing and use it always
397
                thumb_view.settings.set (
398
                    "enable-scripts", false,
399
                    "enable-plugins", false,
400
                    "auto-load-images", true,
401
                    "enable-html5-database", false,
402
                    "enable-html5-local-storage", false,
403
                    "enable-java-applet", false);
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
404
                var offscreen = new Gtk.OffscreenWindow ();
405
                offscreen.add (thumb_view);
406
                thumb_view.set_size_request (800, 600);
407
                offscreen.show_all ();
408
            }
409
6228.2.1 by Christian Dywan
Improve scaled background thumbnailing and use it always
410
            /* Don't load thumbnails already queued */
411
            foreach (var spec_ in thumb_queue)
412
                if (spec_.dial_id == dial_id)
413
                    return;
414
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
415
            thumb_queue.append (new Spec (dial_id, uri));
6228.2.1 by Christian Dywan
Improve scaled background thumbnailing and use it always
416
            if (thumb_queue.length () > 1)
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
417
                return;
418
6228.2.1 by Christian Dywan
Improve scaled background thumbnailing and use it always
419
            spec = thumb_queue.nth_data (0);
5255 by Christian Dywan
Move thumbnail generation into SpeedDial class
420
            thumb_view.notify["load-status"].connect (load_status);
421
            thumb_view.load_uri (spec.uri);
5771 by André Stösel
Add some #ifdef to build Midori with WebKit2 support
422
#endif
5231 by Christian Dywan
Introduce Midori.SpeedDial and unit test
423
        }
424
    }
425
}
426