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

Subscribers

People subscribed via source and target branches

to all changes: