Merge lp:~3v1n0/bamf/javaws-matching-0.3 into lp:bamf/0.3

Proposed by Marco Trevisan (Treviño) on 2013-01-10
Status: Merged
Approved by: Brandon Schaefer on 2013-01-10
Approved revision: 496
Merged at revision: 496
Proposed branch: lp:~3v1n0/bamf/javaws-matching-0.3
Merge into: lp:bamf/0.3
Diff against target: 1011 lines (+448/-211)
9 files modified
src/bamf-legacy-screen.c (+8/-27)
src/bamf-legacy-window.c (+2/-2)
src/bamf-matcher-private.h (+1/-0)
src/bamf-matcher.c (+193/-182)
tests/bamfdaemon/Makefile.am (+1/-0)
tests/bamfdaemon/data/gnome-control-center.desktop (+9/-0)
tests/bamfdaemon/data/gnome-display-panel.desktop (+10/-0)
tests/bamfdaemon/data/gnome-mouse-panel.desktop (+10/-0)
tests/bamfdaemon/test-matcher.c (+214/-0)
To merge this branch: bzr merge lp:~3v1n0/bamf/javaws-matching-0.3
Reviewer Review Type Date Requested Status
Brandon Schaefer (community) 2013-01-10 Approve on 2013-01-10
Review via email: mp+142618@code.launchpad.net

Commit message

BamfMatcher: Don't associate .desktopless applications with different exec string, fix JavaWS apps

Description of the change

Don't associate to the similar application, windows that have different execution path. Also add some rules to fix Java Web Start applications matching.

To post a comment you must log in.
lp:~3v1n0/bamf/javaws-matching-0.3 updated on 2013-01-10
496. By Marco Trevisan (Treviño) on 2013-01-10

Backport JavaWS fixes

Brandon Schaefer (brandontschaefer) wrote :

\o/ LGTM!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/bamf-legacy-screen.c'
2--- src/bamf-legacy-screen.c 2012-08-21 22:01:48 +0000
3+++ src/bamf-legacy-screen.c 2013-01-10 00:25:25 +0000
4@@ -210,7 +210,6 @@
5 BamfLegacyScreen *self;
6 GList *l;
7 guint xid_a, xid_b;
8- guint idx_a, idx_b;
9
10 g_return_val_if_fail (BAMF_IS_LEGACY_SCREEN (data), 1);
11 self = BAMF_LEGACY_SCREEN (data);
12@@ -218,36 +217,18 @@
13 xid_a = bamf_legacy_window_get_xid (BAMF_LEGACY_WINDOW (a));
14 xid_b = bamf_legacy_window_get_xid (BAMF_LEGACY_WINDOW (b));
15
16- gboolean idx_a_found = FALSE;
17- gboolean idx_b_found = FALSE;
18- idx_a = 0;
19- idx_b = 0;
20-
21 for (l = wnck_screen_get_windows_stacked (self->priv->legacy_screen); l; l = l->next)
22 {
23 gulong legacy_xid = wnck_window_get_xid (WNCK_WINDOW (l->data));
24
25- if (!idx_a_found)
26- {
27- if (xid_a != legacy_xid)
28- idx_a++;
29- else
30- idx_a_found = TRUE;
31- }
32-
33- if (!idx_b_found)
34- {
35- if (xid_b != legacy_xid)
36- idx_b++;
37- else
38- idx_b_found = TRUE;
39- }
40-
41- if (idx_a_found && idx_b_found)
42- break;
43+ if (legacy_xid == xid_a)
44+ return -1;
45+
46+ if (legacy_xid == xid_b)
47+ return 1;
48 }
49
50- return (idx_a < idx_b) ? -1 : 1;
51+ return 0;
52 }
53
54 static void
55@@ -300,11 +281,11 @@
56 }
57 }
58
59- WnckWindow *legacy_window = wnck_window_get(xid);
60+ WnckWindow *legacy_window = wnck_window_get (xid);
61
62 if (WNCK_IS_WINDOW (legacy_window))
63 {
64- handle_window_opened(NULL, legacy_window, self);
65+ handle_window_opened (NULL, legacy_window, self);
66 }
67 }
68
69
70=== modified file 'src/bamf-legacy-window.c'
71--- src/bamf-legacy-window.c 2012-10-09 09:13:30 +0000
72+++ src/bamf-legacy-window.c 2013-01-10 00:25:25 +0000
73@@ -498,9 +498,9 @@
74 guint xid = bamf_legacy_window_get_xid (self);
75
76 /* Adding a weak ref to this object, causes to get notified after the object
77- * destruction, so once this BamfLegacyWindow has been closed and drestroyed
78+ * destruction, so once this BamfLegacyWindow has been closed and destroyed
79 * the handle_destroy_notify() function will be called, and that will
80- * provide to iniject another window like this one to the BamfLegacyScreen */
81+ * provide to inject another window like this one to the BamfLegacyScreen */
82 g_object_weak_ref (G_OBJECT (self), (GWeakNotify) handle_destroy_notify,
83 GUINT_TO_POINTER (xid));
84
85
86=== modified file 'src/bamf-matcher-private.h'
87--- src/bamf-matcher-private.h 2012-08-19 22:24:54 +0000
88+++ src/bamf-matcher-private.h 2013-01-10 00:25:25 +0000
89@@ -49,5 +49,6 @@
90
91 BamfApplication * bamf_matcher_get_application_by_desktop_file (BamfMatcher *self, const char *desktop_file);
92 BamfApplication * bamf_matcher_get_application_by_xid (BamfMatcher *self, guint xid);
93+char * bamf_matcher_get_trimmed_exec (BamfMatcher *self, const char *exec);
94
95 #endif
96
97=== modified file 'src/bamf-matcher.c'
98--- src/bamf-matcher.c 2012-11-05 10:23:27 +0000
99+++ src/bamf-matcher.c 2013-01-10 00:25:25 +0000
100@@ -52,6 +52,22 @@
101 static BamfMatcher *static_matcher;
102 static guint matcher_signals[LAST_SIGNAL] = { 0 };
103
104+// Prefixes to be ignored in exec strings
105+const gchar* EXEC_BAD_PREFIXES[] =
106+{
107+ "^gksu(do)?$", "^sudo$", "^su-to-root$", "^amdxdg-su$", "^java(ws)?$",
108+ "^mono$", "^ruby$", "^padsp$", "^aoss$", "^python(\\d.\\d)?$", "^(ba)?sh$",
109+ "^perl$", "^env$", "^xdg-open$",
110+ /* javaws strings: */ "^net\\.sourceforge\\.jnlp\\.runtime\\.Boot$", "^rt.jar$"
111+};
112+
113+// Prefixes that must be considered starting point of exec strings
114+const gchar* EXEC_GOOD_PREFIXES[] =
115+{
116+ "^gnome-control-center$", "^libreoffice$", "^ooffice$", "^wine$", "^steam$",
117+ "^sol$"
118+};
119+
120 static void
121 on_view_active_changed (BamfView *view, gboolean active, BamfMatcher *matcher)
122 {
123@@ -215,7 +231,8 @@
124 return FALSE;
125 }
126
127-static void bamf_matcher_prepare_path_change (BamfMatcher *self, const gchar *desktop_file, ViewChangeType change_type)
128+static void
129+bamf_matcher_prepare_path_change (BamfMatcher *self, const gchar *desktop_file, ViewChangeType change_type)
130 {
131 BamfMatcherPrivate *priv;
132 BamfApplication *app;
133@@ -252,12 +269,6 @@
134 }
135
136 static void
137-on_view_closed (BamfView *view, BamfMatcher *self)
138-{
139- bamf_matcher_unregister_view (self, view);
140-}
141-
142-static void
143 bamf_matcher_register_view_stealing_ref (BamfMatcher *self, BamfView *view)
144 {
145 const char *path, *type;
146@@ -268,8 +279,8 @@
147 path = bamf_view_export_on_bus (view, connection);
148 type = bamf_view_get_view_type (view);
149
150- g_signal_connect (G_OBJECT (view), "closed-internal",
151- (GCallback) on_view_closed, self);
152+ g_signal_connect_swapped (G_OBJECT (view), "closed-internal",
153+ (GCallback) bamf_matcher_unregister_view, self);
154 g_signal_connect (G_OBJECT (view), "active-changed",
155 (GCallback) on_view_active_changed, self);
156
157@@ -300,7 +311,7 @@
158
159 g_signal_emit_by_name (self, "view-closed", path, type);
160
161- g_signal_handlers_disconnect_by_func (G_OBJECT (view), on_view_closed, self);
162+ g_signal_handlers_disconnect_by_func (G_OBJECT (view), bamf_matcher_unregister_view, self);
163 g_signal_handlers_disconnect_by_func (G_OBJECT (view), on_view_active_changed, self);
164
165 if (BAMF_IS_APPLICATION (view))
166@@ -352,7 +363,7 @@
167 else if (g_str_has_suffix (name, "LibreOffice Calc"))
168 {
169 binary = "libreoffice";
170- parameter = "calc";
171+ parameter = "calc";
172 }
173 else if (g_str_has_suffix (name, "LibreOffice Impress"))
174 {
175@@ -470,60 +481,72 @@
176 if (!binary)
177 return NULL;
178
179- const char *sufix = NULL;
180-
181- if (g_strcmp0 (binary, "libreoffice") == 0)
182- sufix = " %U";
183- else if (g_strcmp0 (binary, "ooffice") == 0)
184- sufix = " %F";
185-
186- GList *l;
187- if (!parameter)
188- exec = g_strconcat (binary, sufix, NULL);
189- else
190- exec = g_strconcat (binary, " --", parameter, sufix, NULL);
191-
192- l = g_hash_table_lookup (self->priv->desktop_file_table, exec);
193- g_free (exec);
194-
195- if (!l && parameter)
196+ GList *l = NULL;
197+
198+ if (parameter)
199 {
200- exec = g_strconcat (binary, " -", parameter, sufix, NULL);
201-
202+ exec = g_strconcat (binary, " --", parameter, NULL);
203 l = g_hash_table_lookup (self->priv->desktop_file_table, exec);
204 g_free (exec);
205+
206+ if (!l)
207+ {
208+ exec = g_strconcat (binary, " -", parameter, NULL);
209+ l = g_hash_table_lookup (self->priv->desktop_file_table, exec);
210+ g_free (exec);
211+
212+ if (!l)
213+ {
214+ exec = g_strconcat (binary, "-", parameter, NULL);
215+ l = g_hash_table_lookup (self->priv->desktop_id_table, exec);
216+ g_free (exec);
217+ }
218+ }
219+ }
220+ else
221+ {
222+ l = g_hash_table_lookup (self->priv->desktop_file_table, binary);
223 }
224
225 return (l ? (char *) l->data : NULL);
226 }
227
228 /* Attempts to return the binary name for a particular execution string */
229-static char *
230-trim_exec_string (BamfMatcher * self, char * execString)
231+char *
232+bamf_matcher_get_trimmed_exec (BamfMatcher * self, const char * exec_string)
233 {
234- gchar *result = NULL, *exec = NULL, *part = NULL, *tmp = NULL;
235+ gchar *result = NULL, *part, *tmp;
236 gchar **parts;
237- gint i, j;
238- gboolean regexFail;
239- gboolean goodPrefix = FALSE;
240+ gint i, j, parts_size;
241+ gboolean bad_prefix;
242+ gboolean good_prefix = FALSE;
243+ gboolean double_parsed = FALSE;
244 GRegex *regex;
245
246- if (!execString || (execString && execString[0] == '\0'))
247+ if (!exec_string || exec_string[0] == '\0')
248 return NULL;
249
250- exec = g_utf8_casefold (execString, -1);
251- parts = g_strsplit (exec, " ", 0);
252+ if (!g_shell_parse_argv (exec_string, &parts_size, &parts, NULL))
253+ return g_strdup (exec_string);
254
255- i = 0;
256- while (parts[i] != NULL)
257+ for (i = 0; i < parts_size; ++i)
258 {
259 part = parts[i];
260+ if (*part == '%' || g_utf8_strrchr (part, -1, '='))
261+ continue;
262
263- if (part[0] != '-')
264+ if (*part != '-' || good_prefix)
265 {
266- if (goodPrefix)
267- {
268- gchar *tmp = g_strconcat (result, " ", part, NULL);
269+ if (!result)
270+ {
271+ tmp = g_utf8_strrchr (part, -1, G_DIR_SEPARATOR);
272+ if (tmp)
273+ part = tmp + 1;
274+ }
275+
276+ if (good_prefix)
277+ {
278+ tmp = g_strconcat (result, " ", part, NULL);
279 g_free (result);
280 result = tmp;
281 }
282@@ -534,113 +557,81 @@
283 regex = g_array_index (self->priv->good_prefixes, GRegex *, j);
284 if (g_regex_match (regex, part, 0, NULL))
285 {
286- goodPrefix = TRUE;
287- result = g_strdup (part);
288+ good_prefix = TRUE;
289+ result = g_ascii_strdown (part, -1);
290 break;
291 }
292 }
293- }
294-
295- if (!goodPrefix)
296- {
297- tmp = g_utf8_strrchr (part, -1, G_DIR_SEPARATOR);
298- if (tmp)
299- part = tmp + 1;
300-
301- regexFail = FALSE;
302+
303+ if (good_prefix)
304+ continue;
305+
306+ bad_prefix = FALSE;
307 for (j = 0; j < self->priv->bad_prefixes->len; j++)
308 {
309 regex = g_array_index (self->priv->bad_prefixes, GRegex *, j);
310 if (g_regex_match (regex, part, 0, NULL))
311 {
312- regexFail = TRUE;
313+ bad_prefix = TRUE;
314 break;
315 }
316 }
317
318- if (!regexFail)
319+ if (!bad_prefix)
320 {
321- result = g_strdup (part);
322+ if (!double_parsed && g_utf8_strrchr (part, -1, ' '))
323+ {
324+ /* If the current exec_string has an empty char,
325+ * we double check it again to parse scripts:
326+ * For example strings like 'sh -c "foo || bar"' */
327+ gchar **old_parts = parts;
328+
329+ if (g_shell_parse_argv (part, &parts_size, &parts, NULL))
330+ {
331+ // Make the loop to restart!
332+ g_strfreev (old_parts);
333+ i = -1;
334+ continue;
335+ }
336+
337+ double_parsed = TRUE;
338+ }
339+
340+ result = g_ascii_strdown (part, -1);
341 break;
342 }
343 }
344 }
345- else if (goodPrefix)
346- {
347- break;
348- }
349-
350- i++;
351 }
352
353 if (!result)
354 {
355- result = g_strdup (execString);
356+ if (parts_size > 0)
357+ {
358+ tmp = g_utf8_strrchr (parts[0], -1, G_DIR_SEPARATOR);
359+ if (tmp)
360+ exec_string = tmp + 1;
361+ }
362+
363+ result = g_strdup (exec_string);
364 }
365 else
366 {
367 tmp = result;
368-
369- regex = g_regex_new ("((\\.|-)bin|\\.py)$", 0, 0, NULL);
370+
371+ regex = g_regex_new ("(\\.bin|\\.py|\\.pl)$", 0, 0, NULL);
372 result = g_regex_replace_literal (regex, result, -1, 0, "", 0, NULL);
373-
374+
375 g_free (tmp);
376 g_regex_unref (regex);
377 }
378
379- g_free (exec);
380 g_strfreev (parts);
381
382 return result;
383 }
384
385 static GArray *
386-bad_prefix_strings (void)
387-{
388- GArray *arr = g_array_new (FALSE, TRUE, sizeof (char *));
389-
390- char *str = "^gksu(do)?$";
391- g_array_append_val (arr, str);
392-
393- str = "^sudo$";
394- g_array_append_val (arr, str);
395-
396- str = "^java$";
397- g_array_append_val (arr, str);
398-
399- str = "^mono$";
400- g_array_append_val (arr, str);
401-
402- str = "^ruby$";
403- g_array_append_val (arr, str);
404-
405- str = "^padsp$";
406- g_array_append_val (arr, str);
407-
408- str = "^aoss$";
409- g_array_append_val (arr, str);
410-
411- str = "^python(\\d.\\d)?$";
412- g_array_append_val (arr, str);
413-
414- str = "^(ba)?sh$";
415- g_array_append_val (arr, str);
416-
417- return arr;
418-}
419-
420-static GArray *
421-good_prefix_strings (void)
422-{
423- GArray *arr = g_array_new (FALSE, TRUE, sizeof (char *));
424-
425- char *str = "^gnome-control-center$";
426- g_array_append_val (arr, str);
427-
428- return arr;
429-}
430-
431-static GArray *
432 pid_parent_tree (BamfMatcher *self, gint pid)
433 {
434 BamfMatcherPrivate *priv;
435@@ -682,15 +673,6 @@
436 }
437
438 static gboolean
439-exec_string_should_be_processed (const char *exec)
440-{
441- if (!exec)
442- return TRUE;
443-
444- return !g_str_has_prefix (exec, "ooffice") && !g_str_has_prefix (exec, "libreoffice");
445-}
446-
447-static gboolean
448 is_desktop_folder_item (const char *desktop_file_path, gssize max_len)
449 {
450 gsize len;
451@@ -854,18 +836,15 @@
452 return;
453 }
454
455- if (exec_string_should_be_processed (exec))
456- {
457- /**
458- * Set of nasty hacks which should be removed some day. We wish to keep the full exec
459- * strings so we can do nasty matching hacks later. A very very evil thing indeed. However this
460- * helps hack around applications that run in the same process cross radically different instances.
461- * A better solution needs to be thought up, however at this time it is not known.
462- **/
463- char *tmp = trim_exec_string (self, exec);
464- g_free (exec);
465- exec = tmp;
466- }
467+ /**
468+ * Set of nasty hacks which should be removed some day. We wish to keep the full exec
469+ * strings so we can do nasty matching hacks later. A very very evil thing indeed. However this
470+ * helps hack around applications that run in the same process cross radically different instances.
471+ * A better solution needs to be thought up, however at this time it is not known.
472+ **/
473+ char *tmp = bamf_matcher_get_trimmed_exec (self, exec);
474+ g_free (exec);
475+ exec = tmp;
476
477 path = g_path_get_basename (file);
478 desktop_id = g_string_new (path);
479@@ -962,16 +941,12 @@
480 GString *desktop_id;
481
482 gchar **parts = g_strsplit (line, "\t", 3);
483+
484+ char *tmp = bamf_matcher_get_trimmed_exec (self, parts[1]);
485+ g_free (parts[1]);
486+ parts[1] = tmp;
487 exec = parts[1];
488
489- if (exec_string_should_be_processed (exec))
490- {
491- char *tmp = trim_exec_string (self, exec);
492- g_free (parts[1]);
493- parts[1] = tmp;
494- exec = parts[1];
495- }
496-
497 filename = g_build_filename (directory, parts[0], NULL);
498
499 desktop_id = g_string_new (parts[0]);
500@@ -1176,7 +1151,7 @@
501 free_func (l->data);
502
503 /* If the target is the first element of the list (and thanks to
504-- * the previous check we're also sure that it's not the only one),
505+ * the previous check we're also sure that it's not the only one),
506 * simply switch it with its follower, not to change the first
507 * pointer and the hash table value for key
508 */
509@@ -1305,15 +1280,25 @@
510 }
511
512 static void
513-bamf_add_new_monitored_directory (BamfMatcher * self, const gchar *directory)
514+bamf_matcher_add_new_monitored_directory (BamfMatcher * self, const gchar *directory)
515 {
516 g_return_if_fail (BAMF_IS_MATCHER (self));
517
518 GFile *file;
519 GFileMonitor *monitor;
520+ GError *error = NULL;
521
522 file = g_file_new_for_path (directory);
523- monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
524+ monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, &error);
525+
526+ if (error)
527+ {
528+ g_warning ("Error monitoring %s: %s\n", directory, error->message);
529+ g_error_free (error);
530+ g_object_unref (file);
531+ return;
532+ }
533+
534 g_file_monitor_set_rate_limit (monitor, 1000);
535 g_object_set_data_full (G_OBJECT (monitor), "root", g_strdup (directory), g_free);
536 g_signal_connect (monitor, "changed", (GCallback) on_monitor_changed, self);
537@@ -1342,7 +1327,7 @@
538 if (!g_file_test (directory, G_FILE_TEST_IS_DIR))
539 continue;
540
541- bamf_add_new_monitored_directory (self, directory);
542+ bamf_matcher_add_new_monitored_directory (self, directory);
543
544 bamf_file = g_build_filename (directory, "bamf.index", NULL);
545
546@@ -1496,8 +1481,7 @@
547
548 if (exec_string)
549 {
550- trimmed = trim_exec_string (self, exec_string);
551-
552+ trimmed = bamf_matcher_get_trimmed_exec (self, exec_string);
553 if (trimmed)
554 {
555 if (trimmed[0] != '\0')
556@@ -1886,6 +1870,7 @@
557 /* secondary matching */
558 GList *a;
559 BamfView *view;
560+
561 const gchar *app_desktop_class;
562
563 for (a = self->priv->views; a; a = a->next)
564@@ -1896,10 +1881,41 @@
565 continue;
566
567 app = BAMF_APPLICATION (view);
568- app_desktop_class = bamf_application_get_wmclass (app);
569
570 if (bamf_application_contains_similar_to_window (app, bamf_window))
571 {
572+ char *exec_string = bamf_legacy_window_get_exec_string (window);
573+ char *trimmed_exec = bamf_matcher_get_trimmed_exec (self, exec_string);
574+ g_free (exec_string);
575+
576+ GList *ll;
577+ gboolean found_exec = FALSE;
578+ for (ll = bamf_view_get_children (BAMF_VIEW (app)); ll && !found_exec; ll = ll->next)
579+ {
580+ if (!BAMF_IS_WINDOW (ll->data))
581+ continue;
582+
583+ BamfLegacyWindow *w = bamf_window_get_window (BAMF_WINDOW (ll->data));
584+ char *wexec = bamf_legacy_window_get_exec_string (w);
585+ char *wtrimmed = bamf_matcher_get_trimmed_exec (self, wexec);
586+ g_free (wexec);
587+
588+ if (g_strcmp0 (trimmed_exec, wtrimmed) == 0)
589+ {
590+ best = BAMF_APPLICATION (view);
591+ found_exec = TRUE;
592+ }
593+
594+ g_free (wtrimmed);
595+ }
596+
597+ g_free (trimmed_exec);
598+
599+ if (!found_exec)
600+ continue;
601+
602+ app_desktop_class = bamf_application_get_wmclass (app);
603+
604 if (target_class && g_strcmp0 (target_class, app_desktop_class) == 0)
605 {
606 best = app;
607@@ -2072,26 +2088,26 @@
608 get_gnome_control_center_window_hint (BamfMatcher * self, BamfLegacyWindow * window)
609 {
610 gchar *role;
611- gchar *exec;
612- GHashTable *desktopFileTable;
613 GList *list;
614
615 g_return_val_if_fail (BAMF_IS_MATCHER (self), NULL);
616 g_return_val_if_fail (BAMF_IS_LEGACY_WINDOW (window), NULL);
617
618+ list = NULL;
619 role = bamf_legacy_window_get_hint (window, WM_WINDOW_ROLE);
620- exec = g_strconcat ("gnome-control-center", (role ? " " : NULL), role, NULL);
621-
622- desktopFileTable = self->priv->desktop_file_table;
623- list = g_hash_table_lookup (desktopFileTable, exec);
624-
625- if (!list && g_strcmp0 ("gnome-control-center", exec) != 0)
626- {
627- list = g_hash_table_lookup (desktopFileTable, "gnome-control-center");
628- }
629-
630- g_free (exec);
631- g_free (role);
632+
633+ if (role)
634+ {
635+ gchar *exec = g_strconcat ("gnome-control-center ", role, NULL);
636+ list = g_hash_table_lookup (self->priv->desktop_file_table, exec);
637+ g_free (exec);
638+ g_free (role);
639+ }
640+
641+ if (!role || !list)
642+ {
643+ list = g_hash_table_lookup (self->priv->desktop_id_table, "gnome-control-center");
644+ }
645
646 return (list ? (char *) list->data : NULL);
647 }
648@@ -2129,7 +2145,8 @@
649 g_return_if_fail (BAMF_IS_MATCHER (self));
650 g_return_if_fail (BAMF_IS_LEGACY_WINDOW (window));
651
652- if (bamf_legacy_window_get_window_type (window) == BAMF_WINDOW_DESKTOP)
653+ BamfWindowType win_type = bamf_legacy_window_get_window_type (window);
654+ if (win_type == BAMF_WINDOW_DESKTOP)
655 {
656 BamfWindow *bamfwindow = bamf_window_new (window);
657 bamf_matcher_register_view_stealing_ref (self, BAMF_VIEW (bamfwindow));
658@@ -2139,8 +2156,6 @@
659
660 if (is_open_office_window (self, window))
661 {
662- BamfWindowType win_type = bamf_legacy_window_get_window_type (window);
663-
664 if (win_type == BAMF_WINDOW_SPLASHSCREEN || win_type == BAMF_WINDOW_TOOLBAR)
665 {
666 return;
667@@ -2928,34 +2943,29 @@
668 BamfMatcherPrivate *priv;
669 BamfLegacyScreen *screen;
670 BamfIndicatorSource *approver;
671- GArray *prefixstrings;
672 int i;
673
674 priv = self->priv = BAMF_MATCHER_GET_PRIVATE (self);
675
676 priv->known_pids = g_array_new (FALSE, TRUE, sizeof (gint));
677- priv->bad_prefixes = g_array_new (FALSE, TRUE, sizeof (GRegex *));
678- priv->good_prefixes = g_array_new (FALSE, TRUE, sizeof (GRegex *));
679+ priv->bad_prefixes = g_array_sized_new (FALSE, TRUE, sizeof (GRegex *),
680+ G_N_ELEMENTS (EXEC_BAD_PREFIXES));
681+ priv->good_prefixes = g_array_sized_new (FALSE, TRUE, sizeof (GRegex *),
682+ G_N_ELEMENTS (EXEC_GOOD_PREFIXES));
683 priv->registered_pids = g_hash_table_new_full (g_direct_hash, g_direct_equal,
684 NULL, g_free);
685
686- prefixstrings = bad_prefix_strings ();
687- for (i = 0; i < prefixstrings->len; i++)
688+ for (i = 0; i < G_N_ELEMENTS (EXEC_BAD_PREFIXES); ++i)
689 {
690- char *str = g_array_index (prefixstrings, char *, i);
691- GRegex *regex = g_regex_new (str, G_REGEX_OPTIMIZE, 0, NULL);
692+ GRegex *regex = g_regex_new (EXEC_BAD_PREFIXES[i], G_REGEX_OPTIMIZE, 0, NULL);
693 g_array_append_val (priv->bad_prefixes, regex);
694 }
695- g_array_free (prefixstrings, TRUE);
696
697- prefixstrings = good_prefix_strings ();
698- for (i = 0; i < prefixstrings->len; i++)
699+ for (i = 0; i < G_N_ELEMENTS (EXEC_GOOD_PREFIXES); ++i)
700 {
701- char *str = g_array_index (prefixstrings, char *, i);
702- GRegex *regex = g_regex_new (str, G_REGEX_OPTIMIZE, 0, NULL);
703+ GRegex *regex = g_regex_new (EXEC_GOOD_PREFIXES[i], G_REGEX_OPTIMIZE, 0, NULL);
704 g_array_append_val (priv->good_prefixes, regex);
705 }
706- g_array_free (prefixstrings, TRUE);
707
708 create_desktop_file_table (self, &(priv->desktop_file_table),
709 &(priv->desktop_id_table),
710@@ -3094,6 +3104,7 @@
711 g_signal_handlers_disconnect_by_func (G_OBJECT (l->data),
712 (GCallback) on_monitor_changed, self);
713 }
714+
715 g_list_free_full (priv->monitors, g_object_unref);
716 priv->monitors = NULL;
717
718
719=== modified file 'tests/bamfdaemon/Makefile.am'
720--- tests/bamfdaemon/Makefile.am 2012-11-05 10:23:27 +0000
721+++ tests/bamfdaemon/Makefile.am 2013-01-10 00:25:25 +0000
722@@ -148,6 +148,7 @@
723 export LOG_PATH=$(LOG_PATH); \
724 export XVFB_PATH=$(XVFB); \
725 export DISPLAY=""; \
726+ export XDG_CURRENT_DESKTOP="Unity"; \
727 source $(XVFB_RUN); \
728 \
729 $(DBUS_LAUNCH) > $(LOG_PATH)/sessionbus.sh; \
730
731=== added file 'tests/bamfdaemon/data/gnome-control-center.desktop'
732--- tests/bamfdaemon/data/gnome-control-center.desktop 1970-01-01 00:00:00 +0000
733+++ tests/bamfdaemon/data/gnome-control-center.desktop 2013-01-10 00:25:25 +0000
734@@ -0,0 +1,9 @@
735+[Desktop Entry]
736+Name=System Settings
737+Icon=preferences-system
738+Exec=gnome-control-center --overview
739+Terminal=false
740+Type=Application
741+StartupNotify=true
742+Categories=GNOME;GTK;System;
743+OnlyShowIn=GNOME;Unity;
744
745=== added file 'tests/bamfdaemon/data/gnome-display-panel.desktop'
746--- tests/bamfdaemon/data/gnome-display-panel.desktop 1970-01-01 00:00:00 +0000
747+++ tests/bamfdaemon/data/gnome-display-panel.desktop 2013-01-10 00:25:25 +0000
748@@ -0,0 +1,10 @@
749+[Desktop Entry]
750+Name=Displays
751+Comment=Change resolution and position of monitors and projectors
752+Exec=gnome-control-center display
753+Icon=preferences-desktop-display
754+Terminal=false
755+Type=Application
756+StartupNotify=true
757+Categories=GNOME;GTK;Settings;HardwareSettings;X-GNOME-Settings-Panel;
758+OnlyShowIn=GNOME;Unity;
759
760=== added file 'tests/bamfdaemon/data/gnome-mouse-panel.desktop'
761--- tests/bamfdaemon/data/gnome-mouse-panel.desktop 1970-01-01 00:00:00 +0000
762+++ tests/bamfdaemon/data/gnome-mouse-panel.desktop 2013-01-10 00:25:25 +0000
763@@ -0,0 +1,10 @@
764+[Desktop Entry]
765+Name=Mouse and Touchpad
766+Comment=Set your mouse and touchpad preferences
767+Exec=gnome-control-center mouse
768+Icon=input-mouse
769+Terminal=false
770+Type=Application
771+StartupNotify=true
772+Categories=GNOME;GTK;Settings;HardwareSettings;X-GNOME-Settings-Panel;
773+OnlyShowIn=GNOME;Unity;
774
775=== modified file 'tests/bamfdaemon/test-matcher.c'
776--- tests/bamfdaemon/test-matcher.c 2012-10-10 17:21:47 +0000
777+++ tests/bamfdaemon/test-matcher.c 2013-01-10 00:25:25 +0000
778@@ -32,7 +32,10 @@
779 static void test_match_desktopless_application (void);
780 static void test_match_desktop_application (void);
781 static void test_match_libreoffice_windows (void);
782+static void test_match_gnome_control_center_panels (void);
783+static void test_match_javaws_windows (void);
784 static void test_new_desktop_matches_unmatched_windows (void);
785+static void test_trim_exec_string (void);
786
787 static GDBusConnection *gdbus_connection = NULL;
788
789@@ -51,7 +54,10 @@
790 g_test_add_func (DOMAIN"/Matching/Application/DesktopLess", test_match_desktopless_application);
791 g_test_add_func (DOMAIN"/Matching/Application/Desktop", test_match_desktop_application);
792 g_test_add_func (DOMAIN"/Matching/Application/LibreOffice", test_match_libreoffice_windows);
793+ g_test_add_func (DOMAIN"/Matching/Application/GnomeControlCenter", test_match_gnome_control_center_panels);
794+ g_test_add_func (DOMAIN"/Matching/Application/JavaWebStart", test_match_javaws_windows);
795 g_test_add_func (DOMAIN"/Matching/Windows/UnmatchedOnNewDesktop", test_new_desktop_matches_unmatched_windows);
796+ g_test_add_func (DOMAIN"/ExecStringTrimming", test_trim_exec_string);
797 }
798
799 static void
800@@ -480,3 +486,211 @@
801 g_object_unref (screen);
802 }
803
804+static void
805+test_match_gnome_control_center_panels (void)
806+{
807+ BamfMatcher *matcher;
808+ BamfWindow *window;
809+ BamfLegacyScreen *screen;
810+ BamfLegacyWindowTest *test_win;
811+ BamfApplication *app;
812+ char *hint;
813+
814+ screen = bamf_legacy_screen_get_default ();
815+ matcher = bamf_matcher_get_default ();
816+ guint xid = g_random_int ();
817+ const char *exec = "gnome-control-center";
818+ const char *class_name = "Gnome-control-center";
819+ const char *class_instance = "gnome-control-center";
820+
821+ cleanup_matcher_tables (matcher);
822+ export_matcher_on_bus (matcher);
823+
824+ bamf_matcher_load_desktop_file (matcher, DATA_DIR"/gnome-control-center.desktop");
825+ bamf_matcher_load_desktop_file (matcher, DATA_DIR"/gnome-display-panel.desktop");
826+ bamf_matcher_load_desktop_file (matcher, DATA_DIR"/gnome-mouse-panel.desktop");
827+
828+ test_win = bamf_legacy_window_test_new (xid, "System Settings", NULL, exec);
829+ bamf_legacy_window_test_set_wmclass (test_win, class_name, class_instance);
830+ bamf_legacy_window_set_hint (BAMF_LEGACY_WINDOW (test_win), WM_WINDOW_ROLE, NULL);
831+ _bamf_legacy_screen_open_test_window (screen, test_win);
832+
833+ hint = bamf_legacy_window_get_hint (BAMF_LEGACY_WINDOW (test_win), _NET_WM_DESKTOP_FILE);
834+ g_assert_cmpstr (hint, ==, DATA_DIR"/gnome-control-center.desktop");
835+ g_free (hint);
836+ app = bamf_matcher_get_application_by_desktop_file (matcher, DATA_DIR"/gnome-control-center.desktop");
837+ g_assert (find_window_in_app (app, BAMF_LEGACY_WINDOW (test_win)));
838+
839+ bamf_legacy_window_set_hint (BAMF_LEGACY_WINDOW (test_win), WM_WINDOW_ROLE, "display");
840+ bamf_legacy_window_test_set_name (test_win, "Displays");
841+ g_assert (!bamf_matcher_get_application_by_desktop_file (matcher, DATA_DIR"/gnome-control-center.desktop"));
842+ app = bamf_matcher_get_application_by_desktop_file (matcher, DATA_DIR"/gnome-display-panel.desktop");
843+ g_assert (app);
844+ window = BAMF_WINDOW (bamf_view_get_children (BAMF_VIEW (app))->data);
845+ test_win = BAMF_LEGACY_WINDOW_TEST (bamf_window_get_window (window));
846+ hint = bamf_legacy_window_get_hint (BAMF_LEGACY_WINDOW (test_win), _NET_WM_DESKTOP_FILE);
847+ g_assert_cmpstr (hint, ==, DATA_DIR"/gnome-display-panel.desktop");
848+ g_free (hint);
849+
850+ bamf_legacy_window_set_hint (BAMF_LEGACY_WINDOW (test_win), WM_WINDOW_ROLE, "mouse");
851+ bamf_legacy_window_test_set_name (test_win, "Mouse and Touchpad");
852+ g_assert (!bamf_matcher_get_application_by_desktop_file (matcher, DATA_DIR"/gnome-display-panel.desktop"));
853+ app = bamf_matcher_get_application_by_desktop_file (matcher, DATA_DIR"/gnome-mouse-panel.desktop");
854+ g_assert (app);
855+ window = BAMF_WINDOW (bamf_view_get_children (BAMF_VIEW (app))->data);
856+ test_win = BAMF_LEGACY_WINDOW_TEST (bamf_window_get_window (window));
857+ hint = bamf_legacy_window_get_hint (BAMF_LEGACY_WINDOW (test_win), _NET_WM_DESKTOP_FILE);
858+ g_assert_cmpstr (hint, ==, DATA_DIR"/gnome-mouse-panel.desktop");
859+ g_free (hint);
860+
861+ bamf_legacy_window_set_hint (BAMF_LEGACY_WINDOW (test_win), WM_WINDOW_ROLE, "invalid-role");
862+ bamf_legacy_window_test_set_name (test_win, "Invalid Panel");
863+ g_assert (!bamf_matcher_get_application_by_desktop_file (matcher, DATA_DIR"/gnome-mouse-panel.desktop"));
864+ app = bamf_matcher_get_application_by_desktop_file (matcher, DATA_DIR"/gnome-control-center.desktop");
865+ g_assert (app);
866+ window = BAMF_WINDOW (bamf_view_get_children (BAMF_VIEW (app))->data);
867+ test_win = BAMF_LEGACY_WINDOW_TEST (bamf_window_get_window (window));
868+ hint = bamf_legacy_window_get_hint (BAMF_LEGACY_WINDOW (test_win), _NET_WM_DESKTOP_FILE);
869+ g_assert_cmpstr (hint, ==, DATA_DIR"/gnome-control-center.desktop");
870+ g_free (hint);
871+
872+ g_object_unref (matcher);
873+ g_object_unref (screen);
874+}
875+
876+static void
877+test_match_javaws_windows (void)
878+{
879+ BamfMatcher *matcher;
880+ BamfLegacyScreen *screen;
881+ BamfLegacyWindowTest *test_win;
882+ BamfApplication *app1, *app2, *app3;
883+ GList *app_children;
884+
885+ screen = bamf_legacy_screen_get_default ();
886+ matcher = bamf_matcher_get_default ();
887+ const char *exec_prefix = "/usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java " \
888+ "-Xbootclasspath/a:/usr/share/icedtea-web/netx.jar " \
889+ "-Xms8m -Djava.security.manager " \
890+ "-Djava.security.policy=/etc/icedtea-web/javaws.policy " \
891+ "-classpath /usr/lib/jvm/java-6-openjdk-amd64/jre/lib/rt.jar " \
892+ "-Dicedtea-web.bin.name=javaws " \
893+ "-Dicedtea-web.bin.location=/usr/bin/javaws "\
894+ "net.sourceforge.jnlp.runtime.Boot";
895+ const char *class_name = "sun-awt-X11-XFramePeer";
896+ const char *class_instance = "net-sourceforge-jnlp-runtime-Boot";
897+
898+ cleanup_matcher_tables (matcher);
899+ export_matcher_on_bus (matcher);
900+
901+ guint xid = g_random_int ();
902+ char *exec = g_strconcat (exec_prefix, " Notepad.jnlp", NULL);
903+ test_win = bamf_legacy_window_test_new (xid, "Notepad", NULL, exec);
904+ bamf_legacy_window_test_set_wmclass (test_win, class_name, class_instance);
905+ _bamf_legacy_screen_open_test_window (screen, test_win);
906+ g_free (exec);
907+ app1 = bamf_matcher_get_application_by_xid (matcher, xid);
908+ g_assert (BAMF_IS_APPLICATION (app1));
909+ app_children = bamf_view_get_children (BAMF_VIEW (app1));
910+ g_assert_cmpuint (g_list_length (app_children), ==, 1);
911+ g_assert (find_window_in_app (app1, BAMF_LEGACY_WINDOW (test_win)));
912+
913+ xid = g_random_int ();
914+ exec = g_strconcat (exec_prefix, " Draw.jnlp", NULL);
915+ test_win = bamf_legacy_window_test_new (xid, "Draw", NULL, exec);
916+ bamf_legacy_window_test_set_wmclass (test_win, class_name, class_instance);
917+ _bamf_legacy_screen_open_test_window (screen, test_win);
918+ g_free (exec);
919+ app2 = bamf_matcher_get_application_by_xid (matcher, xid);
920+ g_assert (BAMF_IS_APPLICATION (app2));
921+ g_assert (app1 != app2);
922+ app_children = bamf_view_get_children (BAMF_VIEW (app2));
923+ g_assert_cmpuint (g_list_length (app_children), ==, 1);
924+ g_assert (find_window_in_app (app2, BAMF_LEGACY_WINDOW (test_win)));
925+
926+ xid = g_random_int ();
927+ exec = g_strconcat (exec_prefix, " Notepad.jnlp", NULL);
928+ test_win = bamf_legacy_window_test_new (xid, "Notepad Subwin", NULL, exec);
929+ bamf_legacy_window_test_set_wmclass (test_win, class_name, class_instance);
930+ _bamf_legacy_screen_open_test_window (screen, test_win);
931+ g_free (exec);
932+ app3 = bamf_matcher_get_application_by_xid (matcher, xid);
933+ g_assert (app3 == app1);
934+ g_assert (BAMF_IS_APPLICATION (app3));
935+ app_children = bamf_view_get_children (BAMF_VIEW (app3));
936+ g_assert_cmpuint (g_list_length (app_children), ==, 2);
937+ g_assert (find_window_in_app (app3, BAMF_LEGACY_WINDOW (test_win)));
938+
939+ g_object_unref (matcher);
940+ g_object_unref (screen);
941+}
942+
943+static void
944+test_trim_exec_string (void)
945+{
946+ BamfMatcher *matcher;
947+ char *trimmed;
948+
949+ matcher = bamf_matcher_get_default ();
950+
951+ // Bad prefixes
952+ trimmed = bamf_matcher_get_trimmed_exec (matcher, "gksudo bad-prefix-bin");
953+ g_assert_cmpstr (trimmed, ==, "bad-prefix-bin");
954+ g_free (trimmed);
955+
956+ trimmed = bamf_matcher_get_trimmed_exec (matcher, "sudo --opt val=X /usr/bin/bad-prefix-bin");
957+ g_assert_cmpstr (trimmed, ==, "bad-prefix-bin");
958+ g_free (trimmed);
959+
960+ trimmed = bamf_matcher_get_trimmed_exec (matcher, "python2.7 /home/foo/bad-prefix-script.py");
961+ g_assert_cmpstr (trimmed, ==, "bad-prefix-script");
962+ g_free (trimmed);
963+
964+ trimmed = bamf_matcher_get_trimmed_exec (matcher, "/usr/bin/python3.1");
965+ g_assert_cmpstr (trimmed, ==, "python3.1");
966+ g_free (trimmed);
967+
968+ trimmed = bamf_matcher_get_trimmed_exec (matcher, "/usr/bin/python %u --option val=/path");
969+ g_assert_cmpstr (trimmed, ==, "python");
970+ g_free (trimmed);
971+
972+ trimmed = bamf_matcher_get_trimmed_exec (matcher, "sh -c \"binary --option --value %U || exec binary\"");
973+ g_assert_cmpstr (trimmed, ==, "binary");
974+ g_free (trimmed);
975+
976+ // Good prefixes
977+ trimmed = bamf_matcher_get_trimmed_exec (matcher, "/usr/bin/libreoffice --writer %U");
978+ g_assert_cmpstr (trimmed, ==, "libreoffice --writer");
979+ g_free (trimmed);
980+
981+ trimmed = bamf_matcher_get_trimmed_exec (matcher, "/usr/bin/gnome-control-center");
982+ g_assert_cmpstr (trimmed, ==, "gnome-control-center");
983+ g_free (trimmed);
984+
985+ trimmed = bamf_matcher_get_trimmed_exec (matcher, "gnome-control-center foo-panel");
986+ g_assert_cmpstr (trimmed, ==, "gnome-control-center foo-panel");
987+ g_free (trimmed);
988+
989+ // Other exec strings
990+ trimmed = bamf_matcher_get_trimmed_exec (matcher, "env FOOVAR=\"bar\" myprog");
991+ g_assert_cmpstr (trimmed, ==, "myprog");
992+ g_free (trimmed);
993+
994+ trimmed = bamf_matcher_get_trimmed_exec (matcher, "/opt/path/bin/myprog --option %U --foo=daa");
995+ g_assert_cmpstr (trimmed, ==, "myprog");
996+ g_free (trimmed);
997+
998+ const char *exec = "/usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java " \
999+ "-Xbootclasspath/a:/usr/share/icedtea-web/netx.jar " \
1000+ "-Xms8m -Djava.security.manager " \
1001+ "-Djava.security.policy=/etc/icedtea-web/javaws.policy " \
1002+ "-classpath /usr/lib/jvm/java-6-openjdk-amd64/jre/lib/rt.jar " \
1003+ "-Dicedtea-web.bin.name=javaws " \
1004+ "-Dicedtea-web.bin.location=/usr/bin/javaws "\
1005+ "net.sourceforge.jnlp.runtime.Boot Notepad.jnlp";
1006+ trimmed = bamf_matcher_get_trimmed_exec (matcher, exec);
1007+ g_assert_cmpstr (trimmed, ==, "notepad.jnlp");
1008+ g_free (trimmed);
1009+
1010+ g_object_unref (matcher);
1011+}

Subscribers

People subscribed via source and target branches