Merge lp:~3v1n0/bamf/lib-factory-xids-matching into lp:bamf/0.4
- lib-factory-xids-matching
- Merge into 0.4
Status: | Merged |
---|---|
Approved by: | Marco Trevisan (Treviño) |
Approved revision: | 480 |
Merged at revision: | 462 |
Proposed branch: | lp:~3v1n0/bamf/lib-factory-xids-matching |
Merge into: | lp:bamf/0.4 |
Diff against target: |
892 lines (+410/-120) 9 files modified
lib/libbamf/Makefile.am (+1/-0) lib/libbamf/bamf-application-private.h (+30/-0) lib/libbamf/bamf-application.c (+71/-8) lib/libbamf/bamf-factory.c (+157/-44) lib/libbamf/bamf-factory.h (+17/-0) lib/libbamf/bamf-matcher.c (+68/-38) lib/libbamf/bamf-view-private.h (+2/-0) lib/libbamf/bamf-view.c (+62/-29) lib/libbamf/bamf-window.c (+2/-1) |
To merge this branch: | bzr merge lp:~3v1n0/bamf/lib-factory-xids-matching |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michal Hruby (community) | Approve | ||
Review via email: mp+103591@code.launchpad.net |
Commit message
BamfFactory: be more smart to re-associate a dbus path to a view using windows xid
Description of the change
BamfFactory has been improved adding the new bamf_factory_
Also now the factory now has been improved to re-associate the opened views to the new ones using the related windows xids. So basically when a new application has been opened, we initially try to re-associate it to the opened view with the same desktop file; if that check fails we fallback to the children windows xid comparison (if a view has at least a xid that matches the ones of the new application, then we consider them the same).
So, thanks to this both applications with .desktop files associated and applications with no desktop file can be re-used avoiding memory duplication and double launcher icon instances.
Tests covered by: lp:~3v1n0/unity/launcher-double-icons-tests
Michal Hruby (mhr3) wrote : | # |
Michal Hruby (mhr3) wrote : | # |
And unity also just complained about:
ERROR 2012-04-26 10:42:25 unity <unknown>:0 on_view_
Michal Hruby (mhr3) wrote : | # |
And one more thing - wouldn't it be better to use an enum in the bamf_factory_
- 479. By Marco Trevisan (Treviño)
-
libbamf, bamfview: disconect to the destroyed signal when needed
- 480. By Marco Trevisan (Treviño)
-
BamfFactory: use BamfFactoryViewType instead of strings comparisons when possible.
This cleans the code and is for sure more safe.
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
Ok, updated ;)
Michal Hruby (mhr3) wrote : | # |
Looking good to me, do we want to have this in SRU1?
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
Well... I'd like to.
Preview Diff
1 | === modified file 'lib/libbamf/Makefile.am' |
2 | --- lib/libbamf/Makefile.am 2012-01-20 15:33:59 +0000 |
3 | +++ lib/libbamf/Makefile.am 2012-04-26 17:14:21 +0000 |
4 | @@ -40,6 +40,7 @@ |
5 | |
6 | libbamf_la_SOURCES = \ |
7 | bamf-factory.h \ |
8 | + bamf-application-private.h \ |
9 | bamf-view-private.h \ |
10 | $(sources_h) \ |
11 | $(libbamf_sources) \ |
12 | |
13 | === added file 'lib/libbamf/bamf-application-private.h' |
14 | --- lib/libbamf/bamf-application-private.h 1970-01-01 00:00:00 +0000 |
15 | +++ lib/libbamf/bamf-application-private.h 2012-04-26 17:14:21 +0000 |
16 | @@ -0,0 +1,30 @@ |
17 | +/* |
18 | + * bamf-application-private.h |
19 | + * This file is part of BAMF |
20 | + * |
21 | + * Copyright (C) 2012 - Marco Trevisan (Treviño) |
22 | + * |
23 | + * BAMF is free software; you can redistribute it and/or modify |
24 | + * it under the terms of the GNU General Public License as published by |
25 | + * the Free Software Foundation; either version 2 of the License, or |
26 | + * (at your option) any later version. |
27 | + * |
28 | + * BAMF is distributed in the hope that it will be useful, |
29 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
30 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
31 | + * GNU General Public License for more details. |
32 | + * |
33 | + * You should have received a copy of the GNU General Public License |
34 | + * along with BAMF; if not, write to the Free Software |
35 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, |
36 | + * Boston, MA 02110-1301 USA |
37 | + */ |
38 | + |
39 | +#ifndef _BAMF_APPLICATION_PRIVATE_H_ |
40 | +#define _BAMF_APPLICATION_PRIVATE_H_ |
41 | + |
42 | +#include <libbamf/bamf-application.h> |
43 | + |
44 | +GList *bamf_application_get_cached_xids (BamfApplication *app); |
45 | + |
46 | +#endif |
47 | |
48 | === modified file 'lib/libbamf/bamf-application.c' |
49 | --- lib/libbamf/bamf-application.c 2012-04-10 08:57:06 +0000 |
50 | +++ lib/libbamf/bamf-application.c 2012-04-26 17:14:21 +0000 |
51 | @@ -37,6 +37,7 @@ |
52 | #include "bamf-application.h" |
53 | #include "bamf-window.h" |
54 | #include "bamf-factory.h" |
55 | +#include "bamf-application-private.h" |
56 | #include "bamf-view-private.h" |
57 | |
58 | #include <gio/gdesktopappinfo.h> |
59 | @@ -66,6 +67,7 @@ |
60 | DBusGProxy *proxy; |
61 | gchar *application_type; |
62 | gchar *desktop_file; |
63 | + GList *cached_xids; |
64 | int show_stubs; |
65 | }; |
66 | |
67 | @@ -98,6 +100,12 @@ |
68 | return NULL; |
69 | } |
70 | |
71 | + if (file && file[0] == '\0') |
72 | + { |
73 | + g_free (file); |
74 | + file = NULL; |
75 | + } |
76 | + |
77 | priv->desktop_file = file; |
78 | return file; |
79 | } |
80 | @@ -185,6 +193,7 @@ |
81 | } |
82 | } |
83 | |
84 | + g_list_free (children); |
85 | return windows; |
86 | } |
87 | |
88 | @@ -238,20 +247,48 @@ |
89 | bamf_application_on_window_added (DBusGProxy *proxy, char *path, BamfApplication *self) |
90 | { |
91 | BamfView *view; |
92 | - |
93 | - view = bamf_factory_view_for_path (bamf_factory_get_default (), path); |
94 | - |
95 | - g_signal_emit (G_OBJECT (self), application_signals[WINDOW_ADDED], 0, view); |
96 | + BamfFactory *factory; |
97 | + |
98 | + factory = bamf_factory_get_default (); |
99 | + view = bamf_factory_view_for_path_type (factory, path, BAMF_FACTORY_WINDOW); |
100 | + |
101 | + if (BAMF_IS_WINDOW (view)) |
102 | + { |
103 | + guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view)); |
104 | + |
105 | + if (!g_list_find (self->priv->cached_xids, GUINT_TO_POINTER (xid))) |
106 | + { |
107 | + self->priv->cached_xids = g_list_prepend (self->priv->cached_xids, GUINT_TO_POINTER (xid)); |
108 | + } |
109 | + |
110 | + g_signal_emit (G_OBJECT (self), application_signals[WINDOW_ADDED], 0, view); |
111 | + } |
112 | } |
113 | |
114 | static void |
115 | bamf_application_on_window_removed (DBusGProxy *proxy, char *path, BamfApplication *self) |
116 | { |
117 | BamfView *view; |
118 | - |
119 | - view = bamf_factory_view_for_path (bamf_factory_get_default (), path); |
120 | - |
121 | - g_signal_emit (G_OBJECT (self), application_signals[WINDOW_REMOVED], 0, view); |
122 | + BamfFactory *factory; |
123 | + |
124 | + factory = bamf_factory_get_default (); |
125 | + view = bamf_factory_view_for_path_type (factory, path, BAMF_FACTORY_WINDOW); |
126 | + |
127 | + if (BAMF_IS_WINDOW (view)) |
128 | + { |
129 | + guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view)); |
130 | + self->priv->cached_xids = g_list_remove (self->priv->cached_xids, GUINT_TO_POINTER (xid)); |
131 | + |
132 | + g_signal_emit (G_OBJECT (self), application_signals[WINDOW_REMOVED], 0, view); |
133 | + } |
134 | +} |
135 | + |
136 | +GList * |
137 | +bamf_application_get_cached_xids (BamfApplication *self) |
138 | +{ |
139 | + g_return_val_if_fail (BAMF_IS_APPLICATION (self), NULL); |
140 | + |
141 | + return self->priv->cached_xids; |
142 | } |
143 | |
144 | static void |
145 | @@ -291,6 +328,12 @@ |
146 | priv->proxy = NULL; |
147 | } |
148 | |
149 | + if (priv->cached_xids) |
150 | + { |
151 | + g_list_free (priv->cached_xids); |
152 | + priv->cached_xids = NULL; |
153 | + } |
154 | + |
155 | if (G_OBJECT_CLASS (bamf_application_parent_class)->dispose) |
156 | G_OBJECT_CLASS (bamf_application_parent_class)->dispose (object); |
157 | } |
158 | @@ -335,6 +378,26 @@ |
159 | (GCallback) bamf_application_on_window_removed, |
160 | self, |
161 | NULL); |
162 | + |
163 | + GList *children, *l; |
164 | + children = bamf_view_get_children (view); |
165 | + |
166 | + if (priv->cached_xids) |
167 | + { |
168 | + g_list_free (priv->cached_xids); |
169 | + priv->cached_xids = NULL; |
170 | + } |
171 | + |
172 | + for (l = children; l; l = l->next) |
173 | + { |
174 | + if (!BAMF_IS_WINDOW (l->data)) |
175 | + continue; |
176 | + |
177 | + guint32 xid = bamf_window_get_xid (BAMF_WINDOW (l->data)); |
178 | + priv->cached_xids = g_list_prepend (priv->cached_xids, GUINT_TO_POINTER (xid)); |
179 | + } |
180 | + |
181 | + g_list_free (children); |
182 | } |
183 | |
184 | static void |
185 | |
186 | === modified file 'lib/libbamf/bamf-factory.c' |
187 | --- lib/libbamf/bamf-factory.c 2012-04-18 12:28:41 +0000 |
188 | +++ lib/libbamf/bamf-factory.c 2012-04-26 17:14:21 +0000 |
189 | @@ -39,6 +39,7 @@ |
190 | #include "bamf-view-private.h" |
191 | #include "bamf-window.h" |
192 | #include "bamf-application.h" |
193 | +#include "bamf-application-private.h" |
194 | #include "bamf-indicator.h" |
195 | |
196 | #include <dbus/dbus.h> |
197 | @@ -159,68 +160,181 @@ |
198 | return result; |
199 | } |
200 | |
201 | -BamfView * |
202 | -bamf_factory_view_for_path (BamfFactory * factory, |
203 | - const char * path) |
204 | +static |
205 | +BamfFactoryViewType compute_factory_type_by_str (const char *type) |
206 | +{ |
207 | + BamfFactoryViewType factory_type = BAMF_FACTORY_NONE; |
208 | + |
209 | + if (type && type[0] != '\0') |
210 | + { |
211 | + if (g_strcmp0 (type, "window") == 0) |
212 | + { |
213 | + factory_type = BAMF_FACTORY_WINDOW; |
214 | + } |
215 | + else if (g_strcmp0 (type, "application") == 0) |
216 | + { |
217 | + factory_type = BAMF_FACTORY_APPLICATION; |
218 | + } |
219 | + else if (g_strcmp0 (type, "indicator") == 0) |
220 | + { |
221 | + factory_type = BAMF_FACTORY_INDICATOR; |
222 | + } |
223 | + else if (g_strcmp0 (type, "view") == 0) |
224 | + { |
225 | + factory_type = BAMF_FACTORY_VIEW; |
226 | + } |
227 | + } |
228 | + |
229 | + return factory_type; |
230 | +} |
231 | + |
232 | +BamfView * |
233 | +bamf_factory_view_for_path (BamfFactory * factory, const char * path) |
234 | +{ |
235 | + return bamf_factory_view_for_path_type (factory, path, BAMF_FACTORY_NONE); |
236 | +} |
237 | + |
238 | +BamfView * |
239 | +bamf_factory_view_for_path_type_str (BamfFactory * factory, const char * path, |
240 | + const char * type) |
241 | +{ |
242 | + g_return_val_if_fail (BAMF_IS_FACTORY (factory), NULL); |
243 | + BamfFactoryViewType factory_type = compute_factory_type_by_str (type); |
244 | + |
245 | + return bamf_factory_view_for_path_type (factory, path, factory_type); |
246 | +} |
247 | + |
248 | +BamfView * |
249 | +bamf_factory_view_for_path_type (BamfFactory * factory, const char * path, |
250 | + BamfFactoryViewType type) |
251 | { |
252 | GHashTable *views; |
253 | BamfView *view; |
254 | GList *l; |
255 | - gchar *type; |
256 | gboolean created = FALSE; |
257 | |
258 | g_return_val_if_fail (BAMF_IS_FACTORY (factory), NULL); |
259 | |
260 | - if (!path || strlen (path) == 0) |
261 | + if (!path || path[0] == '\0') |
262 | return NULL; |
263 | |
264 | views = factory->priv->views; |
265 | - |
266 | view = g_hash_table_lookup (views, path); |
267 | |
268 | if (BAMF_IS_VIEW (view)) |
269 | return view; |
270 | - |
271 | - view = g_object_new (BAMF_TYPE_VIEW, NULL); |
272 | - bamf_view_set_path (view, path); |
273 | - type = g_strdup (bamf_view_get_view_type (view)); |
274 | - g_object_unref (view); |
275 | - |
276 | - view = NULL; |
277 | - if (g_strcmp0 (type, "application") == 0) |
278 | - view = BAMF_VIEW (bamf_application_new (path)); |
279 | - else if (g_strcmp0 (type, "window") == 0) |
280 | - view = BAMF_VIEW (bamf_window_new (path)); |
281 | - else if (g_strcmp0 (type, "indicator") == 0) |
282 | - view = BAMF_VIEW (bamf_indicator_new (path)); |
283 | - |
284 | + |
285 | + if (type == BAMF_FACTORY_NONE) |
286 | + { |
287 | + view = g_object_new (BAMF_TYPE_VIEW, NULL); |
288 | + bamf_view_set_path (view, path); |
289 | + type = compute_factory_type_by_str (bamf_view_get_view_type (view)); |
290 | + g_object_unref (view); |
291 | + view = NULL; |
292 | + } |
293 | + |
294 | + switch (type) |
295 | + { |
296 | + case BAMF_FACTORY_VIEW: |
297 | + view = g_object_new (BAMF_TYPE_VIEW, NULL); |
298 | + break; |
299 | + case BAMF_FACTORY_WINDOW: |
300 | + view = BAMF_VIEW (bamf_window_new (path)); |
301 | + break; |
302 | + case BAMF_FACTORY_APPLICATION: |
303 | + view = BAMF_VIEW (bamf_application_new (path)); |
304 | + break; |
305 | + case BAMF_FACTORY_INDICATOR: |
306 | + view = BAMF_VIEW (bamf_indicator_new (path)); |
307 | + break; |
308 | + case BAMF_FACTORY_NONE: |
309 | + view = NULL; |
310 | + } |
311 | + |
312 | created = TRUE; |
313 | - |
314 | + BamfView *matched_view = NULL; |
315 | + |
316 | if (BAMF_IS_APPLICATION (view)) |
317 | { |
318 | /* handle case where a favorite exists and this matches it */ |
319 | const char *local_desktop_file = bamf_application_get_desktop_file (BAMF_APPLICATION (view)); |
320 | - for (l = factory->priv->local_views; l; l = l->next) |
321 | - { |
322 | - /* remote ready views are already matched */ |
323 | - if (bamf_view_remote_ready (BAMF_VIEW (l->data)) || !BAMF_IS_APPLICATION (l->data)) |
324 | - continue; |
325 | - |
326 | - const char *list_desktop_file = bamf_application_get_desktop_file (BAMF_APPLICATION (l->data)); |
327 | - |
328 | - if (g_strcmp0 (local_desktop_file, list_desktop_file) == 0) |
329 | - { |
330 | - created = FALSE; |
331 | - g_object_unref (view); |
332 | - |
333 | - view = BAMF_VIEW (l->data); |
334 | - bamf_view_set_path (view, path); |
335 | - g_object_ref_sink (view); |
336 | - break; |
337 | - } |
338 | - } |
339 | - } |
340 | - |
341 | + GList *local_children = bamf_view_get_children (view); |
342 | + |
343 | + for (l = factory->priv->local_views; l; l = l->next) |
344 | + { |
345 | + if (!BAMF_IS_APPLICATION (l->data)) |
346 | + continue; |
347 | + |
348 | + BamfView *list_view = BAMF_VIEW (l->data); |
349 | + BamfApplication *list_app = BAMF_APPLICATION (l->data); |
350 | + |
351 | + const char *list_desktop_file = bamf_application_get_desktop_file (list_app); |
352 | + |
353 | + /* We try to match applications by desktop files */ |
354 | + if (local_desktop_file && g_strcmp0 (local_desktop_file, list_desktop_file) == 0) |
355 | + { |
356 | + matched_view = list_view; |
357 | + break; |
358 | + } |
359 | + |
360 | + /* If the primary search doesn't give out any result, we fallback |
361 | + * to children window comparison */ |
362 | + if (!matched_view) |
363 | + { |
364 | + GList *list_children, *ll; |
365 | + list_children = bamf_application_get_cached_xids (list_app); |
366 | + |
367 | + for (ll = local_children; ll; ll = ll->next) |
368 | + { |
369 | + if (!BAMF_IS_WINDOW (ll->data)) |
370 | + continue; |
371 | + |
372 | + guint32 local_xid = bamf_window_get_xid (BAMF_WINDOW (ll->data)); |
373 | + |
374 | + if (g_list_find (list_children, GUINT_TO_POINTER (local_xid))) |
375 | + { |
376 | + matched_view = list_view; |
377 | + break; |
378 | + } |
379 | + } |
380 | + } |
381 | + } |
382 | + |
383 | + g_list_free (local_children); |
384 | + } |
385 | + else if (BAMF_IS_WINDOW (view)) |
386 | + { |
387 | + guint32 local_xid = bamf_window_get_xid (BAMF_WINDOW (view)); |
388 | + |
389 | + for (l = factory->priv->local_views; l; l = l->next) |
390 | + { |
391 | + if (!BAMF_IS_WINDOW (l->data)) |
392 | + continue; |
393 | + |
394 | + BamfView *list_view = BAMF_VIEW (l->data); |
395 | + BamfWindow *list_win = BAMF_WINDOW (l->data); |
396 | + |
397 | + guint32 list_xid = bamf_window_get_xid (list_win); |
398 | + |
399 | + /* We try to match windows by xid */ |
400 | + if (local_xid != 0 && local_xid == list_xid) |
401 | + { |
402 | + matched_view = list_view; |
403 | + break; |
404 | + } |
405 | + } |
406 | + } |
407 | + |
408 | + if (matched_view) |
409 | + { |
410 | + created = FALSE; |
411 | + g_object_unref (view); |
412 | + |
413 | + view = matched_view; |
414 | + bamf_view_set_path (view, path); |
415 | + g_object_ref_sink (view); |
416 | + } |
417 | + |
418 | if (view) |
419 | { |
420 | bamf_factory_register_view (factory, view, path); |
421 | @@ -231,8 +345,7 @@ |
422 | g_object_ref_sink (view); |
423 | } |
424 | } |
425 | - |
426 | - g_free (type); |
427 | + |
428 | return view; |
429 | } |
430 | |
431 | |
432 | === modified file 'lib/libbamf/bamf-factory.h' |
433 | --- lib/libbamf/bamf-factory.h 2010-10-26 03:48:12 +0000 |
434 | +++ lib/libbamf/bamf-factory.h 2012-04-26 17:14:21 +0000 |
435 | @@ -54,6 +54,15 @@ |
436 | typedef struct _BamfFactoryClass BamfFactoryClass; |
437 | typedef struct _BamfFactoryPrivate BamfFactoryPrivate; |
438 | |
439 | +typedef enum |
440 | +{ |
441 | + BAMF_FACTORY_VIEW, |
442 | + BAMF_FACTORY_WINDOW, |
443 | + BAMF_FACTORY_APPLICATION, |
444 | + BAMF_FACTORY_INDICATOR, |
445 | + BAMF_FACTORY_NONE |
446 | +} BamfFactoryViewType; |
447 | + |
448 | struct _BamfFactory |
449 | { |
450 | GObject parent; |
451 | @@ -71,6 +80,14 @@ |
452 | BamfView * bamf_factory_view_for_path (BamfFactory * factory, |
453 | const char * path); |
454 | |
455 | +BamfView * bamf_factory_view_for_path_type (BamfFactory * factory, |
456 | + const char * path, |
457 | + BamfFactoryViewType type); |
458 | + |
459 | +BamfView * bamf_factory_view_for_path_type_str (BamfFactory * factory, |
460 | + const char * path, |
461 | + const char * type); |
462 | + |
463 | BamfApplication * bamf_factory_app_for_file (BamfFactory * factory, |
464 | const char * path, |
465 | gboolean create); |
466 | |
467 | === modified file 'lib/libbamf/bamf-matcher.c' |
468 | --- lib/libbamf/bamf-matcher.c 2012-04-24 14:14:44 +0000 |
469 | +++ lib/libbamf/bamf-matcher.c 2012-04-26 17:14:21 +0000 |
470 | @@ -144,8 +144,12 @@ |
471 | BamfMatcher *matcher) |
472 | { |
473 | BamfView *view; |
474 | - |
475 | - view = bamf_factory_view_for_path (bamf_factory_get_default (), path); |
476 | + BamfFactory *factory = bamf_factory_get_default (); |
477 | + |
478 | + view = bamf_factory_view_for_path_type_str (factory, path, type); |
479 | + |
480 | + if (!BAMF_IS_VIEW (view)) |
481 | + return; |
482 | |
483 | g_signal_emit (matcher, matcher_signals[VIEW_OPENED], 0, view); |
484 | } |
485 | @@ -157,8 +161,9 @@ |
486 | BamfMatcher *matcher) |
487 | { |
488 | BamfView *view; |
489 | + BamfFactory *factory = bamf_factory_get_default (); |
490 | |
491 | - view = bamf_factory_view_for_path (bamf_factory_get_default (), path); |
492 | + view = bamf_factory_view_for_path_type_str (factory, path, type); |
493 | |
494 | if (!BAMF_IS_VIEW (view)) |
495 | return; |
496 | @@ -172,14 +177,12 @@ |
497 | char *new_path, |
498 | BamfMatcher *matcher) |
499 | { |
500 | - BamfView *old_view = NULL; |
501 | - BamfView *new_view = NULL; |
502 | - |
503 | - if (old_path && strlen (old_path) > 0) |
504 | - old_view = bamf_factory_view_for_path (bamf_factory_get_default (), old_path); |
505 | - |
506 | - if (new_path && strlen (new_path) > 0) |
507 | - new_view = bamf_factory_view_for_path (bamf_factory_get_default (), new_path); |
508 | + BamfView *old_view; |
509 | + BamfView *new_view; |
510 | + |
511 | + BamfFactory *factory = bamf_factory_get_default (); |
512 | + old_view = bamf_factory_view_for_path_type (factory, old_path, BAMF_FACTORY_APPLICATION); |
513 | + new_view = bamf_factory_view_for_path_type (factory, new_path, BAMF_FACTORY_APPLICATION); |
514 | |
515 | g_signal_emit (matcher, matcher_signals[ACTIVE_APPLICATION_CHANGED], 0, old_view, new_view); |
516 | } |
517 | @@ -190,14 +193,12 @@ |
518 | char *new_path, |
519 | BamfMatcher *matcher) |
520 | { |
521 | - BamfView *old_view = NULL; |
522 | - BamfView *new_view = NULL; |
523 | - |
524 | - if (old_path && strlen (old_path) > 0) |
525 | - old_view = bamf_factory_view_for_path (bamf_factory_get_default (), old_path); |
526 | - |
527 | - if (new_path && strlen (new_path) > 0) |
528 | - new_view = bamf_factory_view_for_path (bamf_factory_get_default (), new_path); |
529 | + BamfView *old_view; |
530 | + BamfView *new_view; |
531 | + |
532 | + BamfFactory *factory = bamf_factory_get_default (); |
533 | + old_view = bamf_factory_view_for_path_type (factory, old_path, BAMF_FACTORY_WINDOW); |
534 | + new_view = bamf_factory_view_for_path_type (factory, new_path, BAMF_FACTORY_WINDOW); |
535 | |
536 | g_signal_emit (matcher, matcher_signals[ACTIVE_WINDOW_CHANGED], 0, old_view, new_view); |
537 | } |
538 | @@ -373,10 +374,17 @@ |
539 | return NULL; |
540 | } |
541 | |
542 | + if (app && app[0] == '\0') |
543 | + { |
544 | + g_free (app); |
545 | + return NULL; |
546 | + } |
547 | + |
548 | if (!app) |
549 | return NULL; |
550 | |
551 | - view = bamf_factory_view_for_path (bamf_factory_get_default (), app); |
552 | + BamfFactory *factory = bamf_factory_get_default (); |
553 | + view = bamf_factory_view_for_path_type (factory, app, BAMF_FACTORY_APPLICATION); |
554 | g_free (app); |
555 | |
556 | if (!BAMF_IS_APPLICATION (view)) |
557 | @@ -390,7 +398,7 @@ |
558 | { |
559 | BamfMatcherPrivate *priv; |
560 | BamfView *view; |
561 | - char *app = NULL; |
562 | + char *win = NULL; |
563 | GError *error = NULL; |
564 | |
565 | g_return_val_if_fail (BAMF_IS_MATCHER (matcher), NULL); |
566 | @@ -400,7 +408,7 @@ |
567 | "ActiveWindow", |
568 | &error, |
569 | G_TYPE_INVALID, |
570 | - G_TYPE_STRING, &app, |
571 | + G_TYPE_STRING, &win, |
572 | G_TYPE_INVALID)) |
573 | { |
574 | g_warning ("Failed to fetch path: %s", error->message); |
575 | @@ -408,11 +416,18 @@ |
576 | return NULL; |
577 | } |
578 | |
579 | - if (!app) |
580 | + if (win && win[0] == '\0') |
581 | + { |
582 | + g_free (win); |
583 | + return NULL; |
584 | + } |
585 | + |
586 | + if (!win) |
587 | return NULL; |
588 | |
589 | - view = bamf_factory_view_for_path (bamf_factory_get_default (), app); |
590 | - g_free (app); |
591 | + BamfFactory *factory = bamf_factory_get_default (); |
592 | + view = bamf_factory_view_for_path_type (factory, win, BAMF_FACTORY_WINDOW); |
593 | + g_free (win); |
594 | |
595 | if (!BAMF_IS_WINDOW (view)) |
596 | return NULL; |
597 | @@ -455,10 +470,17 @@ |
598 | return NULL; |
599 | } |
600 | |
601 | + if (app && app[0] == '\0') |
602 | + { |
603 | + g_free (app); |
604 | + return NULL; |
605 | + } |
606 | + |
607 | if (!app) |
608 | return NULL; |
609 | |
610 | - view = bamf_factory_view_for_path (bamf_factory_get_default (), app); |
611 | + BamfFactory *factory = bamf_factory_get_default (); |
612 | + view = bamf_factory_view_for_path_type (factory, app, BAMF_FACTORY_APPLICATION); |
613 | |
614 | g_free (app); |
615 | |
616 | @@ -522,14 +544,16 @@ |
617 | return NULL; |
618 | } |
619 | |
620 | - g_return_val_if_fail (array, NULL); |
621 | + if (!array) |
622 | + return NULL; |
623 | |
624 | + BamfFactory *factory = bamf_factory_get_default (); |
625 | len = g_strv_length (array); |
626 | for (i = len-1; i >= 0; i--) |
627 | { |
628 | - view = bamf_factory_view_for_path (bamf_factory_get_default (), array[i]); |
629 | + view = bamf_factory_view_for_path_type (factory, array[i], BAMF_FACTORY_APPLICATION); |
630 | |
631 | - if (view) |
632 | + if (BAMF_IS_APPLICATION (view)) |
633 | result = g_list_prepend (result, view); |
634 | } |
635 | |
636 | @@ -563,14 +587,16 @@ |
637 | return NULL; |
638 | } |
639 | |
640 | - g_return_val_if_fail (array, NULL); |
641 | + if (!array) |
642 | + return NULL; |
643 | |
644 | + BamfFactory *factory = bamf_factory_get_default (); |
645 | len = g_strv_length (array); |
646 | for (i = len-1; i >= 0; i--) |
647 | { |
648 | - view = bamf_factory_view_for_path (bamf_factory_get_default (), array[i]); |
649 | + view = bamf_factory_view_for_path_type (factory, array[i], BAMF_FACTORY_WINDOW); |
650 | |
651 | - if (view) |
652 | + if (BAMF_IS_WINDOW (view)) |
653 | result = g_list_prepend (result, view); |
654 | } |
655 | |
656 | @@ -606,14 +632,16 @@ |
657 | return NULL; |
658 | } |
659 | |
660 | - g_return_val_if_fail (array, NULL); |
661 | + if (!array) |
662 | + return NULL; |
663 | |
664 | + BamfFactory *factory = bamf_factory_get_default (); |
665 | len = g_strv_length (array); |
666 | for (i = len-1; i >= 0; i--) |
667 | { |
668 | - view = bamf_factory_view_for_path (bamf_factory_get_default (), array[i]); |
669 | + view = bamf_factory_view_for_path_type (factory, array[i], BAMF_FACTORY_WINDOW); |
670 | |
671 | - if (view) |
672 | + if (BAMF_IS_WINDOW (view)) |
673 | result = g_list_prepend (result, view); |
674 | } |
675 | |
676 | @@ -664,14 +692,16 @@ |
677 | return NULL; |
678 | } |
679 | |
680 | - g_return_val_if_fail (array, NULL); |
681 | + if (!array) |
682 | + return NULL; |
683 | |
684 | + BamfFactory *factory = bamf_factory_get_default (); |
685 | len = g_strv_length (array); |
686 | for (i = len-1; i >= 0; i--) |
687 | { |
688 | - view = bamf_factory_view_for_path (bamf_factory_get_default (), array[i]); |
689 | + view = bamf_factory_view_for_path_type (factory, array[i], BAMF_FACTORY_APPLICATION); |
690 | |
691 | - if (view) |
692 | + if (BAMF_IS_APPLICATION (view)) |
693 | result = g_list_prepend (result, view); |
694 | } |
695 | |
696 | |
697 | === modified file 'lib/libbamf/bamf-view-private.h' |
698 | --- lib/libbamf/bamf-view-private.h 2010-11-01 05:07:11 +0000 |
699 | +++ lib/libbamf/bamf-view-private.h 2012-04-26 17:14:21 +0000 |
700 | @@ -31,6 +31,8 @@ |
701 | |
702 | gboolean bamf_view_remote_ready (BamfView *view); |
703 | |
704 | +void bamf_view_reset_flags (BamfView *view); |
705 | + |
706 | void bamf_view_set_name (BamfView *view, const char *name); |
707 | |
708 | void bamf_view_set_icon (BamfView *view, const char *icon); |
709 | |
710 | === modified file 'lib/libbamf/bamf-view.c' |
711 | --- lib/libbamf/bamf-view.c 2012-04-22 15:10:47 +0000 |
712 | +++ lib/libbamf/bamf-view.c 2012-04-26 17:14:21 +0000 |
713 | @@ -111,7 +111,7 @@ |
714 | if (value) |
715 | priv->set_flags |= flag; |
716 | else |
717 | - priv->set_flags = priv->set_flags & ~flag; |
718 | + priv->set_flags &= ~flag; |
719 | |
720 | priv->checked_flags |= flag; |
721 | } |
722 | @@ -386,7 +386,7 @@ |
723 | return BAMF_VIEW_GET_CLASS (self)->get_name (self); |
724 | |
725 | if (!bamf_view_remote_ready (self)) |
726 | - return g_strdup(priv->local_name); |
727 | + return g_strdup (priv->local_name); |
728 | |
729 | if (!dbus_g_proxy_call (priv->proxy, |
730 | "Name", |
731 | @@ -439,7 +439,7 @@ |
732 | G_TYPE_STRING, &type, |
733 | G_TYPE_INVALID)) |
734 | { |
735 | - g_warning ("Failed to fetch view type at %s: %s", dbus_g_proxy_get_path (priv->proxy), error->message); |
736 | + g_warning ("Failed to fetch view type at %s: %s", dbus_g_proxy_get_path (priv->proxy), error ? error->message : ""); |
737 | g_error_free (error); |
738 | return NULL; |
739 | } |
740 | @@ -543,6 +543,16 @@ |
741 | } |
742 | |
743 | static void |
744 | +on_view_proxy_destroyed (GObject *proxy, gpointer user_data) |
745 | +{ |
746 | + BamfView *view = user_data; |
747 | + g_return_if_fail (BAMF_IS_VIEW (view)); |
748 | + |
749 | + view->priv->checked_flags = 0x0; |
750 | + view->priv->proxy = NULL; |
751 | +} |
752 | + |
753 | +static void |
754 | bamf_view_on_closed (DBusGProxy *proxy, BamfView *self) |
755 | { |
756 | BamfViewPrivate *priv; |
757 | @@ -593,6 +603,8 @@ |
758 | "UserVisibleChanged", |
759 | (GCallback) bamf_view_on_user_visible_changed, |
760 | self); |
761 | + |
762 | + g_signal_handlers_disconnect_by_func (priv->proxy, on_view_proxy_destroyed, self); |
763 | g_object_unref (priv->proxy); |
764 | priv->proxy = NULL; |
765 | } |
766 | @@ -737,6 +749,7 @@ |
767 | (GCallback) bamf_view_on_name_changed, |
768 | view); |
769 | |
770 | + g_signal_handlers_disconnect_by_func (priv->proxy, on_view_proxy_destroyed, view); |
771 | g_object_unref (priv->proxy); |
772 | priv->proxy = NULL; |
773 | } |
774 | @@ -753,6 +766,40 @@ |
775 | } |
776 | |
777 | void |
778 | +bamf_view_reset_flags (BamfView *view) |
779 | +{ |
780 | + BamfViewPrivate *priv; |
781 | + g_return_if_fail (BAMF_IS_VIEW (view)); |
782 | + |
783 | + priv = view->priv; |
784 | + priv->checked_flags = 0x0; |
785 | + |
786 | + if (bamf_view_user_visible (view)) |
787 | + { |
788 | + g_signal_emit (G_OBJECT(view), view_signals[VISIBLE_CHANGED], 0, TRUE); |
789 | + g_object_notify (G_OBJECT (view), "user-visible"); |
790 | + } |
791 | + |
792 | + if (bamf_view_is_active (view)) |
793 | + { |
794 | + g_signal_emit (G_OBJECT(view), view_signals[ACTIVE_CHANGED], 0, TRUE); |
795 | + g_object_notify (G_OBJECT (view), "active"); |
796 | + } |
797 | + |
798 | + if (bamf_view_is_running (view)) |
799 | + { |
800 | + g_signal_emit (G_OBJECT(view), view_signals[RUNNING_CHANGED], 0, TRUE); |
801 | + g_object_notify (G_OBJECT (view), "running"); |
802 | + } |
803 | + |
804 | + if (bamf_view_is_urgent (view)) |
805 | + { |
806 | + g_signal_emit (G_OBJECT(view), view_signals[URGENT_CHANGED], 0, TRUE); |
807 | + g_object_notify (G_OBJECT (view), "urgent"); |
808 | + } |
809 | +} |
810 | + |
811 | +void |
812 | bamf_view_set_path (BamfView *view, const char *path) |
813 | { |
814 | BamfViewPrivate *priv; |
815 | @@ -766,18 +813,27 @@ |
816 | { |
817 | g_free (priv->path); |
818 | } |
819 | - |
820 | + |
821 | + if (priv->proxy) |
822 | + { |
823 | + g_signal_handlers_disconnect_by_func (priv->proxy, on_view_proxy_destroyed, view); |
824 | + g_object_unref (priv->proxy); |
825 | + } |
826 | + |
827 | priv->path = g_strdup (path); |
828 | priv->proxy = dbus_g_proxy_new_for_name (priv->connection, |
829 | "org.ayatana.bamf", |
830 | priv->path, |
831 | "org.ayatana.bamf.view"); |
832 | + |
833 | if (priv->proxy == NULL) |
834 | { |
835 | g_critical ("Unable to get org.ayatana.bamf.view view"); |
836 | return; |
837 | } |
838 | |
839 | + g_signal_connect (priv->proxy, "destroy", G_CALLBACK (on_view_proxy_destroyed), view); |
840 | + |
841 | dbus_g_proxy_add_signal (priv->proxy, |
842 | "ActiveChanged", |
843 | G_TYPE_BOOLEAN, |
844 | @@ -868,32 +924,9 @@ |
845 | |
846 | if (bamf_view_is_sticky (view)) |
847 | { |
848 | - priv->checked_flags = 0x0; |
849 | - |
850 | - if (bamf_view_user_visible (view)) |
851 | - { |
852 | - g_signal_emit (G_OBJECT(view), view_signals[VISIBLE_CHANGED], 0, TRUE); |
853 | - g_object_notify (G_OBJECT (view), "user-visible"); |
854 | - } |
855 | - |
856 | - if (bamf_view_is_active (view)) |
857 | - { |
858 | - g_signal_emit (G_OBJECT(view), view_signals[ACTIVE_CHANGED], 0, TRUE); |
859 | - g_object_notify (G_OBJECT (view), "active"); |
860 | - } |
861 | - |
862 | - if (bamf_view_is_running (view)) |
863 | - { |
864 | - g_signal_emit (G_OBJECT(view), view_signals[RUNNING_CHANGED], 0, TRUE); |
865 | - g_object_notify (G_OBJECT (view), "running"); |
866 | - } |
867 | - |
868 | - if (bamf_view_is_urgent (view)) |
869 | - { |
870 | - g_signal_emit (G_OBJECT(view), view_signals[URGENT_CHANGED], 0, TRUE); |
871 | - g_object_notify (G_OBJECT (view), "urgent"); |
872 | - } |
873 | + bamf_view_reset_flags (view); |
874 | } |
875 | + |
876 | if (BAMF_VIEW_GET_CLASS (view)->set_path) |
877 | BAMF_VIEW_GET_CLASS (view)->set_path (view, path); |
878 | } |
879 | |
880 | === modified file 'lib/libbamf/bamf-window.c' |
881 | --- lib/libbamf/bamf-window.c 2012-02-27 18:34:30 +0000 |
882 | +++ lib/libbamf/bamf-window.c 2012-04-26 17:14:21 +0000 |
883 | @@ -103,7 +103,8 @@ |
884 | if (!path) |
885 | return NULL; |
886 | |
887 | - transient = bamf_factory_view_for_path (bamf_factory_get_default (), path); |
888 | + BamfFactory *factory = bamf_factory_get_default (); |
889 | + transient = bamf_factory_view_for_path_type (factory, path, BAMF_FACTORY_WINDOW); |
890 | g_free (path); |
891 | |
892 | if (!BAMF_IS_WINDOW (transient)) |
It seems to be working fine, although it seems to be causing some assertions:
(bamfdaemon:26376): GLib-CRITICAL **: g_str_has_prefix: assertion `str != NULL' failed
Backtrace:
#0 g_log (log_domain= 0x7ffff632370e "GLib", log_level= G_LOG_LEVEL_ CRITICAL, 0x7ffff632cb2a "%s: assertion `%s' failed") buildd/ glib2.0- 2.32.1/ ./glib/ gmessages. c:788 buildd/ glib2.0- 2.32.1/ ./glib/ gstrfuncs. c:2771 office_ window (window=0x7ac1e0, work/unity/ source/ bamf/src/ bamf-matcher. c:1378 window_ opened (screen=<optimized out>, window=0x7ac1e0, work/unity/ source/ bamf/src/ bamf-matcher. c:2081 marshal_ VOID__OBJECTv (closure=0x7b2630, value=< optimized out>, instance=0x777a80, args=<optimized out>, data=<optimized out>, n_params=<optimized out>, types=0x79bf50) buildd/ glib2.0- 2.32.1/ ./gobject/ gmarshal. c:1312 invoke_ va (closure=0x7b2630, value=0x0, instance=0x777a80, args=0x7fffffff d348, n_params=1, types=< optimized out>) buildd/ glib2.0- 2.32.1/ ./gobject/ gclosure. c:840 emit_valist (instance=0x777a80, id=<optimized out>, detail=0, var_args=<optimized out>) buildd/ glib2.0- 2.32.1/ ./gobject/ gsignal. c:3207 <optimized out>, id=<optimized out>, detail=<optimized out>) buildd/ glib2.0- 2.32.1/ ./gobject/ gsignal. c:3352 marshal_ VOID__OBJECTv (closure=0x7b2590, value=< optimized out>, instance=0x79a390, args=<optimized out>, data=<optimized out>, n_params=<optimized out>, types=0x7b0f30) buildd/ glib2.0- 2.32.1/ ./gobject/ gmarshal. c:1312 invoke_ va (closure=0x7b2590, value=0x0, instance=0x79a390, args=0x7fffffff d718, n_params=1, types=< optimized out>) buildd/ glib2.0- 2.32.1/ ./gobject/ gclosure. c:840 emit_valist (instance=0x79a390, id=<optimized out>, detail=0, var_args=<optimized out>) buildd/ glib2.0- 2.32.1/ ./gobject/ gsignal. c:3207 <optimized out>, id=<optimized out>, detail=<optimized out>) buildd/ glib2.0- 2.32.1/ ./gobject/ gsignal. c:3352 libwnck- 3.so.0 libwnck- 3.so.0 buildd/ glib2.0- 2.32.1/ ./glib/ gmain.c: 2515 context_ dispatch (context=0x666a80) buildd/ glib2.0- 2.32.1/ ./glib/ gmain.c: 3052 context_ iterate (dispatch=1, <optimized out>, context=0x666a80, self=<optimized out>)
format=
at /build/
#1 0x00007ffff63014f2 in g_str_has_prefix (str=0x0,
prefix=0x43e931 "libreoffice")
at /build/
#2 0x000000000042f265 in is_open_
self=<optimized out>)
at /home/miso-
#3 handle_
self=0x7861b0) at /home/miso-
#4 0x00007ffff67b6354 in g_cclosure_
return_
marshal_
param_
at /build/
#5 0x00007ffff67b2eca in _g_closure_
return_
param_
at /build/
#6 0x00007ffff67cb741 in g_signal_
signal_
---Type <return> to continue, or q <return> to quit---
at /build/
#7 0x00007ffff67cc242 in g_signal_emit (instance=
signal_
at /build/
#8 0x00007ffff67b6354 in g_cclosure_
return_
marshal_
param_
at /build/
#9 0x00007ffff67b2eca in _g_closure_
return_
param_
at /build/
#10 0x00007ffff67cb741 in g_signal_
signal_
at /build/
#11 0x00007ffff67cc242 in g_signal_emit (instance=
signal_
at /build/
#12 0x00007ffff787e339 in ?? () from /usr/lib/
#13 0x00007ffff787ea24 in ?? () from /usr/lib/
#14 0x00007ffff62e4c9a in g_main_dispatch (context=0x666a80)
at /build/
#15 g_main_
at /build/
#16 0x00007ffff62e5060 in g_main_
block=
at ...