Merge lp:~3v1n0/bamf/create-local-desktop into lp:bamf

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Christopher Townsend
Approved revision: 645
Merged at revision: 572
Proposed branch: lp:~3v1n0/bamf/create-local-desktop
Merge into: lp:bamf
Diff against target: 1319 lines (+731/-51)
23 files modified
debian/libbamf3-1.symbols (+1/-0)
lib/libbamf-private/org.ayatana.bamf.view.xml (+3/-0)
lib/libbamf-private/org.ayatana.bamf.xml (+8/-1)
lib/libbamf/bamf-application.c (+21/-0)
lib/libbamf/bamf-application.h (+3/-2)
lib/libbamf/bamf-control.c (+31/-5)
lib/libbamf/bamf-control.h (+4/-0)
lib/libbamf/bamf-tab-source.c (+1/-1)
src/bamf-application.c (+272/-2)
src/bamf-application.h (+2/-0)
src/bamf-control.c (+45/-8)
src/bamf-control.h (+3/-0)
src/bamf-legacy-window-test.c (+2/-2)
src/bamf-legacy-window.c (+20/-17)
src/bamf-legacy-window.h (+5/-3)
src/bamf-matcher.c (+27/-2)
src/bamf-matcher.h (+2/-0)
src/bamf-tab.c (+2/-4)
src/bamf-unity-webapps-application.c (+10/-1)
src/bamf-unity-webapps-observer.c (+0/-1)
tests/bamfdaemon/test-application.c (+220/-2)
tests/bamfdaemon/test-bamf.c (+12/-0)
tests/bamfdaemon/test-matcher.c (+37/-0)
To merge this branch: bzr merge lp:~3v1n0/bamf/create-local-desktop
Reviewer Review Type Date Requested Status
Christopher Townsend Approve
PS Jenkins bot (community) continuous-integration Approve
Marco Trevisan (Treviño) Pending
Review via email: mp+178794@code.launchpad.net

Commit message

BamfControl: add an API to allow generation of local .desktop file for a BamfApplication.

Add a bamf_control dbus method that requests to generate a new local .desktop
file for the provided application path. In case the application has alredy
a desktop file, the request is ignored. Otherwise we use some euristic to
generate an hopefully valid file saved in $XDG_DATA_HOME dir.

Also added a new DesktopUpdated signal to the BamfApplication DBus interface
that is emitted when the .desktop file for an application is set (for now).

Description of the change

Add a bamf_control dbus method that requests to generate a new local .desktop
file for the provided application path. In case the application has alredy
a desktop file, the request is ignored. Otherwise we use some euristic to
generate an hopefully valid file saved in $XDG_DATA_HOME dir.

Also added a new DesktopUpdated signal to the BamfApplication DBus interface
that is emitted when the .desktop file for an application is set (for now).

All the dbus changes have been reflected to the libbamf API.
New unit tests added.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~3v1n0/bamf/create-local-desktop updated
645. By Marco Trevisan (Treviño)

debian: update libbamf3-1 symbols file

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Christopher Townsend (townsend) wrote :

Merges and builds cleanly and all tests new and old pass. Code looks good.

I did not try the actual creating the desktop file since that is done by https://code.launchpad.net/~3v1n0/unity/desktop-file-updated-support/+merge/178703. I will review that MP and see if the .desktop file gets created and that the actual bug is fixed.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/libbamf3-1.symbols'
2--- debian/libbamf3-1.symbols 2012-12-19 16:21:01 +0000
3+++ debian/libbamf3-1.symbols 2013-08-06 16:20:35 +0000
4@@ -10,6 +10,7 @@
5 bamf_application_get_xids@Base 0.2.20
6 bamf_application_new@Base 0.2.20
7 bamf_application_new_favorite@Base 0.2.60
8+ bamf_control_create_local_desktop_file@Base 0.5.0
9 bamf_control_get_default@Base 0.2.20
10 bamf_control_get_type@Base 0.2.20
11 bamf_control_insert_desktop_file@Base 0.2.20
12
13=== modified file 'lib/libbamf-private/org.ayatana.bamf.view.xml'
14--- lib/libbamf-private/org.ayatana.bamf.view.xml 2013-06-19 19:31:58 +0000
15+++ lib/libbamf-private/org.ayatana.bamf.view.xml 2013-08-06 16:20:35 +0000
16@@ -105,6 +105,9 @@
17 <signal name="SupportedMimeTypesChanged">
18 <arg name="dnd_mimes" type="as"/>
19 </signal>
20+ <signal name="DesktopFileUpdated">
21+ <arg name="desktop_file" type="s"/>
22+ </signal>
23 </interface>
24
25 <interface name="org.ayatana.bamf.window">
26
27=== modified file 'lib/libbamf-private/org.ayatana.bamf.xml'
28--- lib/libbamf-private/org.ayatana.bamf.xml 2013-06-08 13:54:06 +0000
29+++ lib/libbamf-private/org.ayatana.bamf.xml 2013-08-06 16:20:35 +0000
30@@ -4,7 +4,7 @@
31 <interface name="org.ayatana.bamf.control">
32 <method name="Quit">
33 </method>
34- <method name="OmNomNomDesktopFile">
35+ <method name="InsertDesktopFile">
36 <arg name="tab_path" type="s" direction="in"/>
37 </method>
38 <method name="RegisterTabProvider">
39@@ -14,6 +14,13 @@
40 <arg name="application" type="s" direction="in"/>
41 <arg name="pid" type="i" direction="in"/>
42 </method>
43+ <method name="CreateLocalDesktopFile">
44+ <arg name="application" type="s" direction="in"/>
45+ </method>
46+ <method name="OmNomNomDesktopFile">
47+ <annotation name="org.freedesktop.DBus.Deprecated" value="true"/>
48+ <arg name="tab_path" type="s" direction="in"/>
49+ </method>
50 </interface>
51
52 <interface name="org.ayatana.bamf.matcher">
53
54=== modified file 'lib/libbamf/bamf-application.c'
55--- lib/libbamf/bamf-application.c 2013-07-20 14:57:45 +0000
56+++ lib/libbamf/bamf-application.c 2013-08-06 16:20:35 +0000
57@@ -52,6 +52,7 @@
58
59 enum
60 {
61+ DESKTOP_FILE_UPDATED,
62 WINDOW_ADDED,
63 WINDOW_REMOVED,
64
65@@ -408,6 +409,15 @@
66 }
67
68 static void
69+bamf_application_on_desktop_file_updated (BamfDBusItemApplication *proxy, const char *desktop_file, BamfApplication *self)
70+{
71+ g_free (self->priv->desktop_file);
72+ self->priv->desktop_file = g_strdup (desktop_file);
73+
74+ g_signal_emit (self, application_signals[DESKTOP_FILE_UPDATED], 0, desktop_file);
75+}
76+
77+static void
78 bamf_application_on_window_added (BamfDBusItemApplication *proxy, const char *path, BamfApplication *self)
79 {
80 BamfView *view;
81@@ -549,6 +559,9 @@
82
83 g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (priv->proxy), BAMF_DBUS_DEFAULT_TIMEOUT);
84
85+ g_signal_connect (priv->proxy, "desktop-file-updated",
86+ G_CALLBACK (bamf_application_on_desktop_file_updated), view);
87+
88 g_signal_connect (priv->proxy, "window-added",
89 G_CALLBACK (bamf_application_on_window_added), view);
90
91@@ -678,6 +691,14 @@
92
93 g_type_class_add_private (obj_class, sizeof (BamfApplicationPrivate));
94
95+ application_signals [DESKTOP_FILE_UPDATED] =
96+ g_signal_new (BAMF_APPLICATION_SIGNAL_DESKTOP_FILE_UPDATED,
97+ G_OBJECT_CLASS_TYPE (klass),
98+ 0,
99+ 0, NULL, NULL, NULL,
100+ G_TYPE_NONE, 1,
101+ G_TYPE_STRING);
102+
103 application_signals [WINDOW_ADDED] =
104 g_signal_new (BAMF_APPLICATION_SIGNAL_WINDOW_ADDED,
105 G_OBJECT_CLASS_TYPE (klass),
106
107=== modified file 'lib/libbamf/bamf-application.h'
108--- lib/libbamf/bamf-application.h 2013-06-18 14:46:15 +0000
109+++ lib/libbamf/bamf-application.h 2013-08-06 16:20:35 +0000
110@@ -50,8 +50,9 @@
111 #define BAMF_APPLICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
112 BAMF_TYPE_APPLICATION, BamfApplicationClass))
113
114-#define BAMF_APPLICATION_SIGNAL_WINDOW_ADDED "window-added"
115-#define BAMF_APPLICATION_SIGNAL_WINDOW_REMOVED "window-removed"
116+#define BAMF_APPLICATION_SIGNAL_DESKTOP_FILE_UPDATED "desktop-file-updated"
117+#define BAMF_APPLICATION_SIGNAL_WINDOW_ADDED "window-added"
118+#define BAMF_APPLICATION_SIGNAL_WINDOW_REMOVED "window-removed"
119
120 typedef struct _BamfApplication BamfApplication;
121 typedef struct _BamfApplicationClass BamfApplicationClass;
122
123=== modified file 'lib/libbamf/bamf-control.c'
124--- lib/libbamf/bamf-control.c 2013-06-08 13:54:06 +0000
125+++ lib/libbamf/bamf-control.c 2013-08-06 16:20:35 +0000
126@@ -37,6 +37,7 @@
127
128 #include <libbamf-private/bamf-private.h>
129 #include "bamf-control.h"
130+#include "bamf-view-private.h"
131
132 G_DEFINE_TYPE (BamfControl, bamf_control, G_TYPE_OBJECT);
133
134@@ -117,7 +118,7 @@
135 /**
136 * bamf_control_get_default:
137 *
138- * Returns: (transfer none): The default #BamfControl reference.
139+ * Returns: (transfer full): The default #BamfControl reference.
140 */
141 BamfControl *
142 bamf_control_get_default (void)
143@@ -125,7 +126,9 @@
144 if (BAMF_IS_CONTROL (default_control))
145 return g_object_ref (default_control);
146
147- return (default_control = g_object_new (BAMF_TYPE_CONTROL, NULL));
148+ default_control = g_object_new (BAMF_TYPE_CONTROL, NULL);
149+
150+ return default_control;
151 }
152
153 void
154@@ -137,9 +140,8 @@
155 g_return_if_fail (BAMF_IS_CONTROL (control));
156 priv = control->priv;
157
158- if (!_bamf_dbus_control_call_om_nom_nom_desktop_file_sync (priv->proxy,
159- desktop_file,
160- NULL, &error))
161+ if (!_bamf_dbus_control_call_insert_desktop_file_sync (priv->proxy, desktop_file,
162+ NULL, &error))
163 {
164 g_warning ("Failed to insert desktop file: %s", error->message);
165 g_error_free (error);
166@@ -147,6 +149,30 @@
167 }
168
169 void
170+bamf_control_create_local_desktop_file (BamfControl *control, BamfApplication *app)
171+{
172+ BamfControlPrivate *priv;
173+ const gchar *app_path;
174+ GError *error = NULL;
175+
176+ g_return_if_fail (BAMF_IS_CONTROL (control));
177+ g_return_if_fail (BAMF_IS_APPLICATION (app));
178+
179+ priv = control->priv;
180+ app_path = _bamf_view_get_path (BAMF_VIEW (app));
181+
182+ if (!app_path)
183+ return;
184+
185+ if (!_bamf_dbus_control_call_create_local_desktop_file_sync (priv->proxy, app_path,
186+ NULL, &error))
187+ {
188+ g_warning ("Failed to create local desktop file: %s", error->message);
189+ g_error_free (error);
190+ }
191+}
192+
193+void
194 bamf_control_register_application_for_pid (BamfControl *control,
195 const gchar *desktop_file,
196 gint32 pid)
197
198=== modified file 'lib/libbamf/bamf-control.h'
199--- lib/libbamf/bamf-control.h 2013-06-08 13:54:06 +0000
200+++ lib/libbamf/bamf-control.h 2013-08-06 16:20:35 +0000
201@@ -29,6 +29,7 @@
202 #define _BAMF_CONTROL_H_
203
204 #include <glib-object.h>
205+#include "bamf-application.h"
206
207 G_BEGIN_DECLS
208
209@@ -80,6 +81,9 @@
210 void bamf_control_insert_desktop_file (BamfControl *control,
211 const gchar *desktop_file);
212
213+void bamf_control_create_local_desktop_file (BamfControl *control,
214+ BamfApplication *application);
215+
216 void bamf_control_register_application_for_pid (BamfControl *control,
217 const gchar *desktop_file,
218 gint32 pid);
219
220=== modified file 'lib/libbamf/bamf-tab-source.c'
221--- lib/libbamf/bamf-tab-source.c 2013-06-13 22:20:25 +0000
222+++ lib/libbamf/bamf-tab-source.c 2013-08-06 16:20:35 +0000
223@@ -138,8 +138,8 @@
224 gchar *tab_id,
225 BamfTabSource *self)
226 {
227+ g_dbus_method_invocation_return_value (invocation, NULL);
228 bamf_tab_source_show_tab (self, tab_id, NULL);
229- g_dbus_method_invocation_return_value (invocation, NULL);
230
231 return TRUE;
232 }
233
234=== modified file 'src/bamf-application.c'
235--- src/bamf-application.c 2013-07-23 22:40:05 +0000
236+++ src/bamf-application.c 2013-08-06 16:20:35 +0000
237@@ -40,6 +40,7 @@
238 BamfDBusItemApplication *dbus_iface;
239 BamfApplicationType app_type;
240 BamfView * main_child;
241+ GCancellable * cancellable;
242 char * desktop_file;
243 GList * desktop_file_list;
244 char * wmclass;
245@@ -104,7 +105,7 @@
246
247 GKeyFile* key_file = g_key_file_new ();
248
249- if (!g_key_file_load_from_file (key_file, desktop_file, (GKeyFileFlags) 0, NULL))
250+ if (!g_key_file_load_from_file (key_file, desktop_file, G_KEY_FILE_NONE, NULL))
251 {
252 g_key_file_free (key_file);
253 return NULL;
254@@ -340,7 +341,7 @@
255
256 if (!icon)
257 {
258- icon = g_strdup (bamf_legacy_window_save_mini_icon (legacy_window));
259+ icon = bamf_legacy_window_save_mini_icon (legacy_window);
260
261 if (!icon)
262 {
263@@ -388,6 +389,9 @@
264 on_main_child_name_changed, application);
265 }
266
267+ g_signal_emit_by_name (application, "desktop-file-updated",
268+ application->priv->desktop_file);
269+
270 bamf_application_setup_icon_and_name (application, TRUE);
271 }
272
273@@ -414,6 +418,255 @@
274 return TRUE;
275 }
276
277+static GFile *
278+try_create_subdir (GFile *parent, const gchar *child_name, GCancellable *cancellable)
279+{
280+ GFile *child;
281+ GError *error = NULL;
282+
283+ child = g_file_get_child (parent, child_name);
284+ g_return_val_if_fail (G_IS_FILE (child), NULL);
285+
286+ g_file_make_directory_with_parents (child, cancellable, &error);
287+
288+ if (error)
289+ {
290+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
291+ {
292+ g_error ("Impossible to create `%s` directory: %s", child_name, error->message);
293+ g_clear_object (&child);
294+ }
295+
296+ g_error_free (error);
297+ }
298+
299+ return child;
300+}
301+
302+static GFile *
303+try_create_child (GFile *parent, const gchar *basename, const gchar *extension, GCancellable *cancellable)
304+{
305+ gchar *down, *child_name;
306+
307+ down = g_ascii_strdown (basename, -1);
308+ g_strdelimit (down, "/\\&%\"'!?`*.;:^|()= <>[]{}", '_');
309+
310+ child_name = g_strconcat (down, extension, NULL);
311+
312+ GFile *child = g_file_get_child (parent, child_name);
313+ g_return_val_if_fail (G_IS_FILE (child), NULL);
314+
315+ if (g_file_query_exists (child, cancellable))
316+ g_clear_object (&child);
317+
318+ g_free (child_name);
319+ g_free (down);
320+
321+ return child;
322+}
323+
324+gboolean
325+try_create_local_desktop_data (GFile *apps_dir, GFile *icons_dir, const char *basename,
326+ GFile **out_desktop_file, GFile **out_icon_file,
327+ GCancellable *cancellable)
328+{
329+ g_return_val_if_fail (out_desktop_file, NULL);
330+
331+ if (!apps_dir)
332+ {
333+ *out_desktop_file = NULL;
334+ g_warn_if_reached ();
335+ }
336+
337+ *out_desktop_file = try_create_child (apps_dir, basename, ".desktop", cancellable);
338+
339+ if (G_IS_FILE (*out_desktop_file))
340+ {
341+ if (G_IS_FILE (icons_dir) && out_icon_file)
342+ *out_icon_file = try_create_child (icons_dir, basename, ".png", cancellable);
343+
344+ return TRUE;
345+ }
346+
347+ return FALSE;
348+}
349+
350+gboolean
351+bamf_application_create_local_desktop_file (BamfApplication *self)
352+{
353+ BamfApplicationPrivate *priv;
354+ BamfLegacyWindow *window;
355+ GKeyFile *key_file;
356+ const gchar *name, *icon, *iclass, *nclass, *class, *exec;
357+ GFile *data_dir, *apps_dir, *icons_dir, *desktop_file, *icon_file, *mini_icon;
358+ GError *error = NULL;
359+
360+ g_return_val_if_fail (BAMF_IS_APPLICATION (self), FALSE);
361+ priv = self->priv;
362+
363+ if (priv->desktop_file || !BAMF_IS_WINDOW (priv->main_child))
364+ {
365+ return FALSE;
366+ }
367+
368+ window = bamf_window_get_window (BAMF_WINDOW (priv->main_child));
369+ exec = bamf_legacy_window_get_exec_string (window);
370+
371+ if (!exec)
372+ {
373+ return FALSE;
374+ }
375+
376+ data_dir = g_file_new_for_path (g_get_user_data_dir ());
377+ name = bamf_view_get_name (BAMF_VIEW (self));
378+ icon = bamf_view_get_icon (BAMF_VIEW (self));
379+ iclass = bamf_legacy_window_get_class_instance_name (window);
380+ nclass = bamf_legacy_window_get_class_name (window);
381+ mini_icon = bamf_legacy_window_get_saved_mini_icon (window);
382+
383+ apps_dir = try_create_subdir (data_dir, "applications", priv->cancellable);
384+ icons_dir = NULL;
385+
386+ if (!G_IS_FILE (apps_dir))
387+ {
388+ g_object_unref (data_dir);
389+ return FALSE;
390+ }
391+
392+ if (icon && G_IS_FILE (mini_icon))
393+ icons_dir = try_create_subdir (data_dir, "icons", priv->cancellable);
394+
395+ g_clear_object (&data_dir);
396+
397+ desktop_file = NULL;
398+ icon_file = NULL;
399+ class = (iclass) ? iclass : nclass;
400+
401+ if (class)
402+ {
403+ try_create_local_desktop_data (apps_dir, icons_dir, class,
404+ &desktop_file, &icon_file, priv->cancellable);
405+ }
406+
407+ if (!G_IS_FILE (desktop_file))
408+ {
409+ BamfMatcher *matcher = bamf_matcher_get_default ();
410+ gchar *trimmed_exec = bamf_matcher_get_trimmed_exec (matcher, exec);
411+ try_create_local_desktop_data (apps_dir, icons_dir, trimmed_exec,
412+ &desktop_file, &icon_file, priv->cancellable);
413+ g_free (trimmed_exec);
414+ }
415+
416+ if (!G_IS_FILE (desktop_file))
417+ {
418+ try_create_local_desktop_data (apps_dir, icons_dir, exec,
419+ &desktop_file, &icon_file, priv->cancellable);
420+ }
421+
422+ g_object_unref (apps_dir);
423+
424+ if (!G_IS_FILE (desktop_file))
425+ {
426+ g_critical ("Impossible to find a valid path where to save a .desktop file");
427+ g_clear_object (&icons_dir);
428+ g_clear_object (&icon_file);
429+ return FALSE;
430+ }
431+
432+ if (G_IS_FILE (icons_dir) && !G_IS_FILE (icon_file))
433+ {
434+ gchar *basename = g_file_get_basename (mini_icon);
435+ icon_file = try_create_child (icons_dir, basename+1, ".png", priv->cancellable);
436+ g_free (basename);
437+ }
438+
439+ g_clear_object (&icons_dir);
440+
441+ if (G_IS_FILE (icon_file))
442+ {
443+ if (!g_file_copy (mini_icon, icon_file, G_FILE_COPY_NONE,
444+ priv->cancellable, NULL, NULL, &error))
445+ {
446+ g_warning ("Impossible to copy icon to final destination: %s", error->message);
447+ g_clear_error (&error);
448+ g_clear_object (&icon_file);
449+ }
450+ }
451+
452+ key_file = g_key_file_new ();
453+ g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
454+ G_KEY_FILE_DESKTOP_KEY_TYPE,
455+ G_KEY_FILE_DESKTOP_TYPE_APPLICATION);
456+
457+ if (name)
458+ {
459+ g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
460+ G_KEY_FILE_DESKTOP_KEY_NAME, name);
461+ }
462+
463+ if (icon_file)
464+ {
465+ gchar *basename = g_file_get_basename (icon_file);
466+ g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
467+ G_KEY_FILE_DESKTOP_KEY_ICON, basename);
468+ bamf_view_set_icon (BAMF_VIEW (self), basename);
469+ g_free (basename);
470+ g_clear_object (&icon_file);
471+ }
472+ else if (icon)
473+ {
474+ g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
475+ G_KEY_FILE_DESKTOP_KEY_ICON, icon);
476+ }
477+
478+ g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
479+ G_KEY_FILE_DESKTOP_KEY_EXEC, exec);
480+
481+ g_key_file_set_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP,
482+ G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY, TRUE);
483+
484+ if (class)
485+ {
486+ g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
487+ G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS, class);
488+ }
489+
490+ gsize data_length = 0;
491+ gchar *data = g_key_file_to_data (key_file, &data_length, &error);
492+ g_key_file_free (key_file);
493+
494+ if (error)
495+ {
496+ g_critical ("Impossible to generate local desktop file: %s", error->message);
497+ g_clear_error (&error);
498+ g_clear_pointer (&data, g_free);
499+ }
500+
501+ if (data)
502+ {
503+ g_file_replace_contents (desktop_file, data, data_length, NULL, FALSE,
504+ G_FILE_CREATE_NONE, NULL, priv->cancellable, &error);
505+ g_free (data);
506+
507+ if (error)
508+ {
509+ g_critical ("Impossible to create local desktop file: %s", error->message);
510+ g_clear_error (&error);
511+ g_object_unref (desktop_file);
512+
513+ return FALSE;
514+ }
515+ }
516+
517+ gchar *desktop_path = g_file_get_path (desktop_file);
518+ g_object_unref (desktop_file);
519+
520+ bamf_application_set_desktop_file (self, desktop_path);
521+ g_free (desktop_path);
522+
523+ return TRUE;
524+}
525+
526 void
527 bamf_application_set_wmclass (BamfApplication *application,
528 const char *wmclass)
529@@ -888,6 +1141,13 @@
530 g_signal_emit_by_name (self->priv->dbus_iface, "window-removed", win_path);
531 }
532
533+static void
534+on_desktop_file_updated (BamfApplication *self, const gchar *file, gpointer _not_used)
535+{
536+ g_return_if_fail (BAMF_IS_APPLICATION (self));
537+ g_signal_emit_by_name (self->priv->dbus_iface, "desktop-file-updated", file);
538+}
539+
540 static gboolean
541 on_dbus_handle_show_stubs (BamfDBusItemApplication *interface,
542 GDBusMethodInvocation *invocation,
543@@ -1056,6 +1316,13 @@
544 priv->main_child = NULL;
545 }
546
547+ if (priv->cancellable)
548+ {
549+ g_cancellable_cancel (priv->cancellable);
550+ g_object_unref (priv->cancellable);
551+ priv->cancellable = NULL;
552+ }
553+
554 g_strfreev (priv->mimes);
555 priv->mimes = NULL;
556
557@@ -1085,6 +1352,8 @@
558 priv->app_type = BAMF_APPLICATION_SYSTEM;
559 priv->show_stubs = TRUE;
560
561+ priv->cancellable = g_cancellable_new ();
562+
563 /* Initializing the dbus interface */
564 priv->dbus_iface = _bamf_dbus_item_application_skeleton_new ();
565
566@@ -1092,6 +1361,7 @@
567 * interface */
568 g_signal_connect (self, "window-added", G_CALLBACK (on_window_added), NULL);
569 g_signal_connect (self, "window-removed", G_CALLBACK (on_window_removed), NULL);
570+ g_signal_connect (self, "desktop-file-updated", G_CALLBACK (on_desktop_file_updated), NULL);
571
572 /* Registering signal callbacks to reply to dbus method calls */
573 g_signal_connect (priv->dbus_iface, "handle-show-stubs",
574
575=== modified file 'src/bamf-application.h'
576--- src/bamf-application.h 2013-07-16 16:17:38 +0000
577+++ src/bamf-application.h 2013-08-06 16:20:35 +0000
578@@ -84,6 +84,8 @@
579 gboolean bamf_application_contains_similar_to_window (BamfApplication *app,
580 BamfWindow *window);
581
582+gboolean bamf_application_create_local_desktop_file (BamfApplication *app);
583+
584 const char * bamf_application_get_wmclass (BamfApplication *application);
585 void bamf_application_set_wmclass (BamfApplication *application,
586 const char *wmclass);
587
588=== modified file 'src/bamf-control.c'
589--- src/bamf-control.c 2013-06-08 13:54:06 +0000
590+++ src/bamf-control.c 2013-08-06 16:20:35 +0000
591@@ -19,9 +19,12 @@
592 */
593
594
595-#include "bamf-matcher.h"
596+#include <libbamf-private/bamf-private.h>
597+
598 #include "bamf-control.h"
599+#include "bamf-application.h"
600 #include "bamf-daemon.h"
601+#include "bamf-matcher.h"
602
603 G_DEFINE_TYPE (BamfControl, bamf_control, BAMF_DBUS_TYPE_CONTROL_SKELETON);
604 #define BAMF_CONTROL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, \
605@@ -96,20 +99,20 @@
606 GDBusMethodInvocation *invocation,
607 BamfControl *self)
608 {
609+ g_dbus_method_invocation_return_value (invocation, NULL);
610 bamf_control_quit (self);
611- g_dbus_method_invocation_return_value (invocation, NULL);
612
613 return TRUE;
614 }
615
616 static gboolean
617-on_dbus_handle_om_nom_nom_desktop_file (BamfDBusControl *interface,
618- GDBusMethodInvocation *invocation,
619- const gchar *desktop_file,
620- BamfControl *self)
621+on_dbus_handle_insert_desktop_file (BamfDBusControl *interface,
622+ GDBusMethodInvocation *invocation,
623+ const gchar *desktop_file,
624+ BamfControl *self)
625 {
626+ g_dbus_method_invocation_return_value (invocation, NULL);
627 bamf_control_insert_desktop_file (self, desktop_file);
628- g_dbus_method_invocation_return_value (invocation, NULL);
629
630 return TRUE;
631 }
632@@ -121,8 +124,20 @@
633 guint pid,
634 BamfControl *self)
635 {
636+ g_dbus_method_invocation_return_value (invocation, NULL);
637 bamf_control_register_application_for_pid (self, application, pid);
638+
639+ return TRUE;
640+}
641+
642+static gboolean
643+on_dbus_handle_create_local_desktop_file (BamfDBusControl *interface,
644+ GDBusMethodInvocation *invocation,
645+ const gchar *desktop_file,
646+ BamfControl *self)
647+{
648 g_dbus_method_invocation_return_value (invocation, NULL);
649+ bamf_control_create_local_desktop_file (self, desktop_file);
650
651 return TRUE;
652 }
653@@ -138,10 +153,16 @@
654 G_CALLBACK (on_dbus_handle_quit), self);
655
656 g_signal_connect (self, "handle-om-nom-nom-desktop-file",
657- G_CALLBACK (on_dbus_handle_om_nom_nom_desktop_file), self);
658+ G_CALLBACK (on_dbus_handle_insert_desktop_file), self);
659+
660+ g_signal_connect (self, "handle-insert-desktop-file",
661+ G_CALLBACK (on_dbus_handle_insert_desktop_file), self);
662
663 g_signal_connect (self, "handle-register-application-for-pid",
664 G_CALLBACK (on_dbus_handle_register_application_for_pid), self);
665+
666+ g_signal_connect (self, "handle-create-local-desktop-file",
667+ G_CALLBACK (on_dbus_handle_create_local_desktop_file), self);
668 }
669
670 static void
671@@ -191,6 +212,22 @@
672 bamf_matcher_load_desktop_file (matcher, path);
673 }
674
675+void
676+bamf_control_create_local_desktop_file (BamfControl *control, const char *app_path)
677+{
678+ BamfMatcher *matcher;
679+ BamfView *view;
680+
681+ g_return_if_fail (BAMF_IS_CONTROL (control));
682+ g_return_if_fail (app_path);
683+
684+ matcher = bamf_matcher_get_default ();
685+ view = bamf_matcher_get_view_by_path (matcher, app_path);
686+
687+ if (BAMF_IS_APPLICATION (view))
688+ bamf_application_create_local_desktop_file (BAMF_APPLICATION (view));
689+}
690+
691 static gboolean
692 bamf_control_on_quit (BamfControl *control)
693 {
694
695=== modified file 'src/bamf-control.h'
696--- src/bamf-control.h 2013-06-08 13:54:06 +0000
697+++ src/bamf-control.h 2013-08-06 16:20:35 +0000
698@@ -63,6 +63,9 @@
699 void bamf_control_insert_desktop_file (BamfControl *control,
700 const char *path);
701
702+void bamf_control_create_local_desktop_file (BamfControl *control,
703+ const char *desktop_file);
704+
705 void bamf_control_quit (BamfControl *control);
706
707 BamfControl * bamf_control_get_default (void);
708
709=== modified file 'src/bamf-legacy-window-test.c'
710--- src/bamf-legacy-window-test.c 2013-07-23 22:40:05 +0000
711+++ src/bamf-legacy-window-test.c 2013-08-06 16:20:35 +0000
712@@ -420,10 +420,10 @@
713 return g_hash_table_insert (self->hints, g_strdup (name), g_strdup (value));
714 }
715
716-static const char *
717+static char *
718 bamf_legacy_window_test_save_mini_icon (BamfLegacyWindow *window)
719 {
720- return BAMF_LEGACY_WINDOW_TEST (window)->icon;
721+ return g_strdup (BAMF_LEGACY_WINDOW_TEST (window)->icon);
722 }
723
724 static void
725
726=== modified file 'src/bamf-legacy-window.c'
727--- src/bamf-legacy-window.c 2013-07-23 22:40:05 +0000
728+++ src/bamf-legacy-window.c 2013-08-06 16:20:35 +0000
729@@ -51,7 +51,7 @@
730 struct _BamfLegacyWindowPrivate
731 {
732 WnckWindow * legacy_window;
733- gchar * mini_icon_path;
734+ GFile * mini_icon;
735 gchar * exec_string;
736 gboolean is_closed;
737 };
738@@ -260,7 +260,7 @@
739 return self->priv->exec_string;
740 }
741
742-const char *
743+char *
744 bamf_legacy_window_save_mini_icon (BamfLegacyWindow *self)
745 {
746 WnckWindow *window;
747@@ -274,16 +274,16 @@
748 if (BAMF_LEGACY_WINDOW_GET_CLASS (self)->save_mini_icon)
749 return BAMF_LEGACY_WINDOW_GET_CLASS (self)->save_mini_icon (self);
750
751- if (self->priv->mini_icon_path)
752+ if (self->priv->mini_icon)
753 {
754- if (g_file_test (self->priv->mini_icon_path, G_FILE_TEST_EXISTS))
755+ if (g_file_query_exists (self->priv->mini_icon, NULL))
756 {
757- return self->priv->mini_icon_path;
758+ return g_file_get_path (self->priv->mini_icon);
759 }
760 else
761 {
762- g_free (self->priv->mini_icon_path);
763- self->priv->mini_icon_path = NULL;
764+ g_object_unref (self->priv->mini_icon);
765+ self->priv->mini_icon = NULL;
766 }
767 }
768
769@@ -305,13 +305,21 @@
770
771 if (gdk_pixbuf_save_to_stream (pbuf, output, "png", NULL, NULL, NULL))
772 {
773- self->priv->mini_icon_path = g_file_get_path (tmp);
774+ self->priv->mini_icon = g_object_ref (tmp);
775 }
776
777 g_object_unref (iostream);
778 g_object_unref (tmp);
779
780- return self->priv->mini_icon_path;
781+ return g_file_get_path (self->priv->mini_icon);
782+}
783+
784+GFile *
785+bamf_legacy_window_get_saved_mini_icon (BamfLegacyWindow *self)
786+{
787+ g_return_val_if_fail (BAMF_IS_LEGACY_WINDOW (self), NULL);
788+
789+ return self->priv->mini_icon;
790 }
791
792 guint
793@@ -563,19 +571,14 @@
794 bamf_legacy_window_dispose (GObject *object)
795 {
796 BamfLegacyWindow *self;
797- GFile *file;
798 guint i;
799
800 self = BAMF_LEGACY_WINDOW (object);
801
802- if (self->priv->mini_icon_path)
803+ if (self->priv->mini_icon)
804 {
805- file = g_file_new_for_path (self->priv->mini_icon_path);
806- g_file_delete (file, NULL, NULL);
807- g_object_unref (file);
808-
809- g_free (self->priv->mini_icon_path);
810- self->priv->mini_icon_path = NULL;
811+ g_file_delete (self->priv->mini_icon, NULL, NULL);
812+ g_object_unref (self->priv->mini_icon);
813 }
814
815 if (self->priv->exec_string)
816
817=== modified file 'src/bamf-legacy-window.h'
818--- src/bamf-legacy-window.h 2013-07-23 22:40:05 +0000
819+++ src/bamf-legacy-window.h 2013-08-06 16:20:35 +0000
820@@ -76,8 +76,8 @@
821 const char * (*get_role) (BamfLegacyWindow *legacy_window);
822 const char * (*get_class_name) (BamfLegacyWindow *legacy_window);
823 const char * (*get_class_instance_name) (BamfLegacyWindow *legacy_window);
824- const char * (*save_mini_icon) (BamfLegacyWindow *legacy_window);
825 const char * (*get_exec_string) (BamfLegacyWindow *legacy_window);
826+ char * (*save_mini_icon) (BamfLegacyWindow *legacy_window);
827 char * (*get_process_name) (BamfLegacyWindow *legacy_window);
828 char * (*get_app_id) (BamfLegacyWindow *legacy_window);
829 char * (*get_unique_bus_name) (BamfLegacyWindow *legacy_window);
830@@ -147,10 +147,12 @@
831
832 const char * bamf_legacy_window_get_role (BamfLegacyWindow *self);
833
834-const char * bamf_legacy_window_save_mini_icon (BamfLegacyWindow *self);
835-
836 const char * bamf_legacy_window_get_exec_string (BamfLegacyWindow *self);
837
838+char * bamf_legacy_window_save_mini_icon (BamfLegacyWindow *self);
839+
840+GFile * bamf_legacy_window_get_saved_mini_icon (BamfLegacyWindow *self);
841+
842 char * bamf_legacy_window_get_process_name (BamfLegacyWindow *self);
843
844 BamfLegacyWindow * bamf_legacy_window_get_transient (BamfLegacyWindow *self);
845
846=== modified file 'src/bamf-matcher.c'
847--- src/bamf-matcher.c 2013-07-24 00:11:01 +0000
848+++ src/bamf-matcher.c 2013-08-06 16:20:35 +0000
849@@ -191,6 +191,31 @@
850 return NULL;
851 }
852
853+
854+BamfView *
855+bamf_matcher_get_view_by_path (BamfMatcher *self, const char *view_path)
856+{
857+ GList *l;
858+ BamfView *view;
859+
860+ g_return_val_if_fail (BAMF_IS_MATCHER (self), NULL);
861+
862+ for (l = self->priv->views; l; l = l->next)
863+ {
864+ view = l->data;
865+
866+ if (!BAMF_IS_VIEW (view))
867+ continue;
868+
869+ if (g_strcmp0 (bamf_view_get_path (view), view_path) == 0)
870+ {
871+ return view;
872+ }
873+ }
874+
875+ return NULL;
876+}
877+
878 static gboolean
879 emit_paths_changed (gpointer user_data)
880 {
881@@ -2835,8 +2860,8 @@
882 const char **favorites,
883 BamfMatcher *self)
884 {
885+ g_dbus_method_invocation_return_value (invocation, NULL);
886 bamf_matcher_register_favorites (self, favorites);
887- g_dbus_method_invocation_return_value (invocation, NULL);
888
889 return TRUE;
890 }
891@@ -2917,7 +2942,7 @@
892 webapp_tab = BAMF_UNITY_WEBAPPS_TAB (child);
893 legacy_window = bamf_unity_webapps_tab_get_legacy_window_for (webapp_tab);
894
895- if (is_web_app_window (legacy_window))
896+ if (legacy_window && is_web_app_window (legacy_window))
897 {
898 /* If we have a chromeless window, we remove the window from the
899 * application children list, so that it won't be duplicated in launcher */
900
901=== modified file 'src/bamf-matcher.h'
902--- src/bamf-matcher.h 2013-06-26 20:34:40 +0000
903+++ src/bamf-matcher.h 2013-08-06 16:20:35 +0000
904@@ -114,6 +114,8 @@
905 char * bamf_matcher_get_trimmed_exec (BamfMatcher *matcher,
906 const char *exec_string);
907
908+BamfView * bamf_matcher_get_view_by_path (BamfMatcher *matcher,
909+ const char *view_path);
910
911 BamfMatcher * bamf_matcher_get_default (void);
912
913
914=== modified file 'src/bamf-tab.c'
915--- src/bamf-tab.c 2013-06-13 17:08:07 +0000
916+++ src/bamf-tab.c 2013-08-06 16:20:35 +0000
917@@ -122,10 +122,9 @@
918 GDBusMethodInvocation *invocation,
919 BamfTab *self)
920 {
921+ g_dbus_method_invocation_return_value (invocation, NULL);
922 bamf_tab_raise (self);
923
924- g_dbus_method_invocation_return_value (invocation, NULL);
925-
926 return TRUE;
927 }
928
929@@ -134,10 +133,9 @@
930 GDBusMethodInvocation *invocation,
931 BamfTab *self)
932 {
933+ g_dbus_method_invocation_return_value (invocation, NULL);
934 bamf_tab_close (self);
935
936- g_dbus_method_invocation_return_value (invocation, NULL);
937-
938 return TRUE;
939 }
940
941
942=== modified file 'src/bamf-unity-webapps-application.c'
943--- src/bamf-unity-webapps-application.c 2013-06-26 11:54:58 +0000
944+++ src/bamf-unity-webapps-application.c 2013-08-06 16:20:35 +0000
945@@ -229,7 +229,16 @@
946 static gchar *
947 bamf_unity_webapps_application_get_stable_bus_name (BamfView *view)
948 {
949- return g_strdup_printf ("application%i", abs (g_str_hash (bamf_application_get_desktop_file (BAMF_APPLICATION (view)))));
950+ const gchar *desktop_file;
951+
952+ desktop_file = bamf_application_get_desktop_file (BAMF_APPLICATION (view));
953+
954+ if (desktop_file)
955+ {
956+ return g_strdup_printf ("application%i", abs (g_str_hash (desktop_file)));
957+ }
958+
959+ return g_strdup_printf ("application%p", view);
960 }
961
962
963
964=== modified file 'src/bamf-unity-webapps-observer.c'
965--- src/bamf-unity-webapps-observer.c 2013-07-16 16:19:42 +0000
966+++ src/bamf-unity-webapps-observer.c 2013-08-06 16:20:35 +0000
967@@ -155,7 +155,6 @@
968 unity_webapps_service_on_context_vanished (observer->priv->service, bamf_unity_webapps_observer_context_vanished, observer);
969
970 bamf_unity_webapps_observer_register_existing_contexts (observer, observer->priv->service);
971-
972 }
973
974 static void
975
976=== modified file 'tests/bamfdaemon/test-application.c'
977--- tests/bamfdaemon/test-application.c 2013-07-23 21:45:59 +0000
978+++ tests/bamfdaemon/test-application.c 2013-08-06 16:20:35 +0000
979@@ -328,7 +328,7 @@
980 g_assert (g_file_test (test_icon, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR));
981
982 key_file = g_key_file_new ();
983- g_key_file_load_from_file (key_file, test_app, (GKeyFileFlags)0, NULL);
984+ g_key_file_load_from_file (key_file, test_app, G_KEY_FILE_NONE, NULL);
985 g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON, test_icon);
986
987 gchar *key_data = g_key_file_to_data (key_file, NULL, NULL);
988@@ -358,7 +358,7 @@
989 g_assert (!g_file_test (invalid_test_icon, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR));
990
991 key_file = g_key_file_new ();
992- g_key_file_load_from_file (key_file, test_app, (GKeyFileFlags)0, NULL);
993+ g_key_file_load_from_file (key_file, test_app, G_KEY_FILE_NONE, NULL);
994 g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON, invalid_test_icon);
995
996 gchar *key_data = g_key_file_to_data (key_file, NULL, NULL);
997@@ -1099,6 +1099,218 @@
998 }
999
1000 static void
1001+test_desktop_app_create_local_desktop_file (void)
1002+{
1003+ BamfApplication *application;
1004+ BamfLegacyWindowTest *lwin;
1005+ BamfWindow *win;
1006+
1007+ application = bamf_application_new ();
1008+ bamf_application_set_desktop_file (application, DESKTOP_FILE);
1009+ lwin = bamf_legacy_window_test_new (20, "window", "test-bamf-class", "execution-binary");
1010+ win = bamf_window_new (BAMF_LEGACY_WINDOW (lwin));
1011+ bamf_view_add_child (BAMF_VIEW (application), BAMF_VIEW (win));
1012+
1013+ g_assert (!bamf_application_create_local_desktop_file (application));
1014+
1015+ g_object_unref (lwin);
1016+ g_object_unref (win);
1017+ g_object_unref (application);
1018+}
1019+
1020+static void
1021+test_desktopless_app_create_local_desktop_file_invalid_exec (void)
1022+{
1023+ BamfApplication *application;
1024+ BamfLegacyWindowTest *lwin;
1025+ BamfWindow *win;
1026+
1027+ application = bamf_application_new ();
1028+ lwin = bamf_legacy_window_test_new (20, "window", "test-bamf-class", NULL);
1029+ win = bamf_window_new (BAMF_LEGACY_WINDOW (lwin));
1030+ bamf_view_add_child (BAMF_VIEW (application), BAMF_VIEW (win));
1031+
1032+ g_assert (!bamf_application_create_local_desktop_file (application));
1033+
1034+ g_object_unref (lwin);
1035+ g_object_unref (win);
1036+ g_object_unref (application);
1037+}
1038+
1039+static void
1040+verify_application_desktop_file_content (BamfApplication *application)
1041+{
1042+ GKeyFile *key_file;
1043+ const gchar *desktop_file, *exec, *class;
1044+ gchar *str_value;
1045+ GError *error = NULL;
1046+ BamfView *main_child;
1047+ BamfLegacyWindow *main_window;
1048+
1049+ desktop_file = bamf_application_get_desktop_file (application);
1050+
1051+ key_file = g_key_file_new ();
1052+ g_key_file_load_from_file (key_file, desktop_file, G_KEY_FILE_NONE, NULL);
1053+
1054+ str_value = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
1055+ G_KEY_FILE_DESKTOP_KEY_TYPE, &error);
1056+ g_assert (!error);
1057+ g_assert_cmpstr (str_value, ==, G_KEY_FILE_DESKTOP_TYPE_APPLICATION);
1058+ g_clear_pointer (&str_value, g_free);
1059+
1060+ if (bamf_view_get_name (BAMF_VIEW (application)))
1061+ {
1062+ str_value = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
1063+ G_KEY_FILE_DESKTOP_KEY_NAME, &error);
1064+ g_assert (!error);
1065+ g_assert_cmpstr (str_value, ==, bamf_view_get_name (BAMF_VIEW (application)));
1066+ g_clear_pointer (&str_value, g_free);
1067+ }
1068+
1069+ if (bamf_view_get_icon (BAMF_VIEW (application)))
1070+ {
1071+ str_value = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
1072+ G_KEY_FILE_DESKTOP_KEY_ICON, &error);
1073+ g_assert (!error);
1074+ g_assert_cmpstr (str_value, ==, bamf_view_get_icon (BAMF_VIEW (application)));
1075+ g_clear_pointer (&str_value, g_free);
1076+ }
1077+
1078+ main_child = bamf_application_get_main_child (application);
1079+ main_window = bamf_window_get_window (BAMF_WINDOW (main_child));
1080+ exec = bamf_legacy_window_get_exec_string (main_window);
1081+
1082+ str_value = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
1083+ G_KEY_FILE_DESKTOP_KEY_EXEC, &error);
1084+ g_assert (!error);
1085+ g_assert_cmpstr (str_value, ==, exec);
1086+ g_clear_pointer (&str_value, g_free);
1087+
1088+ g_assert (g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP,
1089+ G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY, &error));
1090+ g_assert (!error);
1091+
1092+ class = bamf_legacy_window_get_class_instance_name (main_window);
1093+ class = class ? class : bamf_legacy_window_get_class_name (main_window);
1094+
1095+ if (class)
1096+ {
1097+ str_value = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
1098+ G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS, &error);
1099+ g_assert (!error);
1100+ g_assert_cmpstr (str_value, ==, class);
1101+ g_clear_pointer (&str_value, g_free);
1102+ }
1103+
1104+ g_key_file_free (key_file);
1105+}
1106+
1107+static void
1108+test_desktopless_app_create_local_desktop_file_using_instance_class_basename (void)
1109+{
1110+ BamfApplication *application;
1111+ BamfLegacyWindowTest *lwin;
1112+ BamfWindow *win;
1113+ const gchar *desktop_path;
1114+
1115+ application = bamf_application_new ();
1116+ lwin = bamf_legacy_window_test_new (20, "window", NULL, "awesome --exec");
1117+ bamf_legacy_window_test_set_wmclass (lwin, "application-class", "instance-class");
1118+ win = bamf_window_new (BAMF_LEGACY_WINDOW (lwin));
1119+ bamf_view_add_child (BAMF_VIEW (application), BAMF_VIEW (win));
1120+
1121+ g_assert (bamf_application_create_local_desktop_file (application));
1122+
1123+ desktop_path = bamf_application_get_desktop_file (application);
1124+ g_assert (desktop_path);
1125+ g_assert (g_str_has_suffix (desktop_path, "instance-class.desktop"));
1126+ g_assert (g_file_test (desktop_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR));
1127+ verify_application_desktop_file_content (application);
1128+
1129+ g_object_unref (lwin);
1130+ g_object_unref (win);
1131+ g_object_unref (application);
1132+}
1133+
1134+static void
1135+test_desktopless_app_create_local_desktop_file_using_name_class_basename (void)
1136+{
1137+ BamfApplication *application;
1138+ BamfLegacyWindowTest *lwin;
1139+ BamfWindow *win;
1140+ const gchar *desktop_path;
1141+
1142+ application = bamf_application_new ();
1143+ lwin = bamf_legacy_window_test_new (20, "window", "Application!/?Class", "awesome --exec");
1144+ win = bamf_window_new (BAMF_LEGACY_WINDOW (lwin));
1145+ bamf_view_add_child (BAMF_VIEW (application), BAMF_VIEW (win));
1146+
1147+ g_assert (bamf_application_create_local_desktop_file (application));
1148+
1149+ desktop_path = bamf_application_get_desktop_file (application);
1150+ g_assert (desktop_path);
1151+ g_assert (g_str_has_suffix (desktop_path, "application___class.desktop"));
1152+ g_assert (g_file_test (desktop_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR));
1153+ verify_application_desktop_file_content (application);
1154+
1155+ g_object_unref (lwin);
1156+ g_object_unref (win);
1157+ g_object_unref (application);
1158+}
1159+
1160+static void
1161+test_desktopless_app_create_local_desktop_file_using_exec_basename (void)
1162+{
1163+ BamfApplication *application;
1164+ BamfLegacyWindowTest *lwin;
1165+ BamfWindow *win;
1166+ const gchar *desktop_path;
1167+
1168+ application = bamf_application_new ();
1169+ lwin = bamf_legacy_window_test_new (20, "window", NULL, "awesome --exec");
1170+ win = bamf_window_new (BAMF_LEGACY_WINDOW (lwin));
1171+ bamf_view_add_child (BAMF_VIEW (application), BAMF_VIEW (win));
1172+
1173+ g_assert (bamf_application_create_local_desktop_file (application));
1174+
1175+ desktop_path = bamf_application_get_desktop_file (application);
1176+ g_assert (desktop_path);
1177+ g_assert (g_str_has_suffix (desktop_path, "awesome.desktop"));
1178+ g_assert (g_file_test (desktop_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR));
1179+ verify_application_desktop_file_content (application);
1180+
1181+ g_object_unref (lwin);
1182+ g_object_unref (win);
1183+ g_object_unref (application);
1184+}
1185+
1186+static void
1187+test_desktopless_app_create_local_desktop_file_using_trimmed_exec_basename (void)
1188+{
1189+ BamfApplication *application;
1190+ BamfLegacyWindowTest *lwin;
1191+ BamfWindow *win;
1192+ const gchar *desktop_path;
1193+
1194+ application = bamf_application_new ();
1195+ lwin = bamf_legacy_window_test_new (20, "window", NULL, "python awesome-script.py");
1196+ win = bamf_window_new (BAMF_LEGACY_WINDOW (lwin));
1197+ bamf_view_add_child (BAMF_VIEW (application), BAMF_VIEW (win));
1198+
1199+ g_assert (bamf_application_create_local_desktop_file (application));
1200+
1201+ desktop_path = bamf_application_get_desktop_file (application);
1202+ g_assert (desktop_path);
1203+ g_assert (g_str_has_suffix (desktop_path, "awesome-script.desktop"));
1204+ g_assert (g_file_test (desktop_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR));
1205+ verify_application_desktop_file_content (application);
1206+
1207+ g_object_unref (lwin);
1208+ g_object_unref (win);
1209+ g_object_unref (application);
1210+}
1211+
1212+static void
1213 test_contain_similar_to_window (void)
1214 {
1215 BamfApplication *application;
1216@@ -1202,6 +1414,7 @@
1217 g_test_add_func (DOMAIN"/DesktopFile/MainChild", test_desktop_app_main_child);
1218 g_test_add_func (DOMAIN"/DesktopFile/MainChild/NotMatchEmblems", test_desktop_app_main_child_doesnt_match_emblems);
1219 g_test_add_func (DOMAIN"/DesktopFile/MainChild/NotUpdatesEmblems", test_desktop_app_main_child_doesnt_update_emblems);
1220+ g_test_add_func (DOMAIN"/DesktopFile/CreateLocalDesktopFile", test_desktop_app_create_local_desktop_file);
1221 g_test_add_func (DOMAIN"/DesktopLess/Icon/ClassName", test_icon_class_name);
1222 g_test_add_func (DOMAIN"/DesktopLess/Icon/Exec", test_icon_exec_string);
1223 g_test_add_func (DOMAIN"/DesktopLess/Icon/Embedded", test_icon_embedded);
1224@@ -1215,6 +1428,11 @@
1225 g_test_add_func (DOMAIN"/DesktopLess/MainChild/NormalPriority", test_app_main_child_normal_priority);
1226 g_test_add_func (DOMAIN"/DesktopLess/MainChild/Removal", test_app_main_child_on_window_removal);
1227 g_test_add_func (DOMAIN"/DesktopLess/MainChild/ReplaceOnRemoval", test_app_main_child_on_window_replace_on_removal);
1228+ g_test_add_func (DOMAIN"/DesktopLess/CreateLocalDesktopFile/InvalidExec", test_desktopless_app_create_local_desktop_file_invalid_exec);
1229+ g_test_add_func (DOMAIN"/DesktopLess/CreateLocalDesktopFile/UsingClassInstance", test_desktopless_app_create_local_desktop_file_using_instance_class_basename);
1230+ g_test_add_func (DOMAIN"/DesktopLess/CreateLocalDesktopFile/UsingClassName", test_desktopless_app_create_local_desktop_file_using_name_class_basename);
1231+ g_test_add_func (DOMAIN"/DesktopLess/CreateLocalDesktopFile/UsingExec", test_desktopless_app_create_local_desktop_file_using_exec_basename);
1232+ g_test_add_func (DOMAIN"/DesktopLess/CreateLocalDesktopFile/UsingTrimmedExec", test_desktopless_app_create_local_desktop_file_using_trimmed_exec_basename);
1233 g_test_add_func (DOMAIN"/ManagesXid", test_manages_xid);
1234 g_test_add_func (DOMAIN"/GetWindow", test_get_window);
1235 g_test_add_func (DOMAIN"/Xids", test_get_xids);
1236
1237=== modified file 'tests/bamfdaemon/test-bamf.c'
1238--- tests/bamfdaemon/test-bamf.c 2013-07-16 14:46:37 +0000
1239+++ tests/bamfdaemon/test-bamf.c 2013-08-06 16:20:35 +0000
1240@@ -82,6 +82,15 @@
1241 {
1242 GMainLoop *loop;
1243
1244+ GFile *tmp_dir;
1245+ gchar *tmp_path;
1246+
1247+ tmp_path = g_dir_make_tmp (".bamfhomedataXXXXXX", NULL);
1248+ tmp_dir = g_file_new_for_path (tmp_path);
1249+ g_file_make_directory (tmp_dir, NULL, NULL);
1250+ g_setenv ("XDG_DATA_HOME", tmp_path, TRUE);
1251+ g_free (tmp_path);
1252+
1253 gtk_init (&argc, &argv);
1254 g_test_init (&argc, &argv, NULL);
1255 glibtop_init ();
1256@@ -99,5 +108,8 @@
1257
1258 g_main_loop_run (loop);
1259
1260+ g_file_delete (tmp_dir, NULL, NULL);
1261+ g_object_unref (tmp_dir);
1262+
1263 return result;
1264 }
1265
1266=== modified file 'tests/bamfdaemon/test-matcher.c'
1267--- tests/bamfdaemon/test-matcher.c 2013-07-24 00:11:46 +0000
1268+++ tests/bamfdaemon/test-matcher.c 2013-08-06 16:20:35 +0000
1269@@ -1176,6 +1176,42 @@
1270 }
1271 }
1272
1273+static void
1274+test_get_view_by_path (void)
1275+{
1276+ BamfMatcher *matcher;
1277+ BamfLegacyScreen *screen;
1278+ BamfLegacyWindowTest *lwin;
1279+ BamfApplication *app;
1280+ BamfWindow *win;
1281+ GList *app_children;
1282+ guint32 xid;
1283+
1284+ screen = bamf_legacy_screen_get_default();
1285+ matcher = bamf_matcher_get_default ();
1286+
1287+ cleanup_matcher_tables (matcher);
1288+ export_matcher_on_bus (matcher);
1289+
1290+ xid = g_random_int ();
1291+ lwin = bamf_legacy_window_test_new (xid, "Window", NULL, NULL);
1292+ _bamf_legacy_screen_open_test_window (screen, lwin);
1293+
1294+ app = bamf_matcher_get_application_by_xid (matcher, xid);
1295+ const char *app_path = bamf_view_get_path (BAMF_VIEW (app));
1296+ g_assert (app == BAMF_APPLICATION (bamf_matcher_get_view_by_path (matcher, app_path)));
1297+
1298+ app_children = bamf_view_get_children (BAMF_VIEW (app));
1299+ g_assert (app_children);
1300+
1301+ win = BAMF_WINDOW (app_children->data);
1302+ const char *win_path = bamf_view_get_path (BAMF_VIEW (win));
1303+ g_assert (win == BAMF_WINDOW (bamf_matcher_get_view_by_path (matcher, win_path)));
1304+
1305+ g_object_unref (matcher);
1306+ g_object_unref (screen);
1307+}
1308+
1309 /* Initialize test suite */
1310
1311 void
1312@@ -1187,6 +1223,7 @@
1313 g_test_add_func (DOMAIN"/AutostartDesktopFile/User", test_autostart_desktop_file_user);
1314 g_test_add_func (DOMAIN"/AutostartDesktopFile/System", test_autostart_desktop_file_system);
1315 g_test_add_func (DOMAIN"/ExecStringTrimming", test_trim_exec_string);
1316+ g_test_add_func (DOMAIN"/GetViewByPath", test_get_view_by_path);
1317 g_test_add_func (DOMAIN"/LoadDesktopFile", test_load_desktop_file);
1318 g_test_add_func (DOMAIN"/LoadDesktopFile/Autostart", test_load_desktop_file_autostart);
1319 g_test_add_func (DOMAIN"/LoadDesktopFile/NoDisplay/SameID", test_load_desktop_file_no_display_has_lower_prio_same_id);

Subscribers

People subscribed via source and target branches