Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Paweł Forysiuk | ||||
Approved revision: | 6208 | ||||
Merged at revision: | 6273 | ||||
Proposed branch: | lp:~kalikiana/midori/apple | ||||
Merge into: | lp:midori | ||||
Diff against target: |
534 lines (+199/-40) 11 files modified
extensions/apps.vala (+94/-28) katze/katze-item.c (+0/-2) katze/midori-paths.vala (+2/-0) midori/midori-completion.vala (+17/-3) midori/midori-locationaction.c (+2/-1) midori/midori-searchcompletion.vala (+2/-5) midori/midori.vapi (+4/-0) midori/sokoke.c (+67/-0) midori/sokoke.h (+8/-0) midori/wscript_build (+1/-1) wscript (+2/-0) |
||||
To merge this branch: | bzr merge lp:~kalikiana/midori/apple | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Paweł Forysiuk | Approve | ||
Cris Dywan | Abstain | ||
Review via email:
|
Commit message
Read apps/ profiles from folder, leave launchers separate
Description of the change
Read apps/ profiles from folder, leave launchers separate
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Paweł Forysiuk (tuxator) wrote : | # |
regarding profiles and win32
it seems to refuse to parse Exec line if there is a backslash there,
so
midori -c c:\dir\
needs to be
midori -c c:\\dir\
Fixing this makes launcher for profile appear on the panel at least
from launching from cli -c arg needs to be double quoted instead it would just run into first
space in the path and thinks it is the whole path
so
midori -c c:\\Documents and Settings\\user
will be launched as
midori -c C:\\Documents
But even with quotes in exec line in desktop file it does not seem to launch properly
about:paths show regular version paths and it just shows google - like in launch where
no existing config is found
additionally i get following error on the cli
** (midori4:1524): WARNING **: fd_recv(): failed with 10054 (errno = 0)
Adding paths to files when showing warings should not hurt as well.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Cris Dywan (kalikiana) : | # |
- 6205. By Paweł Forysiuk
-
Implement deleting default launcher on win32
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Paweł Forysiuk (tuxator) wrote : | # |
I did not check this before but unfortunately adding monitors seems to kill midori ;/
Also there is a problem when there is unicode title it will create launcher but desktop file will not
be parsed so it will not show in the panel, this seems to come from name and i think it is the same
issue as with completion and such.
I implemented deleting default lnk file but we need to sort out crasher and codepage stuff.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Cris Dywan (kalikiana) wrote : | # |
Is it possible that SHGetFolderPath returns a local encoding such as ISO-8859-1? How about using g_get_user_
I haven't seen a crash due to monitoring, a backtrace would be useful.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Paweł Forysiuk (tuxator) wrote : | # |
no crash when using glib function but monitoring does not seem to work, i need to restart midori
- 6206. By Paweł Forysiuk
-
Use glib funtion to get destkop folder on win32
- 6207. By Paweł Forysiuk
-
Check if file exists before removing lnk file
- 6208. By Paweł Forysiuk
-
Don't needlessly recompute filename from launcher title
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Cris Dywan (kalikiana) wrote : | # |
Please review to get this into trunk and simply file the last Win32 quirks as bugs (monitoring and unicode handling).
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Paweł Forysiuk (tuxator) wrote : | # |
Looks fine so far
Preview Diff
1 | === modified file 'extensions/apps.vala' |
2 | --- extensions/apps.vala 2013-06-21 23:18:01 +0000 |
3 | +++ extensions/apps.vala 2013-07-04 20:20:33 +0000 |
4 | @@ -22,11 +22,41 @@ |
5 | |
6 | internal static async void create (string prefix, GLib.File folder, string uri, string title, Gtk.Widget proxy) { |
7 | /* Strip LRE leading character and / */ |
8 | - string exec = prefix + uri; |
9 | string name = title.delimit ("/", ' ').strip(); |
10 | - string filename = Midori.Download.clean_filename (name) + ".desktop"; |
11 | - // TODO: Midori.Paths.get_icon save to png |
12 | + string filename = Midori.Download.clean_filename (name); |
13 | + string exec; |
14 | +#if HAVE_WIN32 |
15 | + string doubleslash_uri = uri.replace ("\\", "\\\\"); |
16 | + string quoted_uri = GLib.Shell.quote (doubleslash_uri); |
17 | + exec = prefix + quoted_uri; |
18 | +#else |
19 | + exec = prefix + uri; |
20 | +#endif |
21 | + try { |
22 | + folder.make_directory_with_parents (null); |
23 | + } |
24 | + catch (Error error) { |
25 | + /* It's not an error if the folder already exists; |
26 | + any fatal problems will fail further down the line */ |
27 | + } |
28 | + |
29 | string icon_name = Midori.Stock.WEB_BROWSER; |
30 | + try { |
31 | + var pixbuf = Midori.Paths.get_icon (uri, null); |
32 | + if (pixbuf == null) |
33 | + throw new FileError.EXIST ("No favicon loaded"); |
34 | + string icon_filename = folder.get_child ("icon.png").get_path (); |
35 | + pixbuf.save (icon_filename, "png", null, "compression", "7", null); |
36 | +#if HAVE_WIN32 |
37 | + string doubleslash_icon = icon_filename.replace ("\\", "\\\\"); |
38 | + icon_name = doubleslash_icon; |
39 | +#else |
40 | + icon_name = icon_filename; |
41 | +#endif |
42 | + } |
43 | + catch (Error error) { |
44 | + GLib.warning (_("Failed to fetch application icon in %s: %s"), folder.get_path (), error.message); |
45 | + } |
46 | string contents = """ |
47 | [Desktop Entry] |
48 | Version=1.0 |
49 | @@ -37,16 +67,25 @@ |
50 | Icon=%s |
51 | Categories=Network; |
52 | """.printf (name, exec, PACKAGE_NAME, icon_name); |
53 | - var file = folder.get_child (filename); |
54 | + var file = folder.get_child ("desc"); |
55 | var browser = proxy.get_toplevel () as Midori.Browser; |
56 | try { |
57 | var stream = yield file.replace_async (null, false, GLib.FileCreateFlags.NONE); |
58 | yield stream.write_async (contents.data); |
59 | + // Create a launcher/ menu |
60 | +#if HAVE_WIN32 |
61 | + Midori.Sokoke.create_win32_desktop_lnk (prefix, filename, uri); |
62 | +#else |
63 | + var data_dir = File.new_for_path (Midori.Paths.get_user_data_dir ()); |
64 | + yield file.copy_async (data_dir.get_child ("applications").get_child (filename + ".desktop"), |
65 | + GLib.FileCopyFlags.NONE); |
66 | +#endif |
67 | |
68 | browser.send_notification (_("Launcher created"), |
69 | _("You can now run <b>%s</b> from your launcher or menu").printf (name)); |
70 | } |
71 | catch (Error error) { |
72 | + warning (_("Failed to create new launcher: %s").printf (error.message)); |
73 | browser.send_notification (_("Error creating launcher"), |
74 | _("Failed to create new launcher: %s").printf (error.message)); |
75 | } |
76 | @@ -57,11 +96,9 @@ |
77 | } |
78 | |
79 | bool init (GLib.Cancellable? cancellable) throws GLib.Error { |
80 | - if (!file.get_basename ().has_suffix (".desktop")) |
81 | - return false; |
82 | - |
83 | var keyfile = new GLib.KeyFile (); |
84 | - keyfile.load_from_file (file.get_path (), GLib.KeyFileFlags.NONE); |
85 | + keyfile.load_from_file (file.get_child ("desc").get_path (), GLib.KeyFileFlags.NONE); |
86 | + |
87 | exec = keyfile.get_string ("Desktop Entry", "Exec"); |
88 | if (!exec.has_prefix (APP_PREFIX) && !exec.has_prefix (PROFILE_PREFIX)) |
89 | return false; |
90 | @@ -79,6 +116,7 @@ |
91 | Gtk.TreeView treeview; |
92 | Katze.Array array; |
93 | GLib.File app_folder; |
94 | + GLib.File profile_folder; |
95 | |
96 | public unowned string get_stock_id () { |
97 | return Midori.Stock.WEB_BROWSER; |
98 | @@ -102,7 +140,7 @@ |
99 | string uuid = g_dbus_generate_guid (); |
100 | string config = Path.build_path (Path.DIR_SEPARATOR_S, |
101 | Midori.Paths.get_user_data_dir (), PACKAGE_NAME, "profiles", uuid); |
102 | - Launcher.create.begin (PROFILE_PREFIX, app_folder, |
103 | + Launcher.create.begin (PROFILE_PREFIX, profile_folder.get_child (uuid), |
104 | config, _("Midori (%s)").printf (uuid), this); |
105 | }); |
106 | toolbar.insert (profile, -1); |
107 | @@ -115,7 +153,8 @@ |
108 | app.show (); |
109 | app.clicked.connect (() => { |
110 | var view = (get_toplevel () as Midori.Browser).tab as Midori.View; |
111 | - Launcher.create.begin (APP_PREFIX, app_folder, |
112 | + string checksum = Checksum.compute_for_string (ChecksumType.MD5, view.get_display_uri (), -1); |
113 | + Launcher.create.begin (APP_PREFIX, app_folder.get_child (checksum), |
114 | view.get_display_uri (), view.get_display_title (), this); |
115 | }); |
116 | toolbar.insert (app, -1); |
117 | @@ -151,6 +190,18 @@ |
118 | try { |
119 | launcher.file.trash (null); |
120 | store.remove (iter); |
121 | + |
122 | + string filename = Midori.Download.clean_filename (launcher.name); |
123 | +#if HAVE_WIN32 |
124 | + string lnk_filename = Midori.Sokoke.get_win32_desktop_lnk_path_for_filename (filename); |
125 | + if (Posix.access (lnk_filename, Posix.F_OK) == 0) { |
126 | + var lnk_file = File.new_for_path (lnk_filename); |
127 | + lnk_file.trash (); |
128 | + } |
129 | +#else |
130 | + var data_dir = File.new_for_path (Midori.Paths.get_user_data_dir ()); |
131 | + data_dir.get_child ("applications").get_child (filename + ".desktop").trash (); |
132 | +#endif |
133 | } |
134 | catch (Error error) { |
135 | GLib.critical (error.message); |
136 | @@ -163,7 +214,7 @@ |
137 | return false; |
138 | } |
139 | |
140 | - public Sidebar (Katze.Array array, GLib.File app_folder) { |
141 | + public Sidebar (Katze.Array array, GLib.File app_folder, GLib.File profile_folder) { |
142 | Gtk.TreeViewColumn column; |
143 | |
144 | treeview = new Gtk.TreeView.with_model (store); |
145 | @@ -204,6 +255,7 @@ |
146 | launcher_added (item); |
147 | |
148 | this.app_folder = app_folder; |
149 | + this.profile_folder = profile_folder; |
150 | } |
151 | |
152 | private int tree_sort_func (Gtk.TreeModel model, Gtk.TreeIter a, Gtk.TreeIter b) { |
153 | @@ -228,11 +280,18 @@ |
154 | |
155 | Launcher launcher; |
156 | model.get (iter, 0, out launcher); |
157 | - if (launcher.icon_name != null) |
158 | + |
159 | + try { |
160 | + int icon_width = 48, icon_height = 48; |
161 | + Gtk.icon_size_lookup_for_settings (get_settings (), |
162 | + Gtk.IconSize.DIALOG, out icon_width, out icon_height); |
163 | + var pixbuf = new Gdk.Pixbuf.from_file_at_size (launcher.icon_name, icon_width, icon_height); |
164 | + renderer.set ("pixbuf", pixbuf); |
165 | + } |
166 | + catch (Error error) { |
167 | renderer.set ("icon-name", launcher.icon_name); |
168 | - else |
169 | - renderer.set ("stock-id", Gtk.STOCK_FILE); |
170 | - renderer.set ("stock-size", Gtk.IconSize.BUTTON, |
171 | + } |
172 | + renderer.set ("stock-size", Gtk.IconSize.DIALOG, |
173 | "xpad", 4); |
174 | } |
175 | |
176 | @@ -258,7 +317,8 @@ |
177 | private class Manager : Midori.Extension { |
178 | internal Katze.Array array; |
179 | internal GLib.File app_folder; |
180 | - internal GLib.FileMonitor? monitor; |
181 | + internal GLib.File profile_folder; |
182 | + internal GLib.List<GLib.FileMonitor> monitors; |
183 | internal GLib.List<Gtk.Widget> widgets; |
184 | |
185 | void app_changed (GLib.File file, GLib.File? other, GLib.FileMonitorEvent event) { |
186 | @@ -282,9 +342,7 @@ |
187 | } |
188 | } |
189 | |
190 | - async void populate_apps () { |
191 | - var data_dir = File.new_for_path (Midori.Paths.get_user_data_dir ()); |
192 | - app_folder = data_dir.get_child ("applications"); |
193 | + async void populate_apps (File app_folder) { |
194 | try { |
195 | try { |
196 | app_folder.make_directory_with_parents (null); |
197 | @@ -294,8 +352,9 @@ |
198 | throw folder_error; |
199 | } |
200 | |
201 | - monitor = app_folder.monitor_directory (0, null); |
202 | + var monitor = app_folder.monitor_directory (0, null); |
203 | monitor.changed.connect (app_changed); |
204 | + monitors.append (monitor); |
205 | |
206 | var enumerator = yield app_folder.enumerate_children_async ("standard::name", 0); |
207 | while (true) { |
208 | @@ -303,9 +362,9 @@ |
209 | if (files == null) |
210 | break; |
211 | foreach (var info in files) { |
212 | - var desktop_file = app_folder.get_child (info.get_name ()); |
213 | + var file = app_folder.get_child (info.get_name ()); |
214 | try { |
215 | - var launcher = new Launcher (desktop_file); |
216 | + var launcher = new Launcher (file); |
217 | if (launcher.init ()) |
218 | array.add_item (launcher); |
219 | } |
220 | @@ -316,8 +375,7 @@ |
221 | } |
222 | } |
223 | catch (Error io_error) { |
224 | - monitor = null; |
225 | - warning ("Failed to list .desktop files (%s): %s", |
226 | + warning ("Failed to list apps (%s): %s", |
227 | app_folder.get_path (), io_error.message); |
228 | } |
229 | } |
230 | @@ -328,13 +386,14 @@ |
231 | menu.append (menuitem); |
232 | menuitem.activate.connect (() => { |
233 | var view = browser.tab as Midori.View; |
234 | - Launcher.create.begin (APP_PREFIX, app_folder, |
235 | + string checksum = Checksum.compute_for_string (ChecksumType.MD5, view.get_display_uri (), -1); |
236 | + Launcher.create.begin (APP_PREFIX, app_folder.get_child (checksum), |
237 | view.get_display_uri (), view.get_display_title (), browser); |
238 | }); |
239 | } |
240 | |
241 | void browser_added (Midori.Browser browser) { |
242 | - var viewable = new Sidebar (array, app_folder); |
243 | + var viewable = new Sidebar (array, app_folder, profile_folder); |
244 | viewable.show (); |
245 | browser.panel.append_page (viewable); |
246 | browser.populate_tool_menu.connect (tool_menu_populated); |
247 | @@ -344,7 +403,12 @@ |
248 | |
249 | void activated (Midori.App app) { |
250 | array = new Katze.Array (typeof (Launcher)); |
251 | - populate_apps.begin (); |
252 | + var data_dir = File.new_for_path (Midori.Paths.get_user_data_dir ()).get_child (PACKAGE_NAME); |
253 | + monitors = new GLib.List<GLib.FileMonitor> (); |
254 | + app_folder = data_dir.get_child ("apps"); |
255 | + populate_apps.begin (app_folder); |
256 | + profile_folder = data_dir.get_child ("profiles"); |
257 | + populate_apps.begin (profile_folder); |
258 | widgets = new GLib.List<Gtk.Widget> (); |
259 | foreach (var browser in app.get_browsers ()) |
260 | browser_added (browser); |
261 | @@ -353,8 +417,10 @@ |
262 | |
263 | void deactivated () { |
264 | var app = get_app (); |
265 | - if (monitor != null) |
266 | + foreach (var monitor in monitors) |
267 | monitor.changed.disconnect (app_changed); |
268 | + monitors = null; |
269 | + |
270 | app.add_browser.disconnect (browser_added); |
271 | foreach (var widget in widgets) |
272 | widget.destroy (); |
273 | |
274 | === modified file 'katze/katze-item.c' |
275 | --- katze/katze-item.c 2013-06-25 16:26:37 +0000 |
276 | +++ katze/katze-item.c 2013-07-04 20:20:33 +0000 |
277 | @@ -447,8 +447,6 @@ |
278 | |
279 | if (widget && KATZE_ITEM_IS_FOLDER (item)) |
280 | return gtk_widget_render_icon (widget, GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL); |
281 | - if ((pixbuf = midori_paths_get_icon (katze_item_get_icon (item), NULL))) |
282 | - return pixbuf; |
283 | if ((pixbuf = midori_paths_get_icon (item->uri, widget))) |
284 | return pixbuf; |
285 | return NULL; |
286 | |
287 | === modified file 'katze/midori-paths.vala' |
288 | --- katze/midori-paths.vala 2013-06-26 21:54:50 +0000 |
289 | +++ katze/midori-paths.vala 2013-07-04 20:20:33 +0000 |
290 | @@ -424,6 +424,8 @@ |
291 | if (widget != null) |
292 | Gtk.icon_size_lookup_for_settings (widget.get_settings (), |
293 | Gtk.IconSize.MENU, out icon_width, out icon_height); |
294 | + else |
295 | + icon_width = icon_height = 0 /* maximum size */; |
296 | #if HAVE_WEBKIT2 |
297 | /* TODO async |
298 | var database = WebKit.WebContext.get_default ().get_favicon_database (); |
299 | |
300 | === modified file 'midori/midori-completion.vala' |
301 | --- midori/midori-completion.vala 2013-05-19 09:43:05 +0000 |
302 | +++ midori/midori-completion.vala 2013-07-04 20:20:33 +0000 |
303 | @@ -52,6 +52,7 @@ |
304 | MARKUP, |
305 | BACKGROUND, |
306 | YALIGN, |
307 | + SIZE, |
308 | N |
309 | } |
310 | |
311 | @@ -60,8 +61,8 @@ |
312 | completions = new List<Completion> (); |
313 | next_position = 0; |
314 | model = new Gtk.ListStore (Columns.N, |
315 | - typeof (Gdk.Pixbuf), typeof (string), typeof (string), |
316 | - typeof (string), typeof (float)); |
317 | + typeof (GLib.Icon), typeof (string), typeof (string), |
318 | + typeof (string), typeof (float), typeof (uint)); |
319 | } |
320 | |
321 | public void add (Completion completion) { |
322 | @@ -78,6 +79,17 @@ |
323 | return false; |
324 | } |
325 | |
326 | + private GLib.Icon? scale_if_needed (GLib.Icon? icon) { |
327 | + if (icon is Gdk.Pixbuf) { |
328 | + var pixbuf = icon as Gdk.Pixbuf; |
329 | + int icon_width = 16, icon_height = 16; |
330 | + Gtk.icon_size_lookup (Gtk.IconSize.MENU, out icon_width, out icon_height); |
331 | + if (pixbuf.width > icon_width || pixbuf.height > icon_height) |
332 | + return pixbuf.scale_simple (icon_width, icon_height, Gdk.InterpType.BILINEAR); |
333 | + } |
334 | + return icon; |
335 | + } |
336 | + |
337 | private void fill_model (Midori.Completion completion, List<Midori.Suggestion>? suggestions) { |
338 | if (need_to_clear) { |
339 | model.clear (); |
340 | @@ -91,6 +103,7 @@ |
341 | Columns.URI, "about:completion-description", |
342 | Columns.MARKUP, "<b>%s</b>\n".printf (Markup.escape_text (completion.description)), |
343 | Columns.ICON, null, |
344 | + Columns.SIZE, Gtk.IconSize.MENU, |
345 | Columns.BACKGROUND, null, |
346 | Columns.YALIGN, 0.25); |
347 | } |
348 | @@ -110,7 +123,8 @@ |
349 | Columns.URI, suggestion.uri, |
350 | Columns.MARKUP, suggestion.use_markup |
351 | ? suggestion.markup : Markup.escape_text (suggestion.markup), |
352 | - Columns.ICON, suggestion.icon, |
353 | + Columns.ICON, scale_if_needed (suggestion.icon), |
354 | + Columns.SIZE, Gtk.IconSize.MENU, |
355 | Columns.BACKGROUND, suggestion.background, |
356 | Columns.YALIGN, 0.25); |
357 | |
358 | |
359 | === modified file 'midori/midori-locationaction.c' |
360 | --- midori/midori-locationaction.c 2013-06-21 20:49:53 +0000 |
361 | +++ midori/midori-locationaction.c 2013-07-04 20:20:33 +0000 |
362 | @@ -714,7 +714,8 @@ |
363 | renderer = gtk_cell_renderer_pixbuf_new (); |
364 | gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer, FALSE); |
365 | gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer, |
366 | - "pixbuf", MIDORI_AUTOCOMPLETER_COLUMNS_ICON, |
367 | + "gicon", MIDORI_AUTOCOMPLETER_COLUMNS_ICON, |
368 | + "stock-size", MIDORI_AUTOCOMPLETER_COLUMNS_SIZE, |
369 | "yalign", MIDORI_AUTOCOMPLETER_COLUMNS_YALIGN, |
370 | "cell-background", MIDORI_AUTOCOMPLETER_COLUMNS_BACKGROUND, |
371 | NULL); |
372 | |
373 | === modified file 'midori/midori-searchcompletion.vala' |
374 | --- midori/midori-searchcompletion.vala 2013-05-19 09:43:05 +0000 |
375 | +++ midori/midori-searchcompletion.vala 2013-07-04 20:20:33 +0000 |
376 | @@ -39,16 +39,13 @@ |
377 | var suggestions = new List<Suggestion> (); |
378 | uint n = 0; |
379 | foreach (var item in items) { |
380 | - string icon, uri, title, desc; |
381 | - item.get ("icon", out icon); |
382 | + string uri, title, desc; |
383 | item.get ("uri", out uri); |
384 | item.get ("name", out title); |
385 | item.get ("text", out desc); |
386 | string search_uri = URI.for_search (uri, text); |
387 | string search_title = _("Search with %s").printf (title); |
388 | - Gdk.Pixbuf? pixbuf = Midori.Paths.get_icon (icon, null); |
389 | - if (pixbuf == null) |
390 | - pixbuf = Midori.Paths.get_icon (uri, null); |
391 | + Gdk.Pixbuf? pixbuf = Midori.Paths.get_icon (uri, null); |
392 | string search_desc = search_title + "\n" + desc ?? uri; |
393 | /* FIXME: Theming? Win32? */ |
394 | string background = "gray"; |
395 | |
396 | === modified file 'midori/midori.vapi' |
397 | --- midori/midori.vapi 2013-05-28 20:02:29 +0000 |
398 | +++ midori/midori.vapi 2013-07-04 20:20:33 +0000 |
399 | @@ -252,6 +252,10 @@ |
400 | [CCode (cheader_filename = "midori/sokoke.h", lower_case_cprefix = "sokoke_")] |
401 | namespace Sokoke { |
402 | public static uint gtk_action_count_modifiers (Gtk.Action action); |
403 | + #if HAVE_WIN32 |
404 | + public static string get_win32_desktop_lnk_path_for_filename (string filename); |
405 | + public static void create_win32_desktop_lnk (string prefix, string filename, string uri); |
406 | + #endif |
407 | } |
408 | } |
409 | |
410 | |
411 | === modified file 'midori/sokoke.c' |
412 | --- midori/sokoke.c 2013-06-26 21:54:50 +0000 |
413 | +++ midori/sokoke.c 2013-07-04 20:20:33 +0000 |
414 | @@ -34,6 +34,11 @@ |
415 | #include <glib/gstdio.h> |
416 | #include "katze/katze.h" |
417 | |
418 | +#ifdef G_OS_WIN32 |
419 | +#include <windows.h> |
420 | +#include <shlobj.h> |
421 | +#endif |
422 | + |
423 | static gchar* |
424 | sokoke_js_string_utf8 (JSStringRef js_string) |
425 | { |
426 | @@ -1116,3 +1121,65 @@ |
427 | return entry; |
428 | } |
429 | |
430 | +#ifdef G_OS_WIN32 |
431 | +gchar* |
432 | +sokoke_get_win32_desktop_lnk_path_for_filename (gchar* filename) |
433 | +{ |
434 | + const gchar* desktop_dir; |
435 | + gchar* lnk_path, *lnk_file; |
436 | + |
437 | + /* CSIDL_PROGRAMS for "start menu -> programs" instead - needs saner/shorter filename */ |
438 | + desktop_dir = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); |
439 | + |
440 | + lnk_file = g_strconcat (filename, ".lnk", NULL); |
441 | + lnk_path = g_build_filename (desktop_dir, lnk_file, NULL); |
442 | + |
443 | + g_free (lnk_file); |
444 | + |
445 | + return lnk_path; |
446 | +} |
447 | + |
448 | +void |
449 | +sokoke_create_win32_desktop_lnk (gchar* prefix, gchar* filename, gchar* uri) |
450 | +{ |
451 | + WCHAR w[MAX_PATH]; |
452 | + |
453 | + gchar* exec_dir, *exec_path, *argument; |
454 | + gchar* lnk_path, *launcher_type; |
455 | + |
456 | + IShellLink* pShellLink; |
457 | + IPersistFile* pPersistFile; |
458 | + |
459 | + exec_dir = g_win32_get_package_installation_directory_of_module (NULL); |
460 | + exec_path = g_build_filename (exec_dir, "bin", "midori.exe", NULL); |
461 | + |
462 | + if (g_str_has_suffix (prefix, " -a ")) |
463 | + launcher_type = "-a"; |
464 | + else if (g_str_has_suffix (prefix, " -c ")) |
465 | + launcher_type = "-c"; |
466 | + |
467 | + argument = g_strdup_printf ("%s \"%s\"", launcher_type, uri); |
468 | + |
469 | + /* Create link */ |
470 | + CoCreateInstance (&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (LPVOID *)&pShellLink); |
471 | + pShellLink->lpVtbl->SetPath (pShellLink, exec_path); |
472 | + pShellLink->lpVtbl->SetArguments (pShellLink, argument); |
473 | + /* TODO: support adding site favicon as webapp icon */ |
474 | + /* pShellLink->lpVtbl->SetIconLocation (pShellLink, icon_path, icon_index); */ |
475 | + |
476 | + /* Save link */ |
477 | + lnk_path = sokoke_get_win32_desktop_lnk_path_for_filename (filename); |
478 | + pShellLink->lpVtbl->QueryInterface (pShellLink, &IID_IPersistFile, (LPVOID *)&pPersistFile); |
479 | + MultiByteToWideChar (CP_UTF8, 0, lnk_path, -1, w, MAX_PATH); |
480 | + pPersistFile->lpVtbl->Save (pPersistFile, w, TRUE); |
481 | + |
482 | + pPersistFile->lpVtbl->Release (pPersistFile); |
483 | + pShellLink->lpVtbl->Release (pShellLink); |
484 | + |
485 | + g_free (exec_dir); |
486 | + g_free (exec_path); |
487 | + g_free (argument); |
488 | + g_free (lnk_path); |
489 | + g_free (launcher_type); |
490 | +} |
491 | +#endif |
492 | |
493 | === modified file 'midori/sokoke.h' |
494 | --- midori/sokoke.h 2013-04-11 20:38:19 +0000 |
495 | +++ midori/sokoke.h 2013-07-04 20:20:33 +0000 |
496 | @@ -128,4 +128,12 @@ |
497 | GtkWidget* |
498 | sokoke_search_entry_new (const gchar* placeholder_text); |
499 | |
500 | +#ifdef G_OS_WIN32 |
501 | +gchar* |
502 | +sokoke_get_win32_desktop_lnk_path_for_filename (gchar* filename); |
503 | + |
504 | +void |
505 | +sokoke_create_win32_desktop_lnk (gchar* prefix, gchar* filename, gchar* uri); |
506 | +#endif |
507 | + |
508 | #endif /* !__SOKOKE_H__ */ |
509 | |
510 | === modified file 'midori/wscript_build' |
511 | --- midori/wscript_build 2013-05-14 17:52:15 +0000 |
512 | +++ midori/wscript_build 2013-07-04 20:20:33 +0000 |
513 | @@ -9,7 +9,7 @@ |
514 | progressive = True |
515 | libs = 'M UNIQUE LIBSOUP GMODULE GTHREAD LIBIDN GIO GTK SQLITE ' \ |
516 | 'LIBNOTIFY WEBKIT JAVASCRIPTCOREGTK LIBXML X11 XSS WS2_32 ' \ |
517 | - 'GCR GRANITE ZEITGEIST' |
518 | + 'GCR GRANITE ZEITGEIST OLE32 UUID ' |
519 | |
520 | if Options.commands['build'] or Options.commands['check']: |
521 | blddir = str (bld.bldnode)[6:] # dir:// + absolute path |
522 | |
523 | === modified file 'wscript' |
524 | --- wscript 2013-06-30 14:37:38 +0000 |
525 | +++ wscript 2013-07-04 20:20:33 +0000 |
526 | @@ -309,6 +309,8 @@ |
527 | conf.check (function_name='inet_addr', header_name='sys/types.h sys/socket.h netinet/in.h arpa/inet.h') |
528 | conf.define ('HAVE_OSX', int(sys.platform == 'darwin')) |
529 | if Options.platform == 'win32': |
530 | + conf.check (lib='ole32') |
531 | + conf.check (lib='uuid') |
532 | conf.env.append_value ('LINKFLAGS', '-mwindows') |
533 | conf.env.append_value ('program_LINKFLAGS', ['-Wl,--out-implib=default/midori/libmidori.a', '-Wl,--export-all-symbols']) |
534 | else: |
Need to fix monitoring after the refactoring and ignore the error if the app/ profile folder exists, desc should still be created if -a was used on its own.