Merge lp:~midori/midori/tabby into lp:midori

Proposed by André Stösel on 2013-08-04
Status: Merged
Approved by: Christian Dywan on 2013-09-07
Approved revision: 6334
Merged at revision: 6384
Proposed branch: lp:~midori/midori/tabby
Merge into: lp:midori
Diff against target: 794 lines (+452/-219)
9 files modified
data/tabby/Create.sql (+33/-0)
extensions/delayed-load.vala (+1/-35)
extensions/tabby.vala (+402/-0)
katze/midori-paths.vala (+1/-1)
midori/midori-extension.c (+5/-1)
midori/midori-frontend.c (+2/-1)
midori/midori-session.c (+5/-178)
midori/midori-session.h (+0/-3)
midori/midori.vapi (+3/-0)
To merge this branch: bzr merge lp:~midori/midori/tabby
Reviewer Review Type Date Requested Status
Paweł Forysiuk 2013-09-07 Approve on 2013-09-07
Christian Dywan 2013-08-04 Approve on 2013-09-07
Review via email: mp+178448@code.launchpad.net

Commit message

Introduce tabby, the new session manager

Future work items:
https://bugs.launchpad.net/midori/+bugs?field.tag=tabby

To post a comment you must log in.
André Stösel (ivaldi) wrote :

This is an early alpha and there are still some features missing and many bugs included.
Please open new bugs (tag "tabby") instead of adding comments.

Christian Dywan (kalikiana) wrote :

I made some improvements to error handling at startup and fixed it to work out of the build folder with cmake. I also resolved the "error" after first startup due to re-creating the tables.

Personally I learn towards merging now. I would look into re-factoring the database creation/ update/ import in a separate branch - I think we don't want to rush it, and it doesn't block tabby.

But I'd like a decision from Paweł before top-approving this. He expressed a strong wish to have the about: page on startup to restore other sessions asap.

review: Approve
Paweł Forysiuk (tuxator) wrote :

Ok lets get this in, should be no worse in any way than we have now even if some stuff is hidden.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'data/tabby'
2=== added file 'data/tabby/Create.sql'
3--- data/tabby/Create.sql 1970-01-01 00:00:00 +0000
4+++ data/tabby/Create.sql 2013-09-07 14:18:40 +0000
5@@ -0,0 +1,33 @@
6+CREATE TABLE IF NOT EXISTS sessions
7+(
8+ id INTEGER PRIMARY KEY,
9+ parent_id INTEGER DEFAULT 0,
10+ crdate INTEGER DEFAULT 0,
11+ tstamp INTEGER DEFAULT 0,
12+ closed INTEGER DEFAULT 0,
13+ title TEXT DEFAULT NULL,
14+ FOREIGN KEY(parent_id) REFERENCES sessions(id)
15+);
16+
17+CREATE TABLE IF NOT EXISTS tabs
18+(
19+ id INTEGER PRIMARY KEY,
20+ session_id INTEGER NOT NULL,
21+ uri TEXT DEFAULT NULL,
22+ icon TEXT DEFAULT NULL,
23+ title TEXT DEFAULT NULL,
24+ crdate INTEGER DEFAULT 0,
25+ tstamp INTEGER DEFAULT 0,
26+ closed INTEGER DEFAULT 0,
27+ FOREIGN KEY(session_id) REFERENCES sessions(id)
28+);
29+
30+CREATE TABLE IF NOT EXISTS tab_history
31+(
32+ id INTEGER PRIMARY KEY,
33+ tab_id INTEGER,
34+ url TEXT,
35+ icon TEXT,
36+ title TEXT,
37+ FOREIGN KEY(tab_id) REFERENCES tabs(id)
38+);
39
40=== modified file 'extensions/delayed-load.vala'
41--- extensions/delayed-load.vala 2013-04-25 22:09:04 +0000
42+++ extensions/delayed-load.vala 2013-09-07 14:18:40 +0000
43@@ -106,7 +106,6 @@
44
45 private class Manager : Midori.Extension {
46 private int timeout = 0;
47- private bool initialized = false;
48 private HashTable<Midori.Browser, TabShaker> tasks;
49
50 public signal void preferences_changed ();
51@@ -141,39 +140,12 @@
52 item.ref();
53
54 int64 delay = item.get_meta_integer ("delay");
55- if (delay == Midori.Delay.PENDING_UNDELAY && new_view.progress < 1.0 && this.initialized) {
56+ if (delay == Midori.Delay.PENDING_UNDELAY && new_view.progress < 1.0) {
57 this.schedule_reload (browser, new_view);
58 }
59 }
60 }
61
62- private bool reload_first_tab () {
63- Midori.App app = get_app ();
64- Midori.Browser? browser = app.browser;
65- Midori.View? view = browser.tab as Midori.View;
66-
67- if (view != null) {
68- this.initialized = true;
69- Katze.Item item = view.get_proxy_item ();
70- item.ref();
71-
72- int64 delay = item.get_meta_integer ("delay");
73- if (delay != Midori.Delay.DELAYED) {
74- if (view.load_status == Midori.LoadStatus.FINISHED) {
75- if (this.timeout != 0)
76- this.tasks.set (browser, new TabShaker (browser));
77-
78- if (view.progress < 1.0)
79- this.schedule_reload (browser, view);
80-
81- return false;
82- }
83- }
84- }
85-
86- return true;
87- }
88-
89 private void browser_added (Midori.Browser browser) {
90 browser.switch_tab.connect_after (this.tab_changed);
91 }
92@@ -188,12 +160,6 @@
93
94 this.preferences_changed ();
95
96- Midori.Browser? focused_browser = app.browser;
97- if (focused_browser == null)
98- Midori.Timeout.add (50, this.reload_first_tab);
99- else
100- this.initialized = true;
101-
102 foreach (Midori.Browser browser in app.get_browsers ()) {
103 browser_added (browser);
104 }
105
106=== added file 'extensions/tabby.vala'
107--- extensions/tabby.vala 1970-01-01 00:00:00 +0000
108+++ extensions/tabby.vala 2013-09-07 14:18:40 +0000
109@@ -0,0 +1,402 @@
110+/*
111+ Copyright (C) 2013 André Stösel <andre@stoesel.de>
112+
113+ This library is free software; you can redistribute it and/or
114+ modify it under the terms of the GNU Lesser General Public
115+ License as published by the Free Software Foundation; either
116+ version 2.1 of the License, or (at your option) any later version.
117+
118+ See the file COPYING for the full license text.
119+*/
120+
121+namespace Tabby {
122+ /* function called from Manager object */
123+ public interface IStorage : GLib.Object {
124+ public abstract Katze.Array get_sessions ();
125+ public abstract Base.Session get_new_session ();
126+ public abstract void restore_last_sessions ();
127+ public abstract void import_session (Katze.Array tabs);
128+ }
129+
130+ public interface ISession : GLib.Object {
131+ public abstract Katze.Array get_tabs ();
132+ public abstract void add_item (Katze.Item item);
133+ public abstract void attach (Midori.Browser browser);
134+ public abstract void restore (Midori.Browser browser);
135+ public abstract void close ();
136+ }
137+
138+ namespace Base {
139+ /* each base class should connect to all necessary signals and provide an abstract function to handle them */
140+
141+ public abstract class Storage : GLib.Object, IStorage {
142+ public Midori.App app { get; construct; }
143+
144+ public abstract Katze.Array get_sessions ();
145+ public abstract Base.Session get_new_session ();
146+ public void restore_last_sessions () {
147+ Katze.Array sessions = this.get_sessions ();
148+ if (sessions.is_empty ()) {
149+ sessions.add_item (this.get_new_session ());
150+ }
151+
152+ GLib.List<unowned Katze.Item> items = sessions.get_items ();
153+ foreach (Katze.Item item in items) {
154+ Session session = item as Session;
155+ Midori.Browser browser = this.app.create_browser ();
156+
157+ /* FixMe: tabby-session should be set in .restore and .attch */
158+ browser.set_data<Base.Session> ("tabby-session", session as Base.Session);
159+
160+ app.add_browser (browser);
161+ browser.show ();
162+
163+ session.restore (browser);
164+ }
165+ }
166+
167+ public void import_session (Katze.Array tabs) {
168+ Session session = this.get_new_session ();
169+ GLib.List<unowned Katze.Item> items = tabs.get_items ();
170+ foreach (Katze.Item item in items) {
171+ session.add_item (item);
172+ }
173+ }
174+ }
175+
176+ public abstract class Session : GLib.Object, ISession {
177+ public abstract void add_item (Katze.Item item);
178+ public abstract void uri_changed (Midori.View view, string uri);
179+ public abstract void tab_added (Midori.Browser browser, Midori.View view);
180+ public abstract void tab_removed (Midori.Browser browser, Midori.View view);
181+ public abstract void close ();
182+ public abstract Katze.Array get_tabs ();
183+
184+ public void attach (Midori.Browser browser) {
185+ browser.add_tab.connect (this.tab_added);
186+ browser.add_tab.connect (this.helper_uri_changed);
187+ browser.remove_tab.connect (this.tab_removed);
188+
189+ foreach (Midori.View view in browser.get_tabs ()) {
190+ this.tab_added (browser, view);
191+ this.helper_uri_changed (browser, view);
192+ }
193+ }
194+
195+ public void restore (Midori.Browser browser) {
196+ Katze.Array tabs = this.get_tabs ();
197+
198+ if(tabs.is_empty ()) {
199+ Katze.Item item = new Katze.Item ();
200+ item.uri = "about:home";
201+ tabs.add_item (item);
202+ }
203+
204+ browser.add_tab.connect (this.tab_added);
205+ browser.add_tab.connect (this.helper_uri_changed);
206+ browser.remove_tab.connect (this.tab_removed);
207+
208+ GLib.List<unowned Katze.Item> items = tabs.get_items ();
209+ unowned GLib.List<unowned Katze.Item> u_items = items;
210+
211+ bool delay = false;
212+
213+ GLib.Idle.add (() => {
214+ /* Note: we need to use `items` for something to maintain a valid reference */
215+ if (items.length () > 0) {
216+ for (int i = 0; i < 3; i++) {
217+ if (u_items == null)
218+ return false;
219+
220+ Katze.Item t_item = u_items.data<Katze.Item>;
221+
222+ if (delay)
223+ t_item.set_meta_integer ("delay", Midori.Delay.DELAYED);
224+ else
225+ delay = true;
226+
227+ browser.add_item (t_item);
228+
229+ u_items = u_items.next;
230+ }
231+ }
232+ return u_items != null;
233+ });
234+ }
235+
236+ private void helper_uri_changed (Midori.Browser browser, Midori.View view) {
237+ /* FixMe: skip first event while restoring the session */
238+ view.web_view.notify["uri"].connect ( () => {
239+ this.uri_changed (view, view.web_view.uri);
240+ });
241+ }
242+ }
243+ }
244+
245+ namespace Local {
246+ private class Session : Base.Session {
247+ public static int open_sessions = 0;
248+ public int64 id { get; private set; }
249+ private unowned Sqlite.Database db;
250+
251+ public override void add_item (Katze.Item item) {
252+ GLib.DateTime time = new DateTime.now_local ();
253+ string sqlcmd = "INSERT INTO `tabs` (`crdate`, `tstamp`, `session_id`, `uri`) VALUES (:tstamp, :tstamp, :session_id, :uri);";
254+ Sqlite.Statement stmt;
255+ if (this.db.prepare_v2 (sqlcmd, -1, out stmt, null) != Sqlite.OK)
256+ critical (_("Failed to update database: %s"), db.errmsg);
257+ stmt.bind_int64 (stmt.bind_parameter_index (":tstamp"), time.to_unix ());
258+ stmt.bind_int64 (stmt.bind_parameter_index (":session_id"), this.id);
259+ stmt.bind_text (stmt.bind_parameter_index (":uri"), item.uri);
260+ if (stmt.step () != Sqlite.DONE)
261+ critical (_("Failed to update database: %s"), db.errmsg);
262+ else {
263+ int64 tab_id = this.db.last_insert_rowid ();
264+ item.set_meta_integer ("tabby-id", tab_id);
265+ }
266+ }
267+
268+ protected override void uri_changed (Midori.View view, string uri) {
269+ unowned Katze.Item item = view.get_proxy_item ();
270+ int64 tab_id = item.get_meta_integer ("tabby-id");
271+ string sqlcmd = "UPDATE `tabs` SET uri = :uri, title = :title WHERE session_id = :session_id AND id = :tab_id;";
272+ Sqlite.Statement stmt;
273+ if (this.db.prepare_v2 (sqlcmd, -1, out stmt, null) != Sqlite.OK)
274+ critical (_("Failed to update database: %s"), db.errmsg ());
275+ stmt.bind_text (stmt.bind_parameter_index (":uri"), uri);
276+ stmt.bind_text (stmt.bind_parameter_index (":title"), view.get_display_title ());
277+ stmt.bind_int64 (stmt.bind_parameter_index (":session_id"), this.id);
278+ stmt.bind_int64 (stmt.bind_parameter_index (":tab_id"), tab_id);
279+ if (stmt.step () != Sqlite.DONE)
280+ critical (_("Failed to update database: %s"), db.errmsg ());
281+ }
282+
283+ protected override void tab_added (Midori.Browser browser, Midori.View view) {
284+ unowned Katze.Item item = view.get_proxy_item ();
285+ int64 tab_id = item.get_meta_integer ("tabby-id");
286+ if (tab_id < 1) {
287+ this.add_item (item);
288+ }
289+ }
290+
291+ protected override void tab_removed (Midori.Browser browser, Midori.View view) {
292+ unowned Katze.Item item = view.get_proxy_item ();
293+ int64 tab_id = item.get_meta_integer ("tabby-id");
294+ /* FixMe: mark as deleted */
295+ string sqlcmd = "DELETE FROM `tabs` WHERE session_id = :session_id AND id = :tab_id;";
296+ Sqlite.Statement stmt;
297+ if (this.db.prepare_v2 (sqlcmd, -1, out stmt, null) != Sqlite.OK)
298+ critical (_("Failed to update database: %s"), db.errmsg ());
299+ stmt.bind_int64 (stmt.bind_parameter_index (":session_id"), this.id);
300+ stmt.bind_int64 (stmt.bind_parameter_index (":tab_id"), tab_id);
301+ if (stmt.step () != Sqlite.DONE)
302+ critical (_("Failed to update database: %s"), db.errmsg ());
303+ }
304+
305+ public override void close() {
306+ if (Session.open_sessions == 1)
307+ return;
308+
309+ GLib.DateTime time = new DateTime.now_local ();
310+ string sqlcmd = "UPDATE `sessions` SET closed = 1, tstamp = :tstamp WHERE id = :session_id;";
311+ Sqlite.Statement stmt;
312+ if (this.db.prepare_v2 (sqlcmd, -1, out stmt, null) != Sqlite.OK)
313+ critical (_("Failed to update database: %s"), db.errmsg ());
314+
315+ stmt.bind_int64 (stmt.bind_parameter_index (":session_id"), this.id);
316+ stmt.bind_int64 (stmt.bind_parameter_index (":tstamp"), time.to_unix ());
317+ if (stmt.step () != Sqlite.DONE)
318+ critical (_("Failed to update database: %s"), db.errmsg ());
319+ }
320+
321+ public override Katze.Array get_tabs() {
322+ Katze.Array tabs = new Katze.Array (typeof (Katze.Item));
323+
324+ string sqlcmd = "SELECT id, uri, title FROM tabs WHERE session_id = :session_id";
325+ Sqlite.Statement stmt;
326+ if (this.db.prepare_v2 (sqlcmd, -1, out stmt, null) != Sqlite.OK)
327+ critical (_("Failed to select from database: %s"), db.errmsg ());
328+ stmt.bind_int64 (stmt.bind_parameter_index (":session_id"), this.id);
329+ int result = stmt.step ();
330+ if (!(result == Sqlite.DONE || result == Sqlite.ROW)) {
331+ critical (_("Failed to select from database: %s"), db.errmsg ());
332+ return tabs;
333+ }
334+
335+ while (result == Sqlite.ROW) {
336+ Katze.Item item = new Katze.Item ();
337+ int64 id = stmt.column_int64 (0);
338+ string uri = stmt.column_text (1);
339+ string title = stmt.column_text (2);
340+ item.uri = uri;
341+ item.name = title;
342+ item.set_meta_integer ("tabby-id", id);
343+ tabs.add_item (item);
344+ result = stmt.step ();
345+ }
346+
347+ return tabs;
348+ }
349+
350+ internal Session (Sqlite.Database db) {
351+ this.db = db;
352+
353+ GLib.DateTime time = new DateTime.now_local ();
354+
355+ string sqlcmd = "INSERT INTO `sessions` (`tstamp`) VALUES (:tstamp);";
356+ Sqlite.Statement stmt;
357+ if (this.db.prepare_v2 (sqlcmd, -1, out stmt, null) != Sqlite.OK)
358+ critical (_("Failed to update database: %s"), db.errmsg);
359+ stmt.bind_int64 (stmt.bind_parameter_index (":tstamp"), time.to_unix ());
360+ if (stmt.step () != Sqlite.DONE)
361+ critical (_("Failed to update database: %s"), db.errmsg);
362+ else
363+ this.id = this.db.last_insert_rowid ();
364+ }
365+
366+ internal Session.with_id (Sqlite.Database db, int64 id) {
367+ this.db = db;
368+ this.id = id;
369+
370+ GLib.DateTime time = new DateTime.now_local ();
371+ string sqlcmd = "UPDATE `sessions` SET closed = 0, tstamp = :tstamp WHERE id = :session_id;";
372+ Sqlite.Statement stmt;
373+ if (this.db.prepare_v2 (sqlcmd, -1, out stmt, null) != Sqlite.OK)
374+ critical (_("Failed to update database: %s"), db.errmsg);
375+
376+ stmt.bind_int64 (stmt.bind_parameter_index (":session_id"), this.id);
377+ stmt.bind_int64 (stmt.bind_parameter_index (":tstamp"), time.to_unix ());
378+ if (stmt.step () != Sqlite.DONE)
379+ critical (_("Failed to update database: %s"), db.errmsg);
380+ }
381+
382+ construct {
383+ Session.open_sessions++;
384+ }
385+
386+ ~Session () {
387+ Session.open_sessions--;
388+ }
389+
390+ }
391+
392+ private class Storage : Base.Storage {
393+ protected Sqlite.Database db;
394+
395+ public override Katze.Array get_sessions () {
396+ Katze.Array sessions = new Katze.Array (typeof (Session));
397+
398+ string sqlcmd = "SELECT id FROM sessions WHERE closed = 0;";
399+ Sqlite.Statement stmt;
400+ if (this.db.prepare_v2 (sqlcmd, -1, out stmt, null) != Sqlite.OK)
401+ critical (_("Failed to select from database: %s"), db.errmsg);
402+ int result = stmt.step ();
403+ if (!(result == Sqlite.DONE || result == Sqlite.ROW)) {
404+ critical (_("Failed to select from database: %s"), db.errmsg);
405+ return sessions;
406+ }
407+
408+ while (result == Sqlite.ROW) {
409+ int64 id = stmt.column_int64 (0);
410+ sessions.add_item (new Session.with_id (this.db, id));
411+ result = stmt.step ();
412+ }
413+
414+ if (sessions.is_empty ()) {
415+ sessions.add_item (new Session (this.db));
416+ }
417+
418+ return sessions;
419+ }
420+
421+ public override Base.Session get_new_session () {
422+ return new Session (this.db) as Base.Session;
423+ }
424+
425+ internal Storage (Midori.App app) {
426+ GLib.Object (app: app);
427+
428+ string db_path = Midori.Paths.get_config_filename_for_writing ("tabby.db");
429+
430+ /* FixMe: why does GLib.FileUtils.test(db_path, GLib.FileTest.EXISTS); randomly work or not? */
431+
432+ if (Sqlite.Database.open_v2 (db_path, out this.db) != Sqlite.OK)
433+ critical (_("Failed to open stored session: %s"), db.errmsg);
434+
435+ string filename = Midori.Paths.get_res_filename ("tabby/Create.sql");
436+ string schema;
437+ try {
438+ bool success = FileUtils.get_contents (filename, out schema, null);
439+ if (!success || schema == null)
440+ critical (_("Failed to open database schema file: %s"), filename);
441+ if (success && schema != null)
442+ if (this.db.exec (schema) != Sqlite.OK)
443+ critical (_("Failed to execute database schema: %s"), filename);
444+ else {
445+ string config_file = Midori.Paths.get_config_filename_for_reading ("session.xbel");
446+ try {
447+ Katze.Array old_session = new Katze.Array (typeof (Katze.Item));
448+ Midori.array_from_file (old_session, config_file, "xbel-tiny");
449+ this.import_session (old_session);
450+ } catch (GLib.FileError file_error) {
451+ /* no old session.xbel -> could be a new profile -> ignore it */
452+ } catch (GLib.Error error) {
453+ critical (_("Failed to import legacy session: %s"), error.message);
454+ }
455+ }
456+ } catch (GLib.FileError schema_error) {
457+ critical (_("Failed to open database schema file: %s"), schema_error.message);
458+ }
459+ }
460+ }
461+ }
462+
463+ private class Manager : Midori.Extension {
464+ private Base.Storage storage;
465+ private bool load_session () {
466+ this.storage.restore_last_sessions ();
467+ return false;
468+ }
469+
470+ private void browser_added (Midori.Browser browser) {
471+ Base.Session session = browser.get_data<Base.Session> ("tabby-session");
472+ if (session == null) {
473+ session = this.storage.get_new_session () as Base.Session;
474+ browser.set_data<Base.Session> ("tabby-session", session);
475+ session.attach (browser);
476+ }
477+ }
478+
479+ private void browser_removed (Midori.Browser browser) {
480+ Base.Session session = browser.get_data<Base.Session> ("tabby-session");
481+ if (session == null) {
482+ GLib.warning ("missing session");
483+ } else {
484+ session.close ();
485+ }
486+ }
487+
488+ private void activated (Midori.App app) {
489+ /* FixMe: provide an option to replace Local.Storage with IStorage based Objects */
490+ this.storage = new Local.Storage (this.get_app ()) as Base.Storage;
491+
492+ app.add_browser.connect (browser_added);
493+ app.remove_browser.connect (browser_removed);
494+
495+ GLib.Idle.add (this.load_session);
496+ }
497+
498+ internal Manager () {
499+ GLib.Object (name: _("Tabby"),
500+ description: _("Tab and session management."),
501+ version: "0.1",
502+ authors: "André Stösel <andre@stoesel.de>");
503+
504+ activate.connect (this.activated);
505+ }
506+ }
507+}
508+
509+public Midori.Extension extension_init () {
510+ return new Tabby.Manager ();
511+}
512
513=== modified file 'katze/midori-paths.vala'
514--- katze/midori-paths.vala 2013-08-02 18:35:37 +0000
515+++ katze/midori-paths.vala 2013-09-07 14:18:40 +0000
516@@ -354,7 +354,7 @@
517
518 /* Fallback to build folder */
519 path = Path.build_filename ((File.new_for_path (exec_path)
520- .get_parent ().get_parent ().get_path ()), "data", filename);
521+ .get_parent ().get_path ()), "data", filename);
522 if (Posix.access (path, Posix.F_OK) == 0)
523 return path;
524
525
526=== modified file 'midori/midori-extension.c'
527--- midori/midori-extension.c 2013-07-07 11:29:11 +0000
528+++ midori/midori-extension.c 2013-09-07 14:18:40 +0000
529@@ -561,6 +561,8 @@
530 /* FIXME need proper stock extension mechanism */
531 g_assert (midori_extension_activate_gracefully (app, extension_path, "libtransfers." G_MODULE_SUFFIX, activate));
532 g_assert (midori_extension_activate_gracefully (app, extension_path, "libapps." G_MODULE_SUFFIX, activate));
533+ g_assert (midori_extension_activate_gracefully (app, extension_path, "libdelayed-load." G_MODULE_SUFFIX, activate));
534+ g_assert (midori_extension_activate_gracefully (app, extension_path, "libtabby." G_MODULE_SUFFIX, activate));
535 }
536 else
537 {
538@@ -673,7 +675,9 @@
539 return;
540 /* FIXME need proper stock extension mechanism */
541 if (!strcmp (filename, "libtransfers." G_MODULE_SUFFIX)
542- || !strcmp (filename, "libapps." G_MODULE_SUFFIX))
543+ || !strcmp (filename, "libapps." G_MODULE_SUFFIX)
544+ || !strcmp (filename, "libdelayed-load." G_MODULE_SUFFIX)
545+ || !strcmp (filename, "libtabby." G_MODULE_SUFFIX))
546 return;
547
548 katze_array_add_item (extensions, extension);
549
550=== modified file 'midori/midori-frontend.c'
551--- midori/midori-frontend.c 2013-08-29 20:27:55 +0000
552+++ midori/midori-frontend.c 2013-09-07 14:18:40 +0000
553@@ -585,9 +585,10 @@
554 g_signal_connect (app, "add-browser",
555 G_CALLBACK (midori_app_add_browser_cb), NULL);
556
557+ midori_session_persistent_settings (settings, app);
558+
559 g_idle_add (midori_load_soup_session_full, settings);
560 g_idle_add (midori_load_extensions, app);
561- g_idle_add (midori_load_session, session);
562 return app;
563 }
564
565
566=== modified file 'midori/midori-session.c'
567--- midori/midori-session.c 2013-09-02 20:05:07 +0000
568+++ midori/midori-session.c 2013-09-07 14:18:40 +0000
569@@ -395,38 +395,6 @@
570 g_free (config_file);
571 }
572
573-void
574-midori_session_persistent_settings (MidoriWebSettings* settings,
575- MidoriApp* app)
576-{
577- g_signal_connect_after (settings, "notify", G_CALLBACK (settings_notify_cb), app);
578-}
579-
580-static void
581-midori_browser_action_last_session_activate_cb (GtkAction* action,
582- MidoriBrowser* browser)
583-{
584- KatzeArray* old_session = katze_array_new (KATZE_TYPE_ITEM);
585- gchar* config_file = midori_paths_get_config_filename_for_reading ("session.old.xbel");
586- GError* error = NULL;
587- if (midori_array_from_file (old_session, config_file, "xbel-tiny", &error))
588- {
589- KatzeItem* item;
590- KATZE_ARRAY_FOREACH_ITEM (item, old_session)
591- midori_browser_add_item (browser, item);
592- }
593- else
594- {
595- sokoke_message_dialog (GTK_MESSAGE_ERROR,
596- _("The session couldn't be loaded: %s\n"), error->message, FALSE);
597- g_error_free (error);
598- }
599- g_free (config_file);
600- gtk_action_set_sensitive (action, FALSE);
601- g_signal_handlers_disconnect_by_func (action,
602- midori_browser_action_last_session_activate_cb, browser);
603-}
604-
605 static void
606 midori_session_accel_map_changed_cb (GtkAccelMap* accel_map,
607 gchar* accel_path,
608@@ -438,153 +406,12 @@
609 g_free (config_file);
610 }
611
612-static guint save_timeout = 0;
613-
614-static gboolean
615-midori_session_save_timeout_cb (KatzeArray* session)
616-{
617- gchar* config_file = midori_paths_get_config_filename_for_writing ("session.xbel");
618- GError* error = NULL;
619- if (!midori_array_to_file (session, config_file, "xbel-tiny", &error))
620- {
621- g_warning (_("The session couldn't be saved. %s"), error->message);
622- g_error_free (error);
623- }
624- g_free (config_file);
625-
626- save_timeout = 0;
627- return FALSE;
628-}
629-
630-static void
631-midori_browser_session_cb (MidoriBrowser* browser,
632- gpointer pspec,
633- KatzeArray* session)
634-{
635- if (!save_timeout)
636- save_timeout = midori_timeout_add_seconds (
637- 5, (GSourceFunc)midori_session_save_timeout_cb, session, NULL);
638-}
639-
640-static void
641-midori_app_quit_cb (MidoriBrowser* browser,
642- KatzeArray* session)
643-{
644- midori_session_save_timeout_cb (session);
645-}
646-
647-static void
648-midori_browser_weak_notify_cb (MidoriBrowser* browser,
649- KatzeArray* session)
650-{
651- g_object_disconnect (browser, "any-signal",
652- G_CALLBACK (midori_browser_session_cb), session, NULL);
653-}
654-
655-gboolean
656-midori_load_session (gpointer data)
657-{
658- KatzeArray* saved_session = KATZE_ARRAY (data);
659- MidoriBrowser* browser;
660- MidoriApp* app = katze_item_get_parent (KATZE_ITEM (saved_session));
661- MidoriWebSettings* settings = katze_object_get_object (app, "settings");
662- MidoriStartup load_on_startup;
663- gchar* config_file;
664- KatzeArray* session;
665- KatzeItem* item;
666- gint64 current;
667- gchar** open_uris = g_object_get_data (G_OBJECT (app), "open-uris");
668- gchar** execute_commands = g_object_get_data (G_OBJECT (app), "execute-commands");
669- gchar* uri;
670- guint i = 0;
671- gboolean startup_timer = midori_debug ("startup");
672- GTimer* timer = startup_timer ? g_timer_new () : NULL;
673-
674- browser = midori_app_create_browser (app);
675- midori_session_persistent_settings (settings, app);
676-
677- config_file = midori_paths_get_config_filename_for_reading ("session.old.xbel");
678- if (g_access (config_file, F_OK) == 0)
679- {
680- GtkActionGroup* action_group = midori_browser_get_action_group (browser);
681- GtkAction* action = gtk_action_group_get_action (action_group, "LastSession");
682- g_signal_connect (action, "activate",
683- G_CALLBACK (midori_browser_action_last_session_activate_cb), browser);
684- gtk_action_set_visible (action, TRUE);
685- }
686- midori_app_add_browser (app, browser);
687- gtk_widget_show (GTK_WIDGET (browser));
688-
689- katze_assign (config_file, midori_paths_get_config_filename_for_reading ("accels"));
690+void
691+midori_session_persistent_settings (MidoriWebSettings* settings,
692+ MidoriApp* app)
693+{
694+ g_signal_connect_after (settings, "notify", G_CALLBACK (settings_notify_cb), app);
695 g_signal_connect_after (gtk_accel_map_get (), "changed",
696 G_CALLBACK (midori_session_accel_map_changed_cb), NULL);
697
698- load_on_startup = (MidoriStartup)g_object_get_data (G_OBJECT (settings), "load-on-startup");
699- if (katze_array_is_empty (saved_session))
700- {
701- item = katze_item_new ();
702- if (open_uris)
703- {
704- uri = sokoke_magic_uri (open_uris[i], TRUE, TRUE);
705- katze_item_set_uri (item, uri);
706- g_free (uri);
707- i++;
708- } else if (load_on_startup == MIDORI_STARTUP_BLANK_PAGE)
709- katze_item_set_uri (item, "about:new");
710- else
711- katze_item_set_uri (item, "about:home");
712- katze_array_add_item (saved_session, item);
713- g_object_unref (item);
714- }
715-
716- session = midori_browser_get_proxy_array (browser);
717- KATZE_ARRAY_FOREACH_ITEM (item, saved_session)
718- {
719- katze_item_set_meta_integer (item, "append", 1);
720- katze_item_set_meta_integer (item, "dont-write-history", 1);
721- if (load_on_startup == MIDORI_STARTUP_DELAYED_PAGES
722- || katze_item_get_meta_integer (item, "delay") == MIDORI_DELAY_PENDING_UNDELAY)
723- katze_item_set_meta_integer (item, "delay", MIDORI_DELAY_DELAYED);
724- midori_browser_add_item (browser, item);
725- }
726-
727- current = katze_item_get_meta_integer (KATZE_ITEM (saved_session), "current");
728- if (!(item = katze_array_get_nth_item (saved_session, current)))
729- {
730- current = 0;
731- item = katze_array_get_nth_item (saved_session, 0);
732- }
733- midori_browser_set_current_page (browser, current);
734- if (midori_uri_is_blank (katze_item_get_uri (item)))
735- midori_browser_activate_action (browser, "Location");
736-
737- /* `i` also used above; in that case we won't re-add the same URLs here */
738- for (; open_uris && open_uris[i]; i++)
739- {
740- uri = sokoke_magic_uri (open_uris[i], TRUE, TRUE);
741- midori_browser_add_uri (browser, uri);
742- g_free (uri);
743- }
744-
745- g_object_unref (settings);
746- g_object_unref (saved_session);
747- g_free (config_file);
748-
749- g_signal_connect_after (browser, "add-tab",
750- G_CALLBACK (midori_browser_session_cb), session);
751- g_signal_connect_after (browser, "remove-tab",
752- G_CALLBACK (midori_browser_session_cb), session);
753- g_signal_connect (app, "quit",
754- G_CALLBACK (midori_app_quit_cb), session);
755- g_object_weak_ref (G_OBJECT (session),
756- (GWeakNotify)(midori_browser_weak_notify_cb), browser);
757-
758- if (execute_commands != NULL)
759- midori_app_send_command (app, execute_commands);
760-
761- if (startup_timer)
762- g_debug ("Session setup:\t%f", g_timer_elapsed (timer, NULL));
763-
764- return FALSE;
765 }
766-
767
768=== modified file 'midori/midori-session.h'
769--- midori/midori-session.h 2013-05-23 22:15:27 +0000
770+++ midori/midori-session.h 2013-09-07 14:18:40 +0000
771@@ -25,9 +25,6 @@
772 gboolean
773 midori_load_extensions (gpointer data);
774
775-gboolean
776-midori_load_session (gpointer data);
777-
778 void
779 midori_session_persistent_settings (MidoriWebSettings* settings,
780 MidoriApp* app);
781
782=== modified file 'midori/midori.vapi'
783--- midori/midori.vapi 2013-08-20 08:24:46 +0000
784+++ midori/midori.vapi 2013-09-07 14:18:40 +0000
785@@ -21,6 +21,9 @@
786 [CCode (array_length = false)] string[]? uris, [CCode (array_length = false)] string[]? commands, int reset, string? block);
787 public static void normal_app_on_quit (App app);
788
789+ [CCode (cheader_filename = "midori/midori-array.h")]
790+ public static bool array_from_file (Katze.Array array, string filename, string format) throws GLib.Error;
791+
792 [CCode (cheader_filename = "midori/midori.h")]
793 public class App : GLib.Object {
794 public App (string? name=null);

Subscribers

People subscribed via source and target branches

to all changes: