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

Proposed by André Stösel
Status: Merged
Approved by: Cris Dywan
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 Approve
Cris Dywan Approve
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.
Revision history for this message
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.

Revision history for this message
Cris 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
Revision history for this message
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: