Merge lp:~3v1n0/bamf/fixes into lp:bamf/0.4
- fixes
- Merge into 0.4
Status: | Merged | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 412 | ||||||||||||
Proposed branch: | lp:~3v1n0/bamf/fixes | ||||||||||||
Merge into: | lp:bamf/0.4 | ||||||||||||
Diff against target: |
1121 lines (+555/-236) 3 files modified
src/bamf-application.c (+27/-14) src/bamf-application.h (+4/-4) src/bamf-matcher.c (+524/-218) |
||||||||||||
To merge this branch: | bzr merge lp:~3v1n0/bamf/fixes | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jason Smith (community) | Approve | ||
Unity Community Hackers | Pending | ||
Review via email: mp+65434@code.launchpad.net |
Commit message
Description of the change
This is a branch I'm working on during my spare time since some weeks; it includes some BAMF miscellaneous fixes.
- Improved desktop folders monitoring support (fix bug #676593) supporting monitoring
newly added .desktop files, newly added folders containing .desktop files
(recursively), edited .desktop files (reducing the rate limit, to save CPU)
- Correctly clear from BAMF cache .desktop files that are removed from system
- Order correctly the .desktop file keeping their priority
- Support the ~/Desktop folder and $XDG_DATA_HOME as .desktop storages (with
highest priority, the order will be kept when adding new files) bug #768636
- Some memory leaks and coding style fixes...
I would have added also the support for dynamically update a bamf_application when a .desktop file (that matches it) is removed, but I guess that it's not vital... On next application reload the user will notice the change (however, if it is requested, I've already done something in it).
For more informations, look at the logs [1]; I've wrote anything there.
- 423. By Marco Trevisan (Treviño)
-
compare_sub_values optimization.
Generate the "prefix" string just once, and not for every sub-folder
.desktop item compared. This should save many allocations/copies. ..
Preview Diff
1 | === modified file 'src/bamf-application.c' | |||
2 | --- src/bamf-application.c 2011-04-18 17:34:28 +0000 | |||
3 | +++ src/bamf-application.c 2011-06-26 22:21:13 +0000 | |||
4 | @@ -237,21 +237,30 @@ | |||
5 | 237 | 237 | ||
6 | 238 | void | 238 | void |
7 | 239 | bamf_application_set_desktop_file (BamfApplication *application, | 239 | bamf_application_set_desktop_file (BamfApplication *application, |
9 | 240 | char * desktop_file) | 240 | const char * desktop_file) |
10 | 241 | { | 241 | { |
11 | 242 | g_return_if_fail (BAMF_IS_APPLICATION (application)); | 242 | g_return_if_fail (BAMF_IS_APPLICATION (application)); |
12 | 243 | 243 | ||
14 | 244 | application->priv->desktop_file = g_strdup (desktop_file); | 244 | if (application->priv->desktop_file) |
15 | 245 | g_free (application->priv->desktop_file); | ||
16 | 246 | |||
17 | 247 | if (desktop_file && desktop_file[0] != '\0') | ||
18 | 248 | application->priv->desktop_file = g_strdup (desktop_file); | ||
19 | 249 | else | ||
20 | 250 | application->priv->desktop_file = NULL; | ||
21 | 245 | 251 | ||
22 | 246 | bamf_application_setup_icon_and_name (application); | 252 | bamf_application_setup_icon_and_name (application); |
23 | 247 | } | 253 | } |
24 | 248 | 254 | ||
25 | 249 | void | 255 | void |
26 | 250 | bamf_application_set_wmclass (BamfApplication *application, | 256 | bamf_application_set_wmclass (BamfApplication *application, |
28 | 251 | char *wmclass) | 257 | const char *wmclass) |
29 | 252 | { | 258 | { |
30 | 253 | g_return_if_fail (BAMF_IS_APPLICATION (application)); | 259 | g_return_if_fail (BAMF_IS_APPLICATION (application)); |
31 | 254 | 260 | ||
32 | 261 | if (application->priv->wmclass) | ||
33 | 262 | g_free (application->priv->wmclass); | ||
34 | 263 | |||
35 | 255 | if (wmclass && wmclass[0] != '\0') | 264 | if (wmclass && wmclass[0] != '\0') |
36 | 256 | application->priv->wmclass = g_strdup (wmclass); | 265 | application->priv->wmclass = g_strdup (wmclass); |
37 | 257 | else | 266 | else |
38 | @@ -517,16 +526,24 @@ | |||
39 | 517 | g_return_if_fail (list); | 526 | g_return_if_fail (list); |
40 | 518 | 527 | ||
41 | 519 | priv = self->priv; | 528 | priv = self->priv; |
43 | 520 | 529 | ||
44 | 530 | if (priv->desktop_file_list) | ||
45 | 531 | { | ||
46 | 532 | g_list_free_full (priv->desktop_file_list, g_free); | ||
47 | 533 | priv->desktop_file_list = NULL; | ||
48 | 534 | } | ||
49 | 535 | |||
50 | 521 | for (l = list; l; l = l->next) | 536 | for (l = list; l; l = l->next) |
51 | 522 | priv->desktop_file_list = g_list_prepend (priv->desktop_file_list, g_strdup (l->data)); | 537 | priv->desktop_file_list = g_list_prepend (priv->desktop_file_list, g_strdup (l->data)); |
53 | 523 | 538 | ||
54 | 539 | priv->desktop_file_list = g_list_reverse (priv->desktop_file_list); | ||
55 | 540 | |||
56 | 524 | desktop_file = bamf_application_favorite_from_list (self, priv->desktop_file_list); | 541 | desktop_file = bamf_application_favorite_from_list (self, priv->desktop_file_list); |
57 | 525 | 542 | ||
59 | 526 | /* items come in priority order */ | 543 | /* items, after reversing them, are in priority order */ |
60 | 527 | if (!desktop_file) | 544 | if (!desktop_file) |
61 | 528 | desktop_file = list->data; | 545 | desktop_file = list->data; |
63 | 529 | 546 | ||
64 | 530 | bamf_application_set_desktop_file (self, desktop_file); | 547 | bamf_application_set_desktop_file (self, desktop_file); |
65 | 531 | } | 548 | } |
66 | 532 | 549 | ||
67 | @@ -576,7 +593,6 @@ | |||
68 | 576 | { | 593 | { |
69 | 577 | BamfApplication *app; | 594 | BamfApplication *app; |
70 | 578 | BamfApplicationPrivate *priv; | 595 | BamfApplicationPrivate *priv; |
71 | 579 | GList *l; | ||
72 | 580 | 596 | ||
73 | 581 | app = BAMF_APPLICATION (object); | 597 | app = BAMF_APPLICATION (object); |
74 | 582 | priv = app->priv; | 598 | priv = app->priv; |
75 | @@ -589,10 +605,7 @@ | |||
76 | 589 | 605 | ||
77 | 590 | if (priv->desktop_file_list) | 606 | if (priv->desktop_file_list) |
78 | 591 | { | 607 | { |
83 | 592 | for (l = priv->desktop_file_list; l; l = l->next) | 608 | g_list_free_full (priv->desktop_file_list, g_free); |
80 | 593 | g_free (l->data); | ||
81 | 594 | |||
82 | 595 | g_list_free (priv->desktop_file_list); | ||
84 | 596 | priv->desktop_file_list = NULL; | 609 | priv->desktop_file_list = NULL; |
85 | 597 | } | 610 | } |
86 | 598 | 611 | ||
87 | @@ -676,7 +689,7 @@ | |||
88 | 676 | } | 689 | } |
89 | 677 | 690 | ||
90 | 678 | BamfApplication * | 691 | BamfApplication * |
92 | 679 | bamf_application_new_from_desktop_file (char * desktop_file) | 692 | bamf_application_new_from_desktop_file (const char * desktop_file) |
93 | 680 | { | 693 | { |
94 | 681 | BamfApplication *application; | 694 | BamfApplication *application; |
95 | 682 | application = (BamfApplication *) g_object_new (BAMF_TYPE_APPLICATION, NULL); | 695 | application = (BamfApplication *) g_object_new (BAMF_TYPE_APPLICATION, NULL); |
96 | @@ -698,7 +711,7 @@ | |||
97 | 698 | } | 711 | } |
98 | 699 | 712 | ||
99 | 700 | BamfApplication * | 713 | BamfApplication * |
101 | 701 | bamf_application_new_with_wmclass (char *wmclass) | 714 | bamf_application_new_with_wmclass (const char *wmclass) |
102 | 702 | { | 715 | { |
103 | 703 | BamfApplication *application; | 716 | BamfApplication *application; |
104 | 704 | application = (BamfApplication *) g_object_new (BAMF_TYPE_APPLICATION, NULL); | 717 | application = (BamfApplication *) g_object_new (BAMF_TYPE_APPLICATION, NULL); |
105 | 705 | 718 | ||
106 | === modified file 'src/bamf-application.h' | |||
107 | --- src/bamf-application.h 2011-03-29 09:37:44 +0000 | |||
108 | +++ src/bamf-application.h 2011-06-26 22:21:13 +0000 | |||
109 | @@ -56,7 +56,7 @@ | |||
110 | 56 | 56 | ||
111 | 57 | char * bamf_application_get_desktop_file (BamfApplication *application); | 57 | char * bamf_application_get_desktop_file (BamfApplication *application); |
112 | 58 | void bamf_application_set_desktop_file (BamfApplication *application, | 58 | void bamf_application_set_desktop_file (BamfApplication *application, |
114 | 59 | char * desktop_file); | 59 | const char * desktop_file); |
115 | 60 | 60 | ||
116 | 61 | GArray * bamf_application_get_xids (BamfApplication *application); | 61 | GArray * bamf_application_get_xids (BamfApplication *application); |
117 | 62 | 62 | ||
118 | @@ -68,15 +68,15 @@ | |||
119 | 68 | 68 | ||
120 | 69 | char * bamf_application_get_wmclass (BamfApplication *application); | 69 | char * bamf_application_get_wmclass (BamfApplication *application); |
121 | 70 | void bamf_application_set_wmclass (BamfApplication *application, | 70 | void bamf_application_set_wmclass (BamfApplication *application, |
123 | 71 | char *wmclass); | 71 | const char *wmclass); |
124 | 72 | 72 | ||
125 | 73 | BamfApplication * bamf_application_new (void); | 73 | BamfApplication * bamf_application_new (void); |
126 | 74 | 74 | ||
128 | 75 | BamfApplication * bamf_application_new_from_desktop_file (char * desktop_file); | 75 | BamfApplication * bamf_application_new_from_desktop_file (const char * desktop_file); |
129 | 76 | gboolean bamf_application_get_show_stubs (BamfApplication *application); | 76 | gboolean bamf_application_get_show_stubs (BamfApplication *application); |
130 | 77 | 77 | ||
131 | 78 | BamfApplication * bamf_application_new_from_desktop_files (GList * desktop_files); | 78 | BamfApplication * bamf_application_new_from_desktop_files (GList * desktop_files); |
132 | 79 | 79 | ||
134 | 80 | BamfApplication * bamf_application_new_with_wmclass (char *wmclass); | 80 | BamfApplication * bamf_application_new_with_wmclass (const char *wmclass); |
135 | 81 | 81 | ||
136 | 82 | #endif | 82 | #endif |
137 | 83 | 83 | ||
138 | === modified file 'src/bamf-matcher.c' | |||
139 | --- src/bamf-matcher.c 2011-04-27 16:48:14 +0000 | |||
140 | +++ src/bamf-matcher.c 2011-06-26 22:21:13 +0000 | |||
141 | @@ -150,7 +150,7 @@ | |||
142 | 150 | type = bamf_view_get_view_type (view); | 150 | type = bamf_view_get_view_type (view); |
143 | 151 | 151 | ||
144 | 152 | g_signal_connect (G_OBJECT (view), "closed-internal", | 152 | g_signal_connect (G_OBJECT (view), "closed-internal", |
146 | 153 | (GCallback) on_view_closed, self); | 153 | (GCallback) on_view_closed, self); |
147 | 154 | g_signal_connect (G_OBJECT (view), "active-changed", | 154 | g_signal_connect (G_OBJECT (view), "active-changed", |
148 | 155 | (GCallback) on_view_active_changed, self); | 155 | (GCallback) on_view_active_changed, self); |
149 | 156 | 156 | ||
150 | @@ -275,28 +275,28 @@ | |||
151 | 275 | part = parts[i]; | 275 | part = parts[i]; |
152 | 276 | 276 | ||
153 | 277 | if (!g_str_has_prefix (part, "-")) | 277 | if (!g_str_has_prefix (part, "-")) |
176 | 278 | { | 278 | { |
177 | 279 | tmp = g_utf8_strrchr (part, -1, '/'); | 279 | tmp = g_utf8_strrchr (part, -1, G_DIR_SEPARATOR); |
178 | 280 | if (tmp) | 280 | if (tmp) |
179 | 281 | part = tmp + 1; | 281 | part = tmp + 1; |
180 | 282 | 282 | ||
181 | 283 | regexFail = FALSE; | 283 | regexFail = FALSE; |
182 | 284 | for (j = 0; j < self->priv->bad_prefixes->len; j++) | 284 | for (j = 0; j < self->priv->bad_prefixes->len; j++) |
183 | 285 | { | 285 | { |
184 | 286 | regex = g_array_index (self->priv->bad_prefixes, GRegex *, j); | 286 | regex = g_array_index (self->priv->bad_prefixes, GRegex *, j); |
185 | 287 | if (g_regex_match (regex, part, 0, NULL)) | 287 | if (g_regex_match (regex, part, 0, NULL)) |
186 | 288 | { | 288 | { |
187 | 289 | regexFail = TRUE; | 289 | regexFail = TRUE; |
188 | 290 | break; | 290 | break; |
189 | 291 | } | 291 | } |
190 | 292 | } | 292 | } |
191 | 293 | 293 | ||
192 | 294 | if (!regexFail) | 294 | if (!regexFail) |
193 | 295 | { | 295 | { |
194 | 296 | result = g_strdup (part); | 296 | result = g_strdup (part); |
195 | 297 | break; | 297 | break; |
196 | 298 | } | 298 | } |
197 | 299 | } | 299 | } |
198 | 300 | i++; | 300 | i++; |
199 | 301 | } | 301 | } |
200 | 302 | 302 | ||
201 | @@ -404,6 +404,34 @@ | |||
202 | 404 | return !g_str_has_prefix (exec, "ooffice") && !g_str_has_prefix (exec, "libreoffice"); | 404 | return !g_str_has_prefix (exec, "ooffice") && !g_str_has_prefix (exec, "libreoffice"); |
203 | 405 | } | 405 | } |
204 | 406 | 406 | ||
205 | 407 | static gboolean | ||
206 | 408 | is_desktop_folder_item (const char *desktop_file_path, gssize max_len) | ||
207 | 409 | { | ||
208 | 410 | gsize len; | ||
209 | 411 | const char *desktop_folder; | ||
210 | 412 | |||
211 | 413 | g_return_val_if_fail (desktop_file_path, FALSE); | ||
212 | 414 | |||
213 | 415 | if (max_len > 0) | ||
214 | 416 | { | ||
215 | 417 | len = max_len; | ||
216 | 418 | } | ||
217 | 419 | else | ||
218 | 420 | { | ||
219 | 421 | char *tmp; | ||
220 | 422 | tmp = strrchr (desktop_file_path, G_DIR_SEPARATOR); | ||
221 | 423 | g_return_val_if_fail (tmp, FALSE); | ||
222 | 424 | len = tmp - desktop_file_path; | ||
223 | 425 | } | ||
224 | 426 | |||
225 | 427 | desktop_folder = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); | ||
226 | 428 | |||
227 | 429 | if (strncmp (desktop_folder, desktop_file_path, len) == 0) | ||
228 | 430 | return TRUE; | ||
229 | 431 | |||
230 | 432 | return FALSE; | ||
231 | 433 | } | ||
232 | 434 | |||
233 | 407 | static void | 435 | static void |
234 | 408 | insert_data_into_tables (BamfMatcher *self, | 436 | insert_data_into_tables (BamfMatcher *self, |
235 | 409 | const char *data, | 437 | const char *data, |
236 | @@ -421,20 +449,60 @@ | |||
237 | 421 | file_list = g_hash_table_lookup (desktop_file_table, exec); | 449 | file_list = g_hash_table_lookup (desktop_file_table, exec); |
238 | 422 | id_list = g_hash_table_lookup (desktop_id_table, desktop_id); | 450 | id_list = g_hash_table_lookup (desktop_id_table, desktop_id); |
239 | 423 | 451 | ||
240 | 452 | if (g_list_find_custom (file_list, data, (GCompareFunc) g_strcmp0) && | ||
241 | 453 | g_list_find_custom (id_list, data, (GCompareFunc) g_strcmp0)) | ||
242 | 454 | { | ||
243 | 455 | return; | ||
244 | 456 | } | ||
245 | 457 | |||
246 | 424 | datadup = g_strdup (data); | 458 | datadup = g_strdup (data); |
248 | 425 | 459 | ||
249 | 426 | /* order so that items whose desktop_id == exec string are first in the list */ | 460 | /* order so that items whose desktop_id == exec string are first in the list */ |
251 | 427 | if (g_strcmp0 (exec, desktop_id) == 0) | 461 | |
252 | 462 | if (g_strcmp0 (exec, desktop_id) == 0 || is_desktop_folder_item (datadup, -1)) | ||
253 | 428 | { | 463 | { |
256 | 429 | file_list = g_list_prepend (file_list, datadup); | 464 | GList *l, *last; |
257 | 430 | id_list = g_list_prepend (id_list, datadup); | 465 | last = NULL; |
258 | 466 | |||
259 | 467 | for (l = file_list; l; l = l->next) | ||
260 | 468 | { | ||
261 | 469 | char *dpath; | ||
262 | 470 | char *dname_start, *dname_end; | ||
263 | 471 | size_t len; | ||
264 | 472 | |||
265 | 473 | dpath = l->data; | ||
266 | 474 | dname_start = strrchr (dpath, G_DIR_SEPARATOR); | ||
267 | 475 | if (!dname_start) | ||
268 | 476 | { | ||
269 | 477 | continue; | ||
270 | 478 | } | ||
271 | 479 | |||
272 | 480 | dname_start++; | ||
273 | 481 | dname_end = strrchr (dname_start, '.'); | ||
274 | 482 | len = dname_end - dname_start; | ||
275 | 483 | |||
276 | 484 | if (!dname_end || len < 1) | ||
277 | 485 | { | ||
278 | 486 | continue; | ||
279 | 487 | } | ||
280 | 488 | |||
281 | 489 | if (strncmp (desktop_id, dname_start, len) != 0 && | ||
282 | 490 | !is_desktop_folder_item (dpath, (dname_start - dpath - 1))) | ||
283 | 491 | { | ||
284 | 492 | last = l; | ||
285 | 493 | break; | ||
286 | 494 | } | ||
287 | 495 | } | ||
288 | 496 | |||
289 | 497 | file_list = g_list_insert_before (file_list, last, datadup); | ||
290 | 431 | } | 498 | } |
291 | 432 | else | 499 | else |
292 | 433 | { | 500 | { |
293 | 434 | file_list = g_list_append (file_list, datadup); | 501 | file_list = g_list_append (file_list, datadup); |
294 | 435 | id_list = g_list_append (id_list, datadup); | ||
295 | 436 | } | 502 | } |
296 | 437 | 503 | ||
297 | 504 | id_list = g_list_append (id_list, datadup); | ||
298 | 505 | |||
299 | 438 | g_hash_table_insert (desktop_file_table, g_strdup (exec), file_list); | 506 | g_hash_table_insert (desktop_file_table, g_strdup (exec), file_list); |
300 | 439 | g_hash_table_insert (desktop_id_table, g_strdup (desktop_id), id_list); | 507 | g_hash_table_insert (desktop_id_table, g_strdup (desktop_id), id_list); |
301 | 440 | } | 508 | } |
302 | @@ -530,8 +598,8 @@ | |||
303 | 530 | GFile *dir; | 598 | GFile *dir; |
304 | 531 | GFileEnumerator *enumerator; | 599 | GFileEnumerator *enumerator; |
305 | 532 | GFileInfo *info; | 600 | GFileInfo *info; |
308 | 533 | const char* name; | 601 | const char *name; |
309 | 534 | const char *path; | 602 | char *path; |
310 | 535 | 603 | ||
311 | 536 | dir = g_file_new_for_path (directory); | 604 | dir = g_file_new_for_path (directory); |
312 | 537 | 605 | ||
313 | @@ -558,7 +626,7 @@ | |||
314 | 558 | desktop_id_table, | 626 | desktop_id_table, |
315 | 559 | desktop_class_table); | 627 | desktop_class_table); |
316 | 560 | 628 | ||
318 | 561 | g_free ((gpointer) path); | 629 | g_free (path); |
319 | 562 | g_object_unref (info); | 630 | g_object_unref (info); |
320 | 563 | } | 631 | } |
321 | 564 | 632 | ||
322 | @@ -599,8 +667,8 @@ | |||
323 | 599 | while ((line = g_data_input_stream_read_line (input, &length, NULL, NULL)) != NULL) | 667 | while ((line = g_data_input_stream_read_line (input, &length, NULL, NULL)) != NULL) |
324 | 600 | { | 668 | { |
325 | 601 | char *exec; | 669 | char *exec; |
326 | 670 | char *filename; | ||
327 | 602 | GString *desktop_id; | 671 | GString *desktop_id; |
328 | 603 | GString *filename; | ||
329 | 604 | 672 | ||
330 | 605 | gchar **parts = g_strsplit (line, "\t", 3); | 673 | gchar **parts = g_strsplit (line, "\t", 3); |
331 | 606 | 674 | ||
332 | @@ -612,64 +680,37 @@ | |||
333 | 612 | exec = tmp; | 680 | exec = tmp; |
334 | 613 | } | 681 | } |
335 | 614 | 682 | ||
339 | 615 | char *name = g_build_filename (directory, parts[0], NULL); | 683 | filename = g_build_filename (directory, parts[0], NULL); |
337 | 616 | filename = g_string_new (name); | ||
338 | 617 | g_free ((gpointer) name); | ||
340 | 618 | 684 | ||
341 | 619 | desktop_id = g_string_new (parts[0]); | 685 | desktop_id = g_string_new (parts[0]); |
342 | 620 | g_string_truncate (desktop_id, desktop_id->len - 8); | 686 | g_string_truncate (desktop_id, desktop_id->len - 8); |
343 | 621 | 687 | ||
346 | 622 | insert_data_into_tables (self, filename->str, exec, desktop_id->str, desktop_file_table, desktop_id_table); | 688 | insert_data_into_tables (self, filename, exec, desktop_id->str, desktop_file_table, desktop_id_table); |
347 | 623 | insert_desktop_file_class_into_table (self, filename->str, desktop_class_table); | 689 | insert_desktop_file_class_into_table (self, filename, desktop_class_table); |
348 | 624 | 690 | ||
349 | 625 | g_string_free (desktop_id, TRUE); | 691 | g_string_free (desktop_id, TRUE); |
350 | 692 | g_free (filename); | ||
351 | 693 | g_strfreev (parts); | ||
352 | 626 | length = 0; | 694 | length = 0; |
353 | 627 | g_strfreev (parts); | ||
354 | 628 | } | 695 | } |
356 | 629 | g_free ((gpointer) directory); | 696 | |
357 | 697 | g_object_unref (input); | ||
358 | 698 | g_object_unref (stream); | ||
359 | 699 | g_object_unref (file); | ||
360 | 700 | g_free (directory); | ||
361 | 630 | } | 701 | } |
362 | 631 | 702 | ||
363 | 703 | static GList * get_directory_tree_list (GList *) G_GNUC_WARN_UNUSED_RESULT; | ||
364 | 704 | |||
365 | 632 | static GList * | 705 | static GList * |
367 | 633 | get_desktop_file_directories (BamfMatcher *self) | 706 | get_directory_tree_list (GList *dirs) |
368 | 634 | { | 707 | { |
369 | 708 | GList *l; | ||
370 | 635 | GFile *file; | 709 | GFile *file; |
371 | 710 | GFileEnumerator *enumerator; | ||
372 | 636 | GFileInfo *info; | 711 | GFileInfo *info; |
409 | 637 | GFileEnumerator *enumerator; | 712 | gchar *path, *subpath; |
410 | 638 | GList *dirs = NULL, *l; | 713 | |
375 | 639 | const char *env; | ||
376 | 640 | char *path; | ||
377 | 641 | char *subpath; | ||
378 | 642 | char **data_dirs = NULL; | ||
379 | 643 | char **data; | ||
380 | 644 | |||
381 | 645 | env = g_getenv ("XDG_DATA_DIRS"); | ||
382 | 646 | |||
383 | 647 | if (env) | ||
384 | 648 | { | ||
385 | 649 | data_dirs = g_strsplit (env, ":", 0); | ||
386 | 650 | |||
387 | 651 | for (data = data_dirs; *data; data++) | ||
388 | 652 | { | ||
389 | 653 | path = g_build_filename (*data, "applications", NULL); | ||
390 | 654 | if (g_file_test (path, G_FILE_TEST_IS_DIR)) | ||
391 | 655 | dirs = g_list_prepend (dirs, path); | ||
392 | 656 | else | ||
393 | 657 | g_free (path); | ||
394 | 658 | } | ||
395 | 659 | } | ||
396 | 660 | |||
397 | 661 | if (!g_list_find_custom (dirs, "/usr/share/applications", (GCompareFunc) g_strcmp0)) | ||
398 | 662 | dirs = g_list_prepend (dirs, g_strdup ("/usr/share/applications")); | ||
399 | 663 | |||
400 | 664 | if (!g_list_find_custom (dirs, "/usr/local/share/applications", (GCompareFunc) g_strcmp0)) | ||
401 | 665 | dirs = g_list_prepend (dirs, g_strdup ("/usr/local/share/applications")); | ||
402 | 666 | |||
403 | 667 | dirs = g_list_prepend (dirs, g_strdup (g_build_filename (g_get_home_dir (), ".local/share/applications", NULL))); | ||
404 | 668 | |||
405 | 669 | if (data_dirs) | ||
406 | 670 | g_strfreev (data_dirs); | ||
407 | 671 | |||
408 | 672 | /* include subdirs */ | ||
411 | 673 | for (l = dirs; l; l = l->next) | 714 | for (l = dirs; l; l = l->next) |
412 | 674 | { | 715 | { |
413 | 675 | path = l->data; | 716 | path = l->data; |
414 | @@ -698,8 +739,10 @@ | |||
415 | 698 | continue; | 739 | continue; |
416 | 699 | 740 | ||
417 | 700 | subpath = g_build_filename (path, g_file_info_get_name (info), NULL); | 741 | subpath = g_build_filename (path, g_file_info_get_name (info), NULL); |
420 | 701 | /* append for non-recursive recursion love */ | 742 | /* append after the current list item for non-recursive recursion love |
421 | 702 | dirs = g_list_append (dirs, subpath); | 743 | * and to keep the priorities (hierarchy) of the .desktop directories. |
422 | 744 | */ | ||
423 | 745 | dirs = g_list_insert_before (dirs, l->next, subpath); | ||
424 | 703 | 746 | ||
425 | 704 | g_object_unref (info); | 747 | g_object_unref (info); |
426 | 705 | } | 748 | } |
427 | @@ -707,42 +750,255 @@ | |||
428 | 707 | g_object_unref (enumerator); | 750 | g_object_unref (enumerator); |
429 | 708 | g_object_unref (file); | 751 | g_object_unref (file); |
430 | 709 | } | 752 | } |
433 | 710 | 753 | ||
434 | 711 | return dirs; | 754 | return dirs; |
435 | 755 | } | ||
436 | 756 | |||
437 | 757 | static GList * get_desktop_file_env_directories (GList *, const gchar *) G_GNUC_WARN_UNUSED_RESULT; | ||
438 | 758 | |||
439 | 759 | static GList * | ||
440 | 760 | get_desktop_file_env_directories (GList *dirs, const gchar *varname) | ||
441 | 761 | { | ||
442 | 762 | g_return_val_if_fail (varname, dirs); | ||
443 | 763 | |||
444 | 764 | const gchar *env; | ||
445 | 765 | char *path; | ||
446 | 766 | char **data_dirs = NULL; | ||
447 | 767 | char **data; | ||
448 | 768 | |||
449 | 769 | env = g_getenv (varname); | ||
450 | 770 | |||
451 | 771 | if (env) | ||
452 | 772 | { | ||
453 | 773 | data_dirs = g_strsplit (env, ":", 0); | ||
454 | 774 | |||
455 | 775 | for (data = data_dirs; *data; data++) | ||
456 | 776 | { | ||
457 | 777 | path = g_build_filename (*data, "applications", NULL); | ||
458 | 778 | if (g_file_test (path, G_FILE_TEST_IS_DIR) && | ||
459 | 779 | !g_list_find_custom (dirs, path, (GCompareFunc) g_strcmp0)) | ||
460 | 780 | { | ||
461 | 781 | dirs = g_list_prepend (dirs, path); | ||
462 | 782 | } | ||
463 | 783 | else | ||
464 | 784 | { | ||
465 | 785 | g_free (path); | ||
466 | 786 | } | ||
467 | 787 | } | ||
468 | 788 | |||
469 | 789 | if (data_dirs) | ||
470 | 790 | g_strfreev (data_dirs); | ||
471 | 791 | } | ||
472 | 792 | |||
473 | 793 | return dirs; | ||
474 | 794 | } | ||
475 | 795 | |||
476 | 796 | static GList * | ||
477 | 797 | get_desktop_file_directories (BamfMatcher *self) | ||
478 | 798 | { | ||
479 | 799 | GList *dirs = NULL; | ||
480 | 800 | char *path; | ||
481 | 801 | |||
482 | 802 | dirs = get_desktop_file_env_directories(dirs, "XDG_DATA_DIRS"); | ||
483 | 803 | |||
484 | 804 | if (!g_list_find_custom (dirs, "/usr/share/applications", (GCompareFunc) g_strcmp0)) | ||
485 | 805 | dirs = g_list_prepend (dirs, g_strdup ("/usr/share/applications")); | ||
486 | 806 | |||
487 | 807 | if (!g_list_find_custom (dirs, "/usr/local/share/applications", (GCompareFunc) g_strcmp0)) | ||
488 | 808 | dirs = g_list_prepend (dirs, g_strdup ("/usr/local/share/applications")); | ||
489 | 809 | |||
490 | 810 | dirs = get_desktop_file_env_directories(dirs, "XDG_DATA_HOME"); | ||
491 | 811 | |||
492 | 812 | path = g_build_filename (g_get_home_dir (), ".local/share/applications", NULL); | ||
493 | 813 | |||
494 | 814 | if (!g_list_find_custom (dirs, path, (GCompareFunc) g_strcmp0)) | ||
495 | 815 | dirs = g_list_prepend (dirs, path); | ||
496 | 816 | else | ||
497 | 817 | g_free (path); | ||
498 | 818 | |||
499 | 819 | /* include subdirs */ | ||
500 | 820 | dirs = get_directory_tree_list (dirs); | ||
501 | 821 | |||
502 | 822 | /* Include also the user desktop folder, but without its subfolders */ | ||
503 | 823 | dirs = g_list_prepend (dirs, g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP))); | ||
504 | 824 | |||
505 | 825 | return dirs; | ||
506 | 826 | } | ||
507 | 827 | |||
508 | 828 | static gint | ||
509 | 829 | compare_sub_values (gconstpointer desktop_path, gconstpointer desktop_file) | ||
510 | 830 | { | ||
511 | 831 | return !g_str_has_prefix (desktop_file, desktop_path); | ||
512 | 832 | } | ||
513 | 833 | |||
514 | 834 | static void | ||
515 | 835 | hash_table_remove_sub_values (GHashTable *htable, GCompareFunc compare_func, | ||
516 | 836 | GFreeFunc free_func, gpointer target, gboolean search_all) | ||
517 | 837 | { | ||
518 | 838 | g_return_if_fail (htable); | ||
519 | 839 | g_return_if_fail (compare_func); | ||
520 | 840 | |||
521 | 841 | GHashTableIter iter; | ||
522 | 842 | gpointer key; | ||
523 | 843 | gpointer value; | ||
524 | 844 | |||
525 | 845 | g_hash_table_iter_init (&iter, htable); | ||
526 | 846 | |||
527 | 847 | while (g_hash_table_iter_next (&iter, &key, &value)) | ||
528 | 848 | { | ||
529 | 849 | GList *list, *l; | ||
530 | 850 | gboolean found; | ||
531 | 851 | |||
532 | 852 | list = value; | ||
533 | 853 | found = FALSE; | ||
534 | 854 | |||
535 | 855 | l = list; | ||
536 | 856 | while (l) | ||
537 | 857 | { | ||
538 | 858 | GList *next = l->next; | ||
539 | 859 | |||
540 | 860 | if (compare_func (target, l->data) == 0) | ||
541 | 861 | { | ||
542 | 862 | found = TRUE; | ||
543 | 863 | |||
544 | 864 | if (!l->prev && !l->next) | ||
545 | 865 | { | ||
546 | 866 | if (free_func) | ||
547 | 867 | g_list_free_full (list, free_func); | ||
548 | 868 | else | ||
549 | 869 | g_list_free (list); | ||
550 | 870 | |||
551 | 871 | g_hash_table_iter_remove (&iter); | ||
552 | 872 | |||
553 | 873 | next = NULL; | ||
554 | 874 | break; | ||
555 | 875 | } | ||
556 | 876 | else | ||
557 | 877 | { | ||
558 | 878 | if (free_func) | ||
559 | 879 | free_func (l->data); | ||
560 | 880 | |||
561 | 881 | /* If the target is the first element of the list (and thanks to | ||
562 | 882 | - * the previous check we're also sure that it's not the only one), | ||
563 | 883 | * simply switch it with its follower, not to change the first | ||
564 | 884 | * pointer and the hash table value for key | ||
565 | 885 | */ | ||
566 | 886 | if (l == list) | ||
567 | 887 | { | ||
568 | 888 | l->data = next->data; | ||
569 | 889 | l = next; | ||
570 | 890 | next = list; | ||
571 | 891 | } | ||
572 | 892 | |||
573 | 893 | list = g_list_delete_link (list, l); | ||
574 | 894 | } | ||
575 | 895 | |||
576 | 896 | if (!search_all) | ||
577 | 897 | break; | ||
578 | 898 | } | ||
579 | 899 | l = next; | ||
580 | 900 | } | ||
581 | 901 | |||
582 | 902 | if (found && !search_all) | ||
583 | 903 | break; | ||
584 | 904 | } | ||
585 | 712 | } | 905 | } |
586 | 713 | 906 | ||
587 | 714 | static gboolean | 907 | static gboolean |
589 | 715 | hash_table_remove_values (gpointer key, gpointer value, gpointer target) | 908 | hash_table_compare_sub_values (gpointer desktop_path, gpointer desktop_class, gpointer target_path) |
590 | 716 | { | 909 | { |
592 | 717 | return g_strcmp0 ((char *) value, (char *) target) == 0; | 910 | return !compare_sub_values (target_path, desktop_path); |
593 | 718 | } | 911 | } |
594 | 719 | 912 | ||
595 | 913 | static void fill_desktop_file_table (BamfMatcher *, GList *, GHashTable *, GHashTable *, GHashTable *); | ||
596 | 914 | |||
597 | 720 | static void | 915 | static void |
598 | 721 | on_monitor_changed (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent type, BamfMatcher *self) | 916 | on_monitor_changed (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent type, BamfMatcher *self) |
599 | 722 | { | 917 | { |
600 | 723 | char *path; | 918 | char *path; |
601 | 919 | const char *monitored_dir; | ||
602 | 920 | GFileType filetype; | ||
603 | 724 | 921 | ||
604 | 725 | g_return_if_fail (G_IS_FILE_MONITOR (monitor)); | 922 | g_return_if_fail (G_IS_FILE_MONITOR (monitor)); |
605 | 726 | g_return_if_fail (BAMF_IS_MATCHER (self)); | ||
606 | 727 | |||
607 | 728 | if (type != G_FILE_MONITOR_EVENT_CHANGED && type != G_FILE_MONITOR_EVENT_DELETED) | ||
608 | 729 | return; | ||
609 | 730 | |||
610 | 731 | g_return_if_fail (G_IS_FILE (file)); | 923 | g_return_if_fail (G_IS_FILE (file)); |
611 | 924 | g_return_if_fail (BAMF_IS_MATCHER (self)); | ||
612 | 925 | |||
613 | 926 | if (type != G_FILE_MONITOR_EVENT_CREATED && | ||
614 | 927 | type != G_FILE_MONITOR_EVENT_DELETED && | ||
615 | 928 | type != G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT) | ||
616 | 929 | return; | ||
617 | 930 | |||
618 | 732 | path = g_file_get_path (file); | 931 | path = g_file_get_path (file); |
619 | 932 | filetype = g_file_query_file_type (file, G_FILE_QUERY_INFO_NONE, NULL); | ||
620 | 933 | monitored_dir = g_object_get_data (G_OBJECT (monitor), "root"); | ||
621 | 733 | 934 | ||
623 | 734 | if (!g_str_has_suffix (path, ".desktop")) | 935 | if (!g_str_has_suffix (path, ".desktop") && |
624 | 936 | filetype != G_FILE_TYPE_DIRECTORY && | ||
625 | 937 | type != G_FILE_MONITOR_EVENT_DELETED) | ||
626 | 735 | goto out; | 938 | goto out; |
627 | 939 | |||
628 | 940 | if (type == G_FILE_MONITOR_EVENT_DELETED || | ||
629 | 941 | type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT) | ||
630 | 942 | { | ||
631 | 943 | if (g_str_has_suffix (path, ".desktop")) | ||
632 | 944 | { | ||
633 | 945 | /* Remove all the .desktop file referencies from the hash tables. | ||
634 | 946 | * Free the string itself only on the 2nd pass (tables share the same | ||
635 | 947 | * string instance) | ||
636 | 948 | */ | ||
637 | 949 | hash_table_remove_sub_values (self->priv->desktop_id_table, | ||
638 | 950 | (GCompareFunc) g_strcmp0, NULL, path, FALSE); | ||
639 | 951 | hash_table_remove_sub_values (self->priv->desktop_file_table, | ||
640 | 952 | (GCompareFunc) g_strcmp0, g_free, path, FALSE); | ||
641 | 953 | g_hash_table_remove (self->priv->desktop_class_table, path); | ||
642 | 954 | } | ||
643 | 955 | else if (g_strcmp0 (monitored_dir, path) == 0) | ||
644 | 956 | { | ||
645 | 957 | /* Remove all the referencies to the .desktop files placed in subfolders | ||
646 | 958 | * of the current path. Free the strings itself only on the 2nd pass | ||
647 | 959 | * (as before, the tables share the same string instance) | ||
648 | 960 | */ | ||
649 | 961 | char *prefix = g_strconcat (path, G_DIR_SEPARATOR_S, NULL); | ||
650 | 962 | |||
651 | 963 | hash_table_remove_sub_values (self->priv->desktop_id_table, | ||
652 | 964 | compare_sub_values, NULL, prefix, TRUE); | ||
653 | 965 | hash_table_remove_sub_values (self->priv->desktop_file_table, | ||
654 | 966 | compare_sub_values, g_free, prefix, TRUE); | ||
655 | 967 | g_hash_table_foreach_remove (self->priv->desktop_class_table, | ||
656 | 968 | hash_table_compare_sub_values, prefix); | ||
657 | 969 | |||
658 | 970 | g_signal_handlers_disconnect_by_func (monitor, on_monitor_changed, self); | ||
659 | 971 | self->priv->monitors = g_list_remove (self->priv->monitors, monitor); | ||
660 | 972 | g_object_unref (monitor); | ||
661 | 973 | g_free (prefix); | ||
662 | 974 | } | ||
663 | 975 | } | ||
664 | 976 | |||
665 | 977 | if (type == G_FILE_MONITOR_EVENT_CREATED || | ||
666 | 978 | type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT) | ||
667 | 979 | { | ||
668 | 980 | if (filetype == G_FILE_TYPE_DIRECTORY) | ||
669 | 981 | { | ||
670 | 982 | const char *desktop_dir; | ||
671 | 983 | desktop_dir = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); | ||
672 | 984 | |||
673 | 985 | if (g_strcmp0 (monitored_dir, desktop_dir) != 0) | ||
674 | 986 | { | ||
675 | 987 | GList *dirs = NULL; | ||
676 | 988 | dirs = g_list_prepend (dirs, g_strdup (path)); | ||
677 | 989 | dirs = get_directory_tree_list (dirs); | ||
678 | 990 | fill_desktop_file_table (self, dirs, | ||
679 | 991 | self->priv->desktop_file_table, | ||
680 | 992 | self->priv->desktop_id_table, | ||
681 | 993 | self->priv->desktop_class_table); | ||
682 | 736 | 994 | ||
692 | 737 | if (type == G_FILE_MONITOR_EVENT_CREATED) | 995 | g_list_free_full (dirs, (GDestroyNotify) g_free); |
693 | 738 | { | 996 | } |
694 | 739 | bamf_matcher_load_desktop_file (self, path); | 997 | } |
695 | 740 | } | 998 | else if (filetype != G_FILE_TYPE_UNKNOWN) |
696 | 741 | else if (type == G_FILE_MONITOR_EVENT_DELETED) | 999 | { |
697 | 742 | { | 1000 | bamf_matcher_load_desktop_file (self, path); |
698 | 743 | g_hash_table_foreach_remove (self->priv->desktop_id_table, (GHRFunc) hash_table_remove_values, path); | 1001 | } |
690 | 744 | g_hash_table_foreach_remove (self->priv->desktop_file_table, (GHRFunc) hash_table_remove_values, path); | ||
691 | 745 | g_hash_table_remove (self->priv->desktop_class_table, path); | ||
699 | 746 | } | 1002 | } |
700 | 747 | 1003 | ||
701 | 748 | out: | 1004 | out: |
702 | @@ -750,17 +1006,71 @@ | |||
703 | 750 | } | 1006 | } |
704 | 751 | 1007 | ||
705 | 752 | static void | 1008 | static void |
706 | 1009 | bamf_add_new_monitored_directory (BamfMatcher * self, const gchar *directory) | ||
707 | 1010 | { | ||
708 | 1011 | g_return_if_fail (BAMF_IS_MATCHER (self)); | ||
709 | 1012 | |||
710 | 1013 | GFile *file; | ||
711 | 1014 | GFileMonitor *monitor; | ||
712 | 1015 | |||
713 | 1016 | file = g_file_new_for_path (directory); | ||
714 | 1017 | monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL); | ||
715 | 1018 | g_file_monitor_set_rate_limit (monitor, 1000); | ||
716 | 1019 | g_object_set_data_full (G_OBJECT (monitor), "root", g_strdup (directory), g_free); | ||
717 | 1020 | g_signal_connect (monitor, "changed", (GCallback) on_monitor_changed, self); | ||
718 | 1021 | self->priv->monitors = g_list_prepend (self->priv->monitors, monitor); | ||
719 | 1022 | |||
720 | 1023 | g_object_unref (file); | ||
721 | 1024 | } | ||
722 | 1025 | |||
723 | 1026 | static void | ||
724 | 1027 | fill_desktop_file_table (BamfMatcher * self, | ||
725 | 1028 | GList *directories, | ||
726 | 1029 | GHashTable *desktop_file_table, | ||
727 | 1030 | GHashTable *desktop_id_table, | ||
728 | 1031 | GHashTable *desktop_class_table) | ||
729 | 1032 | { | ||
730 | 1033 | g_return_if_fail (BAMF_IS_MATCHER (self)); | ||
731 | 1034 | |||
732 | 1035 | GList *l; | ||
733 | 1036 | char *directory; | ||
734 | 1037 | char *bamf_file; | ||
735 | 1038 | |||
736 | 1039 | for (l = directories; l; l = l->next) | ||
737 | 1040 | { | ||
738 | 1041 | directory = l->data; | ||
739 | 1042 | |||
740 | 1043 | if (!g_file_test (directory, G_FILE_TEST_IS_DIR)) | ||
741 | 1044 | continue; | ||
742 | 1045 | |||
743 | 1046 | bamf_add_new_monitored_directory (self, directory); | ||
744 | 1047 | |||
745 | 1048 | bamf_file = g_build_filename (directory, "bamf.index", NULL); | ||
746 | 1049 | |||
747 | 1050 | if (g_file_test (bamf_file, G_FILE_TEST_EXISTS)) | ||
748 | 1051 | { | ||
749 | 1052 | load_index_file_to_table (self, bamf_file, desktop_file_table, | ||
750 | 1053 | desktop_id_table, desktop_class_table); | ||
751 | 1054 | } | ||
752 | 1055 | else | ||
753 | 1056 | { | ||
754 | 1057 | load_directory_to_table (self, directory, desktop_file_table, | ||
755 | 1058 | desktop_id_table, desktop_class_table); | ||
756 | 1059 | } | ||
757 | 1060 | |||
758 | 1061 | g_free (bamf_file); | ||
759 | 1062 | } | ||
760 | 1063 | } | ||
761 | 1064 | |||
762 | 1065 | static void | ||
763 | 753 | create_desktop_file_table (BamfMatcher * self, | 1066 | create_desktop_file_table (BamfMatcher * self, |
764 | 754 | GHashTable **desktop_file_table, | 1067 | GHashTable **desktop_file_table, |
765 | 755 | GHashTable **desktop_id_table, | 1068 | GHashTable **desktop_id_table, |
766 | 756 | GHashTable **desktop_class_table) | 1069 | GHashTable **desktop_class_table) |
767 | 757 | { | 1070 | { |
768 | 1071 | g_return_if_fail (BAMF_IS_MATCHER (self)); | ||
769 | 1072 | |||
770 | 758 | GList *directories; | 1073 | GList *directories; |
771 | 759 | GList *l; | ||
772 | 760 | char *directory; | ||
773 | 761 | const char *bamf_file; | ||
774 | 762 | GFile *file; | ||
775 | 763 | GFileMonitor *monitor; | ||
776 | 764 | 1074 | ||
777 | 765 | *desktop_file_table = | 1075 | *desktop_file_table = |
778 | 766 | g_hash_table_new_full ((GHashFunc) g_str_hash, | 1076 | g_hash_table_new_full ((GHashFunc) g_str_hash, |
779 | @@ -778,44 +1088,14 @@ | |||
780 | 778 | g_hash_table_new_full ((GHashFunc) g_str_hash, | 1088 | g_hash_table_new_full ((GHashFunc) g_str_hash, |
781 | 779 | (GEqualFunc) g_str_equal, | 1089 | (GEqualFunc) g_str_equal, |
782 | 780 | (GDestroyNotify) g_free, | 1090 | (GDestroyNotify) g_free, |
786 | 781 | (GDestroyNotify) g_free); | 1091 | (GDestroyNotify) g_free); |
784 | 782 | |||
785 | 783 | g_return_if_fail (BAMF_IS_MATCHER (self)); | ||
787 | 784 | 1092 | ||
788 | 785 | directories = get_desktop_file_directories (self); | 1093 | directories = get_desktop_file_directories (self); |
789 | 786 | 1094 | ||
820 | 787 | for (l = directories; l; l = l->next) | 1095 | fill_desktop_file_table (self, directories, *desktop_file_table, |
821 | 788 | { | 1096 | *desktop_id_table, *desktop_class_table); |
792 | 789 | directory = l->data; | ||
793 | 790 | |||
794 | 791 | if (!g_file_test (directory, G_FILE_TEST_IS_DIR)) | ||
795 | 792 | continue; | ||
796 | 793 | |||
797 | 794 | file = g_file_new_for_path (directory); | ||
798 | 795 | monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL); | ||
799 | 796 | |||
800 | 797 | self->priv->monitors = g_list_prepend (self->priv->monitors, monitor); | ||
801 | 798 | |||
802 | 799 | g_signal_connect (monitor, "changed", (GCallback) on_monitor_changed, self); | ||
803 | 800 | |||
804 | 801 | bamf_file = g_build_filename (directory, "bamf.index", NULL); | ||
805 | 802 | |||
806 | 803 | if (g_file_test (bamf_file, G_FILE_TEST_EXISTS)) | ||
807 | 804 | { | ||
808 | 805 | load_index_file_to_table (self, bamf_file, *desktop_file_table, | ||
809 | 806 | *desktop_id_table, *desktop_class_table); | ||
810 | 807 | } | ||
811 | 808 | else | ||
812 | 809 | { | ||
813 | 810 | load_directory_to_table (self, directory, *desktop_file_table, | ||
814 | 811 | *desktop_id_table, *desktop_class_table); | ||
815 | 812 | } | ||
816 | 813 | |||
817 | 814 | g_free (directory); | ||
818 | 815 | g_free ((gpointer) bamf_file); | ||
819 | 816 | } | ||
822 | 817 | 1097 | ||
824 | 818 | g_list_free (directories); | 1098 | g_list_free_full (directories, (GDestroyNotify) g_free); |
825 | 819 | } | 1099 | } |
826 | 820 | 1100 | ||
827 | 821 | static gboolean | 1101 | static gboolean |
828 | @@ -861,17 +1141,17 @@ | |||
829 | 861 | atom = XInternAtom (XDisplay, atom_name, FALSE); | 1141 | atom = XInternAtom (XDisplay, atom_name, FALSE); |
830 | 862 | 1142 | ||
831 | 863 | int result = XGetWindowProperty (XDisplay, | 1143 | int result = XGetWindowProperty (XDisplay, |
843 | 864 | (gulong) bamf_legacy_window_get_xid (window), | 1144 | (gulong) bamf_legacy_window_get_xid (window), |
844 | 865 | atom, | 1145 | atom, |
845 | 866 | 0, | 1146 | 0, |
846 | 867 | G_MAXINT, | 1147 | G_MAXINT, |
847 | 868 | FALSE, | 1148 | FALSE, |
848 | 869 | XA_STRING, | 1149 | XA_STRING, |
849 | 870 | &type, | 1150 | &type, |
850 | 871 | &format, | 1151 | &format, |
851 | 872 | &numItems, | 1152 | &numItems, |
852 | 873 | &bytesAfter, | 1153 | &bytesAfter, |
853 | 874 | &buffer); | 1154 | &buffer); |
854 | 875 | 1155 | ||
855 | 876 | if (close_display) | 1156 | if (close_display) |
856 | 877 | XCloseDisplay (XDisplay); | 1157 | XCloseDisplay (XDisplay); |
857 | @@ -912,24 +1192,18 @@ | |||
858 | 912 | } | 1192 | } |
859 | 913 | 1193 | ||
860 | 914 | XChangeProperty (XDisplay, | 1194 | XChangeProperty (XDisplay, |
870 | 915 | bamf_legacy_window_get_xid (window), | 1195 | bamf_legacy_window_get_xid (window), |
871 | 916 | XInternAtom (XDisplay, | 1196 | XInternAtom (XDisplay, |
872 | 917 | atom_name, | 1197 | atom_name, |
873 | 918 | FALSE), | 1198 | FALSE), |
874 | 919 | XA_STRING, | 1199 | XA_STRING, |
875 | 920 | 8, | 1200 | 8, |
876 | 921 | PropModeReplace, | 1201 | PropModeReplace, |
877 | 922 | (unsigned char *) data, | 1202 | (unsigned char *) data, |
878 | 923 | strlen (data)); | 1203 | strlen (data)); |
879 | 924 | 1204 | ||
880 | 925 | if (close_display) | 1205 | if (close_display) |
888 | 926 | XCloseDisplay (XDisplay); | 1206 | XCloseDisplay (XDisplay); |
882 | 927 | } | ||
883 | 928 | |||
884 | 929 | static char* | ||
885 | 930 | window_class_name (BamfLegacyWindow *window) | ||
886 | 931 | { | ||
887 | 932 | return g_strdup (bamf_legacy_window_get_class_name (window)); | ||
889 | 933 | } | 1207 | } |
890 | 934 | 1208 | ||
891 | 935 | static char * | 1209 | static char * |
892 | @@ -951,7 +1225,7 @@ | |||
893 | 951 | { | 1225 | { |
894 | 952 | g_string_append (exec, argv[i]); | 1226 | g_string_append (exec, argv[i]); |
895 | 953 | if (argv[i + 1] != NULL) | 1227 | if (argv[i + 1] != NULL) |
897 | 954 | g_string_append (exec, " "); | 1228 | g_string_append (exec, " "); |
898 | 955 | g_free (argv[i]); | 1229 | g_free (argv[i]); |
899 | 956 | i++; | 1230 | i++; |
900 | 957 | } | 1231 | } |
901 | @@ -1084,7 +1358,7 @@ | |||
902 | 1084 | } | 1358 | } |
903 | 1085 | else | 1359 | else |
904 | 1086 | { | 1360 | { |
906 | 1087 | char *window_class = window_class_name (window); | 1361 | const char *window_class = bamf_legacy_window_get_class_name (window); |
907 | 1088 | 1362 | ||
908 | 1089 | char *desktop_file; | 1363 | char *desktop_file; |
909 | 1090 | char *desktop_class; | 1364 | char *desktop_class; |
910 | @@ -1098,6 +1372,7 @@ | |||
911 | 1098 | for (; l; l = l->next) | 1372 | for (; l; l = l->next) |
912 | 1099 | { | 1373 | { |
913 | 1100 | desktop_file = l->data; | 1374 | desktop_file = l->data; |
914 | 1375 | |||
915 | 1101 | if (desktop_file) | 1376 | if (desktop_file) |
916 | 1102 | { | 1377 | { |
917 | 1103 | desktop_class = g_hash_table_lookup (priv->desktop_class_table, desktop_file); | 1378 | desktop_class = g_hash_table_lookup (priv->desktop_class_table, desktop_file); |
918 | @@ -1128,6 +1403,10 @@ | |||
919 | 1128 | { | 1403 | { |
920 | 1129 | desktop_files = g_list_prepend (desktop_files, desktop_file); | 1404 | desktop_files = g_list_prepend (desktop_files, desktop_file); |
921 | 1130 | } | 1405 | } |
922 | 1406 | else | ||
923 | 1407 | { | ||
924 | 1408 | g_free (desktop_file); | ||
925 | 1409 | } | ||
926 | 1131 | } | 1410 | } |
927 | 1132 | 1411 | ||
928 | 1133 | pid = bamf_legacy_window_get_pid (window); | 1412 | pid = bamf_legacy_window_get_pid (window); |
929 | @@ -1139,26 +1418,56 @@ | |||
930 | 1139 | for (l = pid_list; l; l = l->next) | 1418 | for (l = pid_list; l; l = l->next) |
931 | 1140 | { | 1419 | { |
932 | 1141 | desktop_file = l->data; | 1420 | desktop_file = l->data; |
935 | 1142 | if (g_list_find_custom (desktop_files, l->data, (GCompareFunc) g_strcmp0)) | 1421 | if (g_list_find_custom (desktop_files, desktop_file, (GCompareFunc) g_strcmp0)) |
936 | 1143 | g_free (desktop_file); | 1422 | { |
937 | 1423 | g_free (desktop_file); | ||
938 | 1424 | } | ||
939 | 1144 | else | 1425 | else |
940 | 1145 | { | 1426 | { |
941 | 1427 | gboolean append = FALSE; | ||
942 | 1428 | |||
943 | 1146 | if (window_class) | 1429 | if (window_class) |
944 | 1147 | { | 1430 | { |
945 | 1148 | desktop_class = g_hash_table_lookup (priv->desktop_class_table, desktop_file); | 1431 | desktop_class = g_hash_table_lookup (priv->desktop_class_table, desktop_file); |
955 | 1149 | if ((desktop_class == NULL || g_strcmp0 (desktop_class, window_class) == 0) && | 1432 | if (desktop_class == NULL || g_strcmp0 (desktop_class, window_class) == 0) |
956 | 1150 | !g_list_find_custom (desktop_files, desktop_file, | 1433 | { |
957 | 1151 | (GCompareFunc) g_strcmp0)) | 1434 | append = TRUE; |
958 | 1152 | { | 1435 | } |
959 | 1153 | desktop_files = g_list_append (desktop_files, desktop_file); | 1436 | } |
960 | 1154 | } | 1437 | else |
961 | 1155 | } | 1438 | { |
962 | 1156 | else | 1439 | append = TRUE; |
963 | 1157 | desktop_files = g_list_append (desktop_files, desktop_file); | 1440 | } |
964 | 1441 | |||
965 | 1442 | if (append) | ||
966 | 1443 | { | ||
967 | 1444 | /* If we're adding a .desktop file stored in the desktop folder, | ||
968 | 1445 | give it the priority it should have. */ | ||
969 | 1446 | GList *last = NULL; | ||
970 | 1447 | |||
971 | 1448 | if (is_desktop_folder_item (desktop_file, -1)) | ||
972 | 1449 | { | ||
973 | 1450 | GList *ll; | ||
974 | 1451 | |||
975 | 1452 | for (ll = desktop_files; ll; ll = ll->next) | ||
976 | 1453 | { | ||
977 | 1454 | if (!is_desktop_folder_item (ll->data, -1)) | ||
978 | 1455 | { | ||
979 | 1456 | last = ll; | ||
980 | 1457 | break; | ||
981 | 1458 | } | ||
982 | 1459 | } | ||
983 | 1460 | } | ||
984 | 1461 | |||
985 | 1462 | desktop_files = g_list_insert_before (desktop_files, last, desktop_file); | ||
986 | 1463 | } | ||
987 | 1464 | else | ||
988 | 1465 | { | ||
989 | 1466 | g_free (desktop_file); | ||
990 | 1467 | } | ||
991 | 1158 | } | 1468 | } |
992 | 1159 | } | 1469 | } |
993 | 1160 | 1470 | ||
994 | 1161 | g_free (window_class); | ||
995 | 1162 | g_list_free (pid_list); | 1471 | g_list_free (pid_list); |
996 | 1163 | } | 1472 | } |
997 | 1164 | 1473 | ||
998 | @@ -1172,8 +1481,8 @@ | |||
999 | 1172 | GList *possible_apps, *l; | 1481 | GList *possible_apps, *l; |
1000 | 1173 | BamfLegacyWindow *window; | 1482 | BamfLegacyWindow *window; |
1001 | 1174 | GList *views, *a; | 1483 | GList *views, *a; |
1002 | 1484 | const char *win_class; | ||
1003 | 1175 | char *desktop_file; | 1485 | char *desktop_file; |
1004 | 1176 | char *win_class; | ||
1005 | 1177 | char *app_class; | 1486 | char *app_class; |
1006 | 1178 | BamfApplication *app = NULL, *best = NULL; | 1487 | BamfApplication *app = NULL, *best = NULL; |
1007 | 1179 | BamfView *view; | 1488 | BamfView *view; |
1008 | @@ -1185,7 +1494,7 @@ | |||
1009 | 1185 | views = self->priv->views; | 1494 | views = self->priv->views; |
1010 | 1186 | 1495 | ||
1011 | 1187 | possible_apps = bamf_matcher_possible_applications_for_window (self, bamf_window); | 1496 | possible_apps = bamf_matcher_possible_applications_for_window (self, bamf_window); |
1013 | 1188 | win_class = window_class_name(window); | 1497 | win_class = bamf_legacy_window_get_class_name (window); |
1014 | 1189 | 1498 | ||
1015 | 1190 | /* Loop over every application, inside that application see if its .desktop file | 1499 | /* Loop over every application, inside that application see if its .desktop file |
1016 | 1191 | * matches with any of our possible hits. If so we match it. If we have no possible hits | 1500 | * matches with any of our possible hits. If so we match it. If we have no possible hits |
1017 | @@ -1200,7 +1509,6 @@ | |||
1018 | 1200 | 1509 | ||
1019 | 1201 | app = BAMF_APPLICATION (view); | 1510 | app = BAMF_APPLICATION (view); |
1020 | 1202 | app_class = bamf_application_get_wmclass (app); | 1511 | app_class = bamf_application_get_wmclass (app); |
1021 | 1203 | |||
1022 | 1204 | desktop_file = bamf_application_get_desktop_file (app); | 1512 | desktop_file = bamf_application_get_desktop_file (app); |
1023 | 1205 | 1513 | ||
1024 | 1206 | if (possible_apps) | 1514 | if (possible_apps) |
1025 | @@ -1242,8 +1550,6 @@ | |||
1026 | 1242 | g_object_unref (best); | 1550 | g_object_unref (best); |
1027 | 1243 | } | 1551 | } |
1028 | 1244 | 1552 | ||
1029 | 1245 | g_free (win_class); | ||
1030 | 1246 | |||
1031 | 1247 | for (l = possible_apps; l; l = l->next) | 1553 | for (l = possible_apps; l; l = l->next) |
1032 | 1248 | { | 1554 | { |
1033 | 1249 | char *str = l->data; | 1555 | char *str = l->data; |
1034 | @@ -1912,51 +2218,51 @@ | |||
1035 | 1912 | g_type_class_add_private (klass, sizeof (BamfMatcherPrivate)); | 2218 | g_type_class_add_private (klass, sizeof (BamfMatcherPrivate)); |
1036 | 1913 | 2219 | ||
1037 | 1914 | dbus_g_object_type_install_info (BAMF_TYPE_MATCHER, | 2220 | dbus_g_object_type_install_info (BAMF_TYPE_MATCHER, |
1039 | 1915 | &dbus_glib_bamf_matcher_object_info); | 2221 | &dbus_glib_bamf_matcher_object_info); |
1040 | 1916 | 2222 | ||
1041 | 1917 | matcher_signals [VIEW_OPENED] = | 2223 | matcher_signals [VIEW_OPENED] = |
1049 | 1918 | g_signal_new ("view-opened", | 2224 | g_signal_new ("view-opened", |
1050 | 1919 | G_OBJECT_CLASS_TYPE (klass), | 2225 | G_OBJECT_CLASS_TYPE (klass), |
1051 | 1920 | 0, | 2226 | 0, |
1052 | 1921 | 0, NULL, NULL, | 2227 | 0, NULL, NULL, |
1053 | 1922 | bamf_marshal_VOID__STRING_STRING, | 2228 | bamf_marshal_VOID__STRING_STRING, |
1054 | 1923 | G_TYPE_NONE, 2, | 2229 | G_TYPE_NONE, 2, |
1055 | 1924 | G_TYPE_STRING, G_TYPE_STRING); | 2230 | G_TYPE_STRING, G_TYPE_STRING); |
1056 | 1925 | 2231 | ||
1057 | 1926 | matcher_signals [VIEW_CLOSED] = | 2232 | matcher_signals [VIEW_CLOSED] = |
1065 | 1927 | g_signal_new ("view-closed", | 2233 | g_signal_new ("view-closed", |
1066 | 1928 | G_OBJECT_CLASS_TYPE (klass), | 2234 | G_OBJECT_CLASS_TYPE (klass), |
1067 | 1929 | 0, | 2235 | 0, |
1068 | 1930 | 0, NULL, NULL, | 2236 | 0, NULL, NULL, |
1069 | 1931 | bamf_marshal_VOID__STRING_STRING, | 2237 | bamf_marshal_VOID__STRING_STRING, |
1070 | 1932 | G_TYPE_NONE, 2, | 2238 | G_TYPE_NONE, 2, |
1071 | 1933 | G_TYPE_STRING, G_TYPE_STRING); | 2239 | G_TYPE_STRING, G_TYPE_STRING); |
1072 | 1934 | 2240 | ||
1073 | 1935 | matcher_signals [ACTIVE_APPLICATION_CHANGED] = | 2241 | matcher_signals [ACTIVE_APPLICATION_CHANGED] = |
1081 | 1936 | g_signal_new ("active-application-changed", | 2242 | g_signal_new ("active-application-changed", |
1082 | 1937 | G_OBJECT_CLASS_TYPE (klass), | 2243 | G_OBJECT_CLASS_TYPE (klass), |
1083 | 1938 | 0, | 2244 | 0, |
1084 | 1939 | 0, NULL, NULL, | 2245 | 0, NULL, NULL, |
1085 | 1940 | bamf_marshal_VOID__STRING_STRING, | 2246 | bamf_marshal_VOID__STRING_STRING, |
1086 | 1941 | G_TYPE_NONE, 2, | 2247 | G_TYPE_NONE, 2, |
1087 | 1942 | G_TYPE_STRING, G_TYPE_STRING); | 2248 | G_TYPE_STRING, G_TYPE_STRING); |
1088 | 1943 | 2249 | ||
1089 | 1944 | matcher_signals [ACTIVE_WINDOW_CHANGED] = | 2250 | matcher_signals [ACTIVE_WINDOW_CHANGED] = |
1098 | 1945 | g_signal_new ("active-window-changed", | 2251 | g_signal_new ("active-window-changed", |
1099 | 1946 | G_OBJECT_CLASS_TYPE (klass), | 2252 | G_OBJECT_CLASS_TYPE (klass), |
1100 | 1947 | 0, | 2253 | 0, |
1101 | 1948 | 0, NULL, NULL, | 2254 | 0, NULL, NULL, |
1102 | 1949 | bamf_marshal_VOID__STRING_STRING, | 2255 | bamf_marshal_VOID__STRING_STRING, |
1103 | 1950 | G_TYPE_NONE, 2, | 2256 | G_TYPE_NONE, 2, |
1104 | 1951 | G_TYPE_STRING, G_TYPE_STRING); | 2257 | G_TYPE_STRING, G_TYPE_STRING); |
1105 | 1952 | 2258 | ||
1106 | 1953 | matcher_signals [FAVORITES_CHANGED] = | 2259 | matcher_signals [FAVORITES_CHANGED] = |
1113 | 1954 | g_signal_new ("favorites-changed", | 2260 | g_signal_new ("favorites-changed", |
1114 | 1955 | G_OBJECT_CLASS_TYPE (klass), | 2261 | G_OBJECT_CLASS_TYPE (klass), |
1115 | 1956 | 0, | 2262 | 0, |
1116 | 1957 | 0, NULL, NULL, | 2263 | 0, NULL, NULL, |
1117 | 1958 | g_cclosure_marshal_VOID__VOID, | 2264 | g_cclosure_marshal_VOID__VOID, |
1118 | 1959 | G_TYPE_NONE, 0); | 2265 | G_TYPE_NONE, 0); |
1119 | 1960 | } | 2266 | } |
1120 | 1961 | 2267 | ||
1121 | 1962 | BamfMatcher * | 2268 | BamfMatcher * |
+1 looks good :)
runs well too!