Merge lp:~3v1n0/bamf/safe-win-reopen-on-new-desktop into lp:bamf/0.4

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Michal Hruby
Approved revision: 502
Merged at revision: 476
Proposed branch: lp:~3v1n0/bamf/safe-win-reopen-on-new-desktop
Merge into: lp:bamf/0.4
Diff against target: 1107 lines (+634/-109)
13 files modified
src/bamf-application.c (+1/-1)
src/bamf-legacy-screen-private.h (+29/-0)
src/bamf-legacy-screen.c (+69/-18)
src/bamf-legacy-window-test.c (+95/-14)
src/bamf-legacy-window-test.h (+8/-2)
src/bamf-legacy-window.c (+15/-5)
src/bamf-legacy-window.h (+6/-4)
src/bamf-matcher-private.h (+50/-0)
src/bamf-matcher.c (+59/-53)
src/bamf-window.c (+1/-1)
tests/bamfdaemon/data/test-bamf-app.desktop (+7/-0)
tests/bamfdaemon/test-bamf.c (+2/-2)
tests/bamfdaemon/test-matcher.c (+292/-9)
To merge this branch: bzr merge lp:~3v1n0/bamf/safe-win-reopen-on-new-desktop
Reviewer Review Type Date Requested Status
Michal Hruby (community) Approve
Review via email: mp+117177@code.launchpad.net

Commit message

BamfMatcher: don't reopen windows when iterating on view's list, add tests

Description of the change

Fixed a crash that happened on reopening bamf windows when a new desktop file is added to a monitored folder, LegacyWindow and LegacyScreen slightly refactored and improved to allow matcher testing.

Added first real unit tests for the matcher.

To post a comment you must log in.
500. By Marco Trevisan (Treviño)

test-matcher: fix data_dir path

501. By Marco Trevisan (Treviño)

BamfLegacyScreen: avoid close event duplication

Revision history for this message
Michal Hruby (mhr3) wrote :

243 g_signal_emit_by_name (self, "closed");
244 + self->is_closed = TRUE;

Shouldn't the is_closed be set before emitting the signal? That way calling the .is_closed method will return proper value even inside the handler.

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Yes, true.

502. By Marco Trevisan (Treviño)

BamfLegacyWindowTest: set the window as closed before emitting the signal

Revision history for this message
Michal Hruby (mhr3) wrote :

Looks fine, tests pass here...

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/bamf-application.c'
2--- src/bamf-application.c 2012-07-17 19:03:36 +0000
3+++ src/bamf-application.c 2012-07-31 15:13:24 +0000
4@@ -322,7 +322,7 @@
5 const char *window_class = bamf_legacy_window_get_class_name (window);
6 const char *instance_name = bamf_legacy_window_get_class_instance_name (window);
7
8- if (!window_class || !instance_name)
9+ if (!window_class && !instance_name)
10 return FALSE;
11
12 children = bamf_view_get_children (BAMF_VIEW (self));
13
14=== added file 'src/bamf-legacy-screen-private.h'
15--- src/bamf-legacy-screen-private.h 1970-01-01 00:00:00 +0000
16+++ src/bamf-legacy-screen-private.h 2012-07-31 15:13:24 +0000
17@@ -0,0 +1,29 @@
18+/*
19+ * Copyright (C) 2012 Canonical Ltd
20+ *
21+ * This program is free software: you can redistribute it and/or modify
22+ * it under the terms of the GNU General Public License version 3 as
23+ * published by the Free Software Foundation.
24+ *
25+ * This program is distributed in the hope that it will be useful,
26+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28+ * GNU General Public License for more details.
29+ *
30+ * You should have received a copy of the GNU General Public License
31+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
32+ *
33+ * Authored by: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
34+ *
35+ */
36+
37+#ifndef __BAMF_LEGACY_SCREEN_PRIVATE_H__
38+#define __BAMF_LEGACY_SCREEN_PRIVATE_H__
39+
40+#include "bamf-legacy-screen.h"
41+#include "bamf-legacy-window-test.h"
42+
43+void _bamf_legacy_screen_open_test_window (BamfLegacyScreen *self, BamfLegacyWindowTest *window);
44+void _bamf_legacy_screen_close_test_window (BamfLegacyScreen *self, BamfLegacyWindowTest *window);
45+
46+#endif
47
48=== modified file 'src/bamf-legacy-screen.c'
49--- src/bamf-legacy-screen.c 2012-01-10 17:48:03 +0000
50+++ src/bamf-legacy-screen.c 2012-07-31 15:13:24 +0000
51@@ -18,13 +18,15 @@
52 */
53
54 #include "bamf-legacy-screen.h"
55-#include "bamf-legacy-window-test.h"
56+#include "bamf-legacy-screen-private.h"
57 #include <gio/gio.h>
58
59 G_DEFINE_TYPE (BamfLegacyScreen, bamf_legacy_screen, G_TYPE_OBJECT);
60 #define BAMF_LEGACY_SCREEN_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, \
61 BAMF_TYPE_LEGACY_SCREEN, BamfLegacyScreenPrivate))
62
63+static BamfLegacyScreen *static_screen = NULL;
64+
65 enum
66 {
67 WINDOW_OPENED,
68@@ -100,14 +102,8 @@
69 class = parts[3];
70 exec = parts[4];
71
72- window = BAMF_LEGACY_WINDOW (bamf_legacy_window_test_new (xid, name, class, exec));
73- self->priv->windows = g_list_append (self->priv->windows, window);
74- g_signal_emit (window, legacy_screen_signals[STACKING_CHANGED], 0);
75-
76- g_signal_connect (G_OBJECT (window), "closed",
77- (GCallback) handle_window_closed, self);
78-
79- g_signal_emit (self, legacy_screen_signals[WINDOW_OPENED], 0, window);
80+ BamfLegacyWindowTest *test_win = bamf_legacy_window_test_new (xid, name, class, exec);
81+ _bamf_legacy_screen_open_test_window (self, test_win);
82 }
83 else if (g_strcmp0 (parts[0], "close") == 0 && parts_size == 2)
84 {
85@@ -116,7 +112,7 @@
86 window = l->data;
87 if (bamf_legacy_window_get_xid (window) == xid)
88 {
89- bamf_legacy_window_test_close (BAMF_LEGACY_WINDOW_TEST (window));
90+ _bamf_legacy_screen_close_test_window (self, BAMF_LEGACY_WINDOW_TEST (window));
91 break;
92 }
93 }
94@@ -382,9 +378,22 @@
95 }
96
97 static void
98-bamf_legacy_screen_dispose (GObject *object)
99+bamf_legacy_screen_finalize (GObject *object)
100 {
101- G_OBJECT_CLASS (bamf_legacy_screen_parent_class)->dispose (object);
102+ BamfLegacyScreen *self = BAMF_LEGACY_SCREEN (object);
103+
104+ if (self->priv->windows)
105+ g_list_free_full (self->priv->windows, g_object_unref);
106+
107+ if (self->priv->file)
108+ g_object_unref (self->priv->file);
109+
110+ if (self->priv->stream)
111+ g_object_unref (self->priv->stream);
112+
113+ static_screen = NULL;
114+
115+ G_OBJECT_CLASS (bamf_legacy_screen_parent_class)->finalize (object);
116 }
117
118 static void
119@@ -398,7 +407,7 @@
120 {
121 GObjectClass *object_class = G_OBJECT_CLASS (klass);
122
123- object_class->dispose = bamf_legacy_screen_dispose;
124+ object_class->finalize = bamf_legacy_screen_finalize;
125
126 g_type_class_add_private (klass, sizeof (BamfLegacyScreenPrivate));
127
128@@ -441,15 +450,16 @@
129 G_TYPE_NONE, 0);
130 }
131
132-static BamfLegacyScreen *self = NULL;
133-
134 BamfLegacyScreen *
135 bamf_legacy_screen_get_default ()
136 {
137- if (self)
138- return self;
139+ BamfLegacyScreen *self;
140+
141+ if (static_screen)
142+ return static_screen;
143
144 self = (BamfLegacyScreen *) g_object_new (BAMF_TYPE_LEGACY_SCREEN, NULL);
145+ static_screen = self;
146
147 self->priv->legacy_screen = wnck_screen_get_default ();
148
149@@ -462,5 +472,46 @@
150 g_signal_connect (G_OBJECT (self->priv->legacy_screen), "active-window-changed",
151 (GCallback) handle_active_window_changed, self);
152
153- return self;
154+ return static_screen;
155+}
156+
157+
158+// Private functions for testing purposes
159+
160+void _bamf_legacy_screen_open_test_window (BamfLegacyScreen *self, BamfLegacyWindowTest *test_window)
161+{
162+ GList *l;
163+ BamfLegacyWindow *window;
164+ guint xid;
165+
166+ g_return_if_fail (BAMF_IS_LEGACY_SCREEN (self));
167+ g_return_if_fail (BAMF_IS_LEGACY_WINDOW_TEST (test_window));
168+
169+ window = BAMF_LEGACY_WINDOW (test_window);
170+ xid = bamf_legacy_window_get_xid (window);
171+
172+ for (l = self->priv->windows; l; l = l->next)
173+ {
174+ if (bamf_legacy_window_get_xid (BAMF_LEGACY_WINDOW (l->data)) == xid)
175+ {
176+ return;
177+ }
178+ }
179+
180+ self->priv->windows = g_list_append (self->priv->windows, window);
181+ g_signal_emit (self, legacy_screen_signals[STACKING_CHANGED], 0);
182+
183+ g_signal_connect (G_OBJECT (window), "closed",
184+ (GCallback) handle_window_closed, self);
185+
186+ g_signal_emit (self, legacy_screen_signals[WINDOW_OPENED], 0, window);
187+}
188+
189+void _bamf_legacy_screen_close_test_window (BamfLegacyScreen *self, BamfLegacyWindowTest *test_window)
190+{
191+ g_return_if_fail (BAMF_IS_LEGACY_SCREEN (self));
192+ g_return_if_fail (BAMF_IS_LEGACY_WINDOW_TEST (test_window));
193+
194+ // This will cause handle_window_closed to be called
195+ bamf_legacy_window_test_close (BAMF_LEGACY_WINDOW_TEST (test_window));
196 }
197
198=== modified file 'src/bamf-legacy-window-test.c'
199--- src/bamf-legacy-window-test.c 2012-01-10 18:01:52 +0000
200+++ src/bamf-legacy-window-test.c 2012-07-31 15:13:24 +0000
201@@ -18,6 +18,7 @@
202 */
203
204 #include "bamf-legacy-window-test.h"
205+#include "bamf-legacy-screen-private.h"
206
207 G_DEFINE_TYPE (BamfLegacyWindowTest, bamf_legacy_window_test, BAMF_TYPE_LEGACY_WINDOW);
208
209@@ -147,13 +148,23 @@
210 }
211
212 static const char *
213-bamf_legacy_window_test_get_class (BamfLegacyWindow *legacy_window)
214-{
215- BamfLegacyWindowTest *self;
216-
217- self = BAMF_LEGACY_WINDOW_TEST (legacy_window);
218-
219- return self->klass;
220+bamf_legacy_window_test_get_class_name (BamfLegacyWindow *legacy_window)
221+{
222+ BamfLegacyWindowTest *self;
223+
224+ self = BAMF_LEGACY_WINDOW_TEST (legacy_window);
225+
226+ return self->wm_class_name;
227+}
228+
229+static const char *
230+bamf_legacy_window_test_get_class_instance_name (BamfLegacyWindow *legacy_window)
231+{
232+ BamfLegacyWindowTest *self;
233+
234+ self = BAMF_LEGACY_WINDOW_TEST (legacy_window);
235+
236+ return self->wm_class_instance;
237 }
238
239 char *
240@@ -229,6 +240,7 @@
241 void
242 bamf_legacy_window_test_close (BamfLegacyWindowTest *self)
243 {
244+ self->is_closed = TRUE;
245 g_signal_emit_by_name (self, "closed");
246 }
247
248@@ -280,6 +292,42 @@
249 self->dbus_menu_object_path = g_strdup (object_path);
250 }
251
252+gboolean
253+bamf_legacy_window_test_is_closed (BamfLegacyWindow *window)
254+{
255+ g_return_val_if_fail (BAMF_IS_LEGACY_WINDOW_TEST (window), TRUE);
256+
257+ BamfLegacyWindowTest *self = BAMF_LEGACY_WINDOW_TEST (window);
258+ return self->is_closed;
259+}
260+
261+static void
262+handle_destroy_notify (BamfLegacyWindowTest *copy, BamfLegacyWindowTest *self_was_here)
263+{
264+ BamfLegacyScreen *screen = bamf_legacy_screen_get_default ();
265+ _bamf_legacy_screen_open_test_window (screen, copy);
266+}
267+
268+void
269+bamf_legacy_window_test_reopen (BamfLegacyWindow *window)
270+{
271+ g_return_if_fail (BAMF_IS_LEGACY_WINDOW_TEST (window));
272+
273+ BamfLegacyWindowTest *self = BAMF_LEGACY_WINDOW_TEST (window);
274+ BamfLegacyWindowTest *copy = bamf_legacy_window_copy (self);
275+ g_object_weak_ref (G_OBJECT (self), (GWeakNotify) handle_destroy_notify, copy);
276+ bamf_legacy_window_test_close (self);
277+}
278+
279+BamfWindowType
280+bamf_legacy_window_test_get_window_type (BamfLegacyWindow *window)
281+{
282+ g_return_val_if_fail (BAMF_IS_LEGACY_WINDOW_TEST (window), TRUE);
283+
284+ BamfLegacyWindowTest *self = BAMF_LEGACY_WINDOW_TEST (window);
285+ return self->window_type;
286+}
287+
288 void
289 bamf_legacy_window_test_dispose (GObject *object)
290 {
291@@ -294,7 +342,8 @@
292
293 obj_class->dispose = bamf_legacy_window_test_dispose;
294 win_class->get_name = bamf_legacy_window_test_get_name;
295- win_class->get_class_name = bamf_legacy_window_test_get_class;
296+ win_class->get_class_name = bamf_legacy_window_test_get_class_name;
297+ win_class->get_class_instance_name = bamf_legacy_window_test_get_class_instance_name;
298 win_class->get_exec_string = bamf_legacy_window_test_get_exec_string;
299 win_class->get_xid = bamf_legacy_window_test_get_xid;
300 win_class->get_pid = bamf_legacy_window_test_get_pid;
301@@ -306,7 +355,10 @@
302 win_class->get_unique_bus_name = bamf_legacy_window_test_get_unique_bus_name;
303 win_class->get_menu_object_path = bamf_legacy_window_test_get_menu_object_path;
304 win_class->get_geometry = bamf_legacy_window_test_get_geometry;
305+ win_class->get_window_type = bamf_legacy_window_test_get_window_type;
306 win_class->maximized = bamf_legacy_window_test_maximized;
307+ win_class->is_closed = bamf_legacy_window_test_is_closed;
308+ win_class->reopen = bamf_legacy_window_test_reopen;
309 }
310
311
312@@ -315,18 +367,47 @@
313 {
314 self->pid = g_random_int_range (1, 100000);
315 self->maximized = BAMF_WINDOW_FLOATING;
316-}
317-
318-
319-BamfLegacyWindowTest *
320-bamf_legacy_window_test_new (guint32 xid, gchar *name, gchar *klass, gchar *exec)
321+ self->is_closed = FALSE;
322+}
323+
324+
325+BamfLegacyWindowTest *
326+bamf_legacy_window_copy (BamfLegacyWindowTest *self)
327+{
328+ BamfLegacyWindowTest *copy;
329+
330+ copy = g_object_new (BAMF_TYPE_LEGACY_WINDOW_TEST, NULL);
331+ copy->xid = self->xid;
332+ copy->pid = self->pid;
333+ copy->name = g_strdup (self->name);
334+ copy->wm_class_name = g_strdup (self->wm_class_name);
335+ copy->wm_class_instance = g_strdup (self->wm_class_instance);
336+ copy->exec = g_strdup (self->exec);
337+ copy->application_id = g_strdup (self->application_id);
338+ copy->unique_bus_name = g_strdup (self->unique_bus_name);
339+ copy->dbus_menu_object_path = g_strdup (self->dbus_menu_object_path);
340+ copy->needs_attention = self->needs_attention;
341+ copy->is_desktop = self->is_desktop;
342+ copy->is_skip = self->is_skip;
343+ copy->is_active = self->is_active;
344+ copy->is_closed = self->is_closed;
345+ copy->geometry = self->geometry;
346+ copy->maximized = self->maximized;
347+ copy->window_type = self->window_type;
348+
349+ return copy;
350+}
351+
352+BamfLegacyWindowTest *
353+bamf_legacy_window_test_new (guint32 xid, gchar *name, gchar *wmclass_name, gchar *exec)
354 {
355 BamfLegacyWindowTest *self;
356
357 self = g_object_new (BAMF_TYPE_LEGACY_WINDOW_TEST, NULL);
358+ self->window_type = BAMF_WINDOW_NORMAL;
359 self->xid = xid;
360 self->name = g_strdup (name);
361- self->klass = g_strdup (klass);
362+ self->wm_class_name = g_strdup (wmclass_name);
363 self->exec = g_strdup (exec);
364
365 return self;
366
367=== modified file 'src/bamf-legacy-window-test.h'
368--- src/bamf-legacy-window-test.h 2012-01-10 18:01:52 +0000
369+++ src/bamf-legacy-window-test.h 2012-07-31 15:13:24 +0000
370@@ -54,7 +54,8 @@
371 guint32 xid;
372 gint pid;
373 char * name;
374- char * klass;
375+ char * wm_class_name;
376+ char * wm_class_instance;
377 char * exec;
378 char * application_id;
379 char * unique_bus_name;
380@@ -63,8 +64,10 @@
381 gboolean is_desktop;
382 gboolean is_skip;
383 gboolean is_active;
384+ gboolean is_closed;
385 GdkRectangle geometry;
386 BamfWindowMaximizationType maximized;
387+ BamfWindowType window_type;
388 };
389
390 struct _BamfLegacyWindowTestClass
391@@ -136,6 +139,9 @@
392 bamf_legacy_window_test_close (BamfLegacyWindowTest *self);
393
394 BamfLegacyWindowTest *
395-bamf_legacy_window_test_new (guint32 xid, gchar *name, gchar *klass, gchar *exec);
396+bamf_legacy_window_test_new (guint32 xid, gchar *name, gchar *wmclass_name, gchar *exec);
397+
398+BamfLegacyWindowTest *
399+bamf_legacy_window_copy (BamfLegacyWindowTest *self);
400
401 #endif
402
403=== modified file 'src/bamf-legacy-window.c'
404--- src/bamf-legacy-window.c 2012-04-19 18:00:19 +0000
405+++ src/bamf-legacy-window.c 2012-07-31 15:13:24 +0000
406@@ -78,6 +78,10 @@
407 bamf_legacy_window_get_window_type (BamfLegacyWindow *self)
408 {
409 g_return_val_if_fail (BAMF_IS_LEGACY_WINDOW (self), 0);
410+
411+ if (BAMF_LEGACY_WINDOW_GET_CLASS (self)->get_window_type)
412+ return BAMF_LEGACY_WINDOW_GET_CLASS (self)->get_window_type (self);
413+
414 g_return_val_if_fail (self->priv->legacy_window, 0);
415
416 return (BamfWindowType) wnck_window_get_window_type (self->priv->legacy_window);
417@@ -88,7 +92,6 @@
418 {
419 g_return_val_if_fail (BAMF_IS_LEGACY_WINDOW (self), FALSE);
420
421-
422 if (BAMF_LEGACY_WINDOW_GET_CLASS (self)->needs_attention)
423 return BAMF_LEGACY_WINDOW_GET_CLASS (self)->needs_attention (self);
424
425@@ -356,11 +359,14 @@
426 g_signal_emit (self, legacy_window_signals[GEOMETRY_CHANGED], 0);
427 }
428
429-gboolean
430+gboolean
431 bamf_legacy_window_is_closed (BamfLegacyWindow *self)
432 {
433 g_return_val_if_fail (BAMF_IS_LEGACY_WINDOW (self), TRUE);
434-
435+
436+ if (BAMF_LEGACY_WINDOW_GET_CLASS (self)->is_closed)
437+ return BAMF_LEGACY_WINDOW_GET_CLASS (self)->is_closed (self);
438+
439 return self->priv->is_closed;
440 }
441
442@@ -463,6 +469,10 @@
443 bamf_legacy_window_reopen (BamfLegacyWindow *self)
444 {
445 g_return_if_fail (BAMF_IS_LEGACY_WINDOW (self));
446+
447+ if (BAMF_LEGACY_WINDOW_GET_CLASS (self)->reopen)
448+ return BAMF_LEGACY_WINDOW_GET_CLASS (self)->reopen (self);
449+
450 g_return_if_fail (WNCK_IS_WINDOW (self->priv->legacy_window));
451
452 guint xid = bamf_legacy_window_get_xid (self);
453@@ -488,13 +498,13 @@
454
455 g_signal_handler_disconnect (wnck_screen_get_default (),
456 self->priv->closed_id);
457-
458+
459 if (self->priv->mini_icon_path)
460 {
461 file = g_file_new_for_path (self->priv->mini_icon_path);
462 g_file_delete (file, NULL, NULL);
463 g_object_unref (file);
464-
465+
466 g_free (self->priv->mini_icon_path);
467 self->priv->mini_icon_path = NULL;
468 }
469
470=== modified file 'src/bamf-legacy-window.h'
471--- src/bamf-legacy-window.h 2012-04-18 20:12:33 +0000
472+++ src/bamf-legacy-window.h 2012-07-31 15:13:24 +0000
473@@ -84,11 +84,13 @@
474 gboolean (*is_skip_tasklist) (BamfLegacyWindow *legacy_window);
475 gboolean (*is_desktop) (BamfLegacyWindow *legacy_window);
476 gboolean (*is_dialog) (BamfLegacyWindow *legacy_window);
477+ gboolean (*is_closed) (BamfLegacyWindow *legacy_window);
478 BamfWindowMaximizationType (*maximized) (BamfLegacyWindow *legacy_window);
479-
480- void (*get_geometry) (BamfLegacyWindow *self,
481- gint *x, gint *y,
482- gint *width, gint *height);
483+ BamfWindowType (*get_window_type) (BamfLegacyWindow *legacy_window);
484+ void (*get_geometry) (BamfLegacyWindow *legacy_window,
485+ gint *x, gint *y,
486+ gint *width, gint *height);
487+ void (*reopen) (BamfLegacyWindow *legacy_window);
488
489 /*< signals >*/
490 void (*name_changed) (BamfLegacyWindow *legacy_window);
491
492=== added file 'src/bamf-matcher-private.h'
493--- src/bamf-matcher-private.h 1970-01-01 00:00:00 +0000
494+++ src/bamf-matcher-private.h 2012-07-31 15:13:24 +0000
495@@ -0,0 +1,50 @@
496+/*
497+ * Copyright (C) 2012 Canonical Ltd
498+ *
499+ * This program is free software: you can redistribute it and/or modify
500+ * it under the terms of the GNU General Public License version 3 as
501+ * published by the Free Software Foundation.
502+ *
503+ * This program is distributed in the hope that it will be useful,
504+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
505+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
506+ * GNU General Public License for more details.
507+ *
508+ * You should have received a copy of the GNU General Public License
509+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
510+ *
511+ * Authored by: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
512+ *
513+ */
514+
515+#ifndef __BAMF_MATCHER_PRIVATE_H__
516+#define __BAMF_MATCHER_PRIVATE_H__
517+
518+#include "bamf-view.h"
519+#include "bamf-matcher.h"
520+#include "bamf-application.h"
521+#include "bamf-window.h"
522+#include "bamf-legacy-window.h"
523+
524+struct _BamfMatcherPrivate
525+{
526+ GArray * bad_prefixes;
527+ GArray * good_prefixes;
528+ GArray * known_pids;
529+ GHashTable * desktop_id_table;
530+ GHashTable * desktop_file_table;
531+ GHashTable * desktop_class_table;
532+ GHashTable * registered_pids;
533+ GHashTable * opened_closed_paths_table;
534+ GList * views;
535+ GList * monitors;
536+ GList * favorites;
537+ BamfView * active_app;
538+ BamfView * active_win;
539+ guint dispatch_changes_id;
540+};
541+
542+BamfApplication * bamf_matcher_get_application_by_desktop_file (BamfMatcher *self, const char *desktop_file);
543+BamfApplication * bamf_matcher_get_application_by_xid (BamfMatcher *self, guint xid);
544+
545+#endif
546
547=== modified file 'src/bamf-matcher.c'
548--- src/bamf-matcher.c 2012-05-22 17:02:28 +0000
549+++ src/bamf-matcher.c 2012-07-31 15:13:24 +0000
550@@ -21,10 +21,9 @@
551 #include "config.h"
552
553 #include "bamf-matcher.h"
554+#include "bamf-matcher-private.h"
555 #include "bamf-application.h"
556 #include "bamf-window.h"
557-#include "bamf-legacy-window.h"
558-#include "bamf-legacy-window-test.h"
559 #include "bamf-legacy-screen.h"
560 #include "bamf-indicator-source.h"
561 #include "bamf-xutils.h"
562@@ -50,24 +49,6 @@
563 static BamfMatcher *static_matcher;
564 static guint matcher_signals[LAST_SIGNAL] = { 0 };
565
566-struct _BamfMatcherPrivate
567-{
568- GArray * bad_prefixes;
569- GArray * good_prefixes;
570- GArray * known_pids;
571- GHashTable * desktop_id_table;
572- GHashTable * desktop_file_table;
573- GHashTable * desktop_class_table;
574- GHashTable * registered_pids;
575- GHashTable * opened_closed_paths_table;
576- GList * views;
577- GList * monitors;
578- GList * favorites;
579- BamfView * active_app;
580- BamfView * active_win;
581- guint dispatch_changes_id;
582-};
583-
584 static void
585 on_view_active_changed (BamfView *view, gboolean active, BamfMatcher *matcher)
586 {
587@@ -127,7 +108,7 @@
588
589 static void bamf_matcher_unregister_view (BamfMatcher *self, BamfView *view);
590
591-static BamfApplication *
592+BamfApplication *
593 bamf_matcher_get_application_by_desktop_file (BamfMatcher *self, const char *desktop_file)
594 {
595 GList *l;
596@@ -158,6 +139,30 @@
597 return NULL;
598 }
599
600+BamfApplication *
601+bamf_matcher_get_application_by_xid (BamfMatcher *self, guint xid)
602+{
603+ GList *l;
604+ BamfView *view;
605+
606+ g_return_val_if_fail (BAMF_IS_MATCHER (self), NULL);
607+
608+ for (l = self->priv->views; l; l = l->next)
609+ {
610+ view = l->data;
611+
612+ if (!BAMF_IS_APPLICATION (view))
613+ continue;
614+
615+ if (bamf_application_manages_xid (BAMF_APPLICATION (view), xid))
616+ {
617+ return BAMF_APPLICATION (view);
618+ }
619+ }
620+
621+ return NULL;
622+}
623+
624 static gboolean
625 emit_paths_changed (gpointer user_data)
626 {
627@@ -2238,7 +2243,7 @@
628 {
629 g_return_if_fail (BAMF_IS_MATCHER (self));
630 g_return_if_fail (BAMF_IS_INDICATOR (indicator));
631-
632+
633 bamf_matcher_register_view_stealing_ref (self, BAMF_VIEW (indicator));
634 bamf_matcher_setup_indicator_state (self, indicator);
635 }
636@@ -2258,7 +2263,12 @@
637 self->priv->desktop_class_table);
638
639 /* If an application with no .desktop file has windows that matches
640- * the new added .desktop file, then we try to re-match them. */
641+ * the new added .desktop file, then we try to re-match them.
642+ * We use another list to save the windows that should be re-matched to avoid
643+ * that the list that we're iterating is changed, since reopening a window
644+ * makes it to be removed from the views. */
645+ GList *to_rematch = NULL;
646+
647 for (vl = self->priv->views; vl; vl = vl->next)
648 {
649 if (!BAMF_IS_APPLICATION (vl->data))
650@@ -2271,21 +2281,29 @@
651 GList *children = bamf_view_get_children (BAMF_VIEW (app));
652
653 for (wl = children; wl; wl = wl->next)
654- {
655- if (!BAMF_IS_WINDOW (wl->data))
656- continue;
657-
658- BamfWindow *win = BAMF_WINDOW (wl->data);
659- GList *desktops = bamf_matcher_possible_applications_for_window (self, win, NULL);
660-
661- if (g_list_find_custom (desktops, desktop_file, (GCompareFunc) g_strcmp0))
662- {
663- BamfLegacyWindow *legacy_window = bamf_window_get_window (win);
664- bamf_legacy_window_reopen (legacy_window);
665- }
666- }
667+ {
668+ if (!BAMF_IS_WINDOW (wl->data))
669+ continue;
670+
671+ BamfWindow *win = BAMF_WINDOW (wl->data);
672+ GList *desktops = bamf_matcher_possible_applications_for_window (self, win, NULL);
673+
674+ if (g_list_find_custom (desktops, desktop_file, (GCompareFunc) g_strcmp0))
675+ {
676+ BamfLegacyWindow *legacy_window = bamf_window_get_window (win);
677+ to_rematch = g_list_prepend (to_rematch, legacy_window);
678+ }
679+ }
680 }
681 }
682+
683+ for (wl = to_rematch; wl; wl = wl->next)
684+ {
685+ BamfLegacyWindow *legacy_window = BAMF_LEGACY_WINDOW (wl->data);
686+ bamf_legacy_window_reopen (legacy_window);
687+ }
688+
689+ g_list_free (to_rematch);
690 }
691
692 void
693@@ -2396,26 +2414,14 @@
694 bamf_matcher_application_for_xid (BamfMatcher *matcher,
695 guint32 xid)
696 {
697- GList *l;
698- BamfView *view;
699- BamfMatcherPrivate *priv;
700+ BamfApplication *app;
701
702 g_return_val_if_fail (BAMF_IS_MATCHER (matcher), NULL);
703
704- priv = matcher->priv;
705-
706- for (l = priv->views; l; l = l->next)
707- {
708- view = l->data;
709-
710- if (!BAMF_IS_APPLICATION (view))
711- continue;
712-
713- if (bamf_application_manages_xid (BAMF_APPLICATION (view), xid))
714- {
715- return bamf_view_get_path (view);
716- }
717- }
718+ app = bamf_matcher_get_application_by_xid (matcher, xid);
719+
720+ if (BAMF_IS_APPLICATION (app))
721+ return bamf_view_get_path (BAMF_VIEW (app));
722
723 return "";
724 }
725
726=== modified file 'src/bamf-window.c'
727--- src/bamf-window.c 2012-02-15 05:45:13 +0000
728+++ src/bamf-window.c 2012-07-31 15:13:24 +0000
729@@ -265,7 +265,7 @@
730 g_return_val_if_fail (BAMF_IS_WINDOW (view), NULL);
731 self = BAMF_WINDOW (view);
732
733- return g_strdup_printf ("window%i", bamf_legacy_window_get_xid (self->priv->legacy_window));
734+ return g_strdup_printf ("window%u", bamf_legacy_window_get_xid (self->priv->legacy_window));
735 }
736
737 gint
738
739=== added file 'tests/bamfdaemon/data/test-bamf-app.desktop'
740--- tests/bamfdaemon/data/test-bamf-app.desktop 1970-01-01 00:00:00 +0000
741+++ tests/bamfdaemon/data/test-bamf-app.desktop 2012-07-31 15:13:24 +0000
742@@ -0,0 +1,7 @@
743+[Desktop Entry]
744+Name=TestBamfApp
745+Type=Application
746+Exec=testbamfapp
747+Icon=bamf
748+StartupWMClass=test_bamf_app
749+
750
751=== modified file 'tests/bamfdaemon/test-bamf.c'
752--- tests/bamfdaemon/test-bamf.c 2012-01-19 16:22:52 +0000
753+++ tests/bamfdaemon/test-bamf.c 2012-07-31 15:13:24 +0000
754@@ -28,7 +28,7 @@
755 #include "bamf.h"
756
757 void test_application_create_suite (GDBusConnection *connection);
758-void test_matcher_create_suite (void);
759+void test_matcher_create_suite (GDBusConnection *connection);
760 void test_view_create_suite (GDBusConnection *connection);
761 void test_window_create_suite (void);
762
763@@ -39,7 +39,7 @@
764 {
765 GMainLoop *loop = data;
766
767- test_matcher_create_suite ();
768+ test_matcher_create_suite (connection);
769 test_view_create_suite (connection);
770 test_window_create_suite ();
771 test_application_create_suite (connection);
772
773=== modified file 'tests/bamfdaemon/test-matcher.c'
774--- tests/bamfdaemon/test-matcher.c 2010-05-05 10:07:48 +0000
775+++ tests/bamfdaemon/test-matcher.c 2012-07-31 15:13:24 +0000
776@@ -1,8 +1,8 @@
777 /*
778- * Copyright (C) 2009 Canonical Ltd
779+ * Copyright (C) 2009-2012 Canonical Ltd
780 *
781 * This program is free software: you can redistribute it and/or modify
782- * it under the terms of the GNU General Public License version 3 as
783+ * it under the terms of the GNU General Public License version 3 as
784 * published by the Free Software Foundation.
785 *
786 * This program is distributed in the hope that it will be useful,
787@@ -13,30 +13,313 @@
788 * You should have received a copy of the GNU General Public License
789 * along with this program. If not, see <http://www.gnu.org/licenses/>.
790 *
791- * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
792+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
793+ * Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
794 *
795 */
796
797 #include <glib.h>
798 #include <stdlib.h>
799 #include "bamf-matcher.h"
800-
801-static void test_allocation (void);
802+#include "bamf-matcher-private.h"
803+#include "bamf-legacy-screen-private.h"
804+#include "bamf-legacy-window.h"
805+#include "bamf-legacy-window-test.h"
806+
807+static void test_allocation (void);
808+static void test_load_desktop_file (void);
809+static void test_open_windows (void);
810+static void test_match_desktopless_application (void);
811+static void test_match_desktop_application (void);
812+static void test_new_desktop_matches_unmatched_windows (void);
813+
814+static GDBusConnection *gdbus_connection = NULL;
815+
816+#define DOMAIN "/Matcher"
817+#define DATA_DIR TESTDIR "/bamfdaemon/data"
818+#define TEST_BAMF_APP_DESKTOP DATA_DIR "/test-bamf-app.desktop"
819
820 void
821-test_matcher_create_suite (void)
822+test_matcher_create_suite (GDBusConnection *connection)
823 {
824-#define DOMAIN "/Matcher"
825+ gdbus_connection = connection;
826
827 g_test_add_func (DOMAIN"/Allocation", test_allocation);
828+ g_test_add_func (DOMAIN"/LoadDesktopFile", test_load_desktop_file);
829+ g_test_add_func (DOMAIN"/OpenWindows", test_open_windows);
830+ g_test_add_func (DOMAIN"/MatchDesktopLessApplication", test_match_desktopless_application);
831+ g_test_add_func (DOMAIN"/MatchDesktopApplication", test_match_desktop_application);
832+ g_test_add_func (DOMAIN"/NewMatchesUnmatchedWindows", test_new_desktop_matches_unmatched_windows);
833+}
834+
835+static void
836+export_matcher_on_bus (BamfMatcher *matcher)
837+{
838+ GError *error = NULL;
839+ g_return_if_fail (BAMF_IS_MATCHER (matcher));
840+
841+ g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (matcher),
842+ gdbus_connection, BAMF_MATCHER_PATH"/Test",
843+ &error);
844+
845+ g_assert (!error);
846+ g_clear_error (&error);
847+}
848+
849+static BamfWindow *
850+find_window_in_matcher (BamfMatcher *matcher, BamfLegacyWindow *legacy)
851+{
852+ GList *l;
853+ BamfWindow *found_window = NULL;
854+
855+ for (l = matcher->priv->views; l; l = l->next)
856+ {
857+ if (!BAMF_IS_WINDOW (l->data))
858+ continue;
859+
860+ if (bamf_window_get_window (BAMF_WINDOW (l->data)) == legacy)
861+ {
862+ g_assert (!found_window);
863+ found_window = l->data;
864+ }
865+ }
866+
867+ return found_window;
868+}
869+
870+static BamfWindow *
871+find_window_in_app (BamfApplication *app, BamfLegacyWindow *legacy)
872+{
873+ GList *l;
874+ BamfWindow *found_window = NULL;
875+
876+ for (l = bamf_view_get_children (BAMF_VIEW (app)); l; l = l->next)
877+ {
878+ if (!BAMF_IS_WINDOW (l->data))
879+ continue;
880+
881+ if (bamf_window_get_window (BAMF_WINDOW (l->data)) == legacy)
882+ {
883+ g_assert (!found_window);
884+ found_window = l->data;
885+ }
886+ }
887+
888+ return found_window;
889 }
890
891 static void
892 test_allocation (void)
893 {
894- BamfMatcher *matcher;
895+ BamfMatcher *matcher;
896
897 /* Check it allocates */
898 matcher = bamf_matcher_get_default ();
899 g_assert (BAMF_IS_MATCHER (matcher));
900-}
901+ g_object_unref (matcher);
902+}
903+
904+static void
905+test_load_desktop_file (void)
906+{
907+ BamfMatcher *matcher = bamf_matcher_get_default ();
908+ BamfMatcherPrivate *priv = matcher->priv;
909+
910+ bamf_matcher_load_desktop_file (matcher, TEST_BAMF_APP_DESKTOP);
911+
912+ GList *l = g_hash_table_lookup (priv->desktop_file_table, "testbamfapp");
913+ g_assert_cmpstr (l->data, ==, TEST_BAMF_APP_DESKTOP);
914+
915+ l = g_hash_table_lookup (priv->desktop_id_table, "test-bamf-app");
916+ g_assert_cmpstr (l->data, ==, TEST_BAMF_APP_DESKTOP);
917+
918+ const char *desktop = g_hash_table_lookup (priv->desktop_class_table, TEST_BAMF_APP_DESKTOP);
919+ g_assert_cmpstr (desktop, ==, "test_bamf_app");
920+}
921+
922+static void
923+test_open_windows (void)
924+{
925+ BamfMatcher *matcher;
926+ BamfLegacyScreen *screen;
927+ BamfLegacyWindow *window;
928+ BamfLegacyWindowTest *test_win;
929+ guint xid;
930+ const int window_count = 500;
931+
932+ screen = bamf_legacy_screen_get_default();
933+ matcher = bamf_matcher_get_default ();
934+
935+ export_matcher_on_bus (matcher);
936+
937+ for (xid = G_MAXUINT; xid > G_MAXUINT-window_count; xid--)
938+ {
939+ gchar *name = g_strdup_printf ("Test Window %u", xid);
940+ gchar *class = g_strdup_printf ("test-class-%u", xid);
941+ gchar *exec = g_strdup_printf ("test-class-%u", xid);
942+
943+ test_win = bamf_legacy_window_test_new (xid, name, class, exec);
944+ window = BAMF_LEGACY_WINDOW (test_win);
945+
946+ _bamf_legacy_screen_open_test_window (screen, test_win);
947+ g_assert (g_list_find (bamf_legacy_screen_get_windows (screen), test_win));
948+ g_assert (find_window_in_matcher (matcher, window));
949+ g_assert (bamf_matcher_get_application_by_xid (matcher, xid));
950+
951+ _bamf_legacy_screen_close_test_window (screen, test_win);
952+ g_assert (!g_list_find (bamf_legacy_screen_get_windows (screen), test_win));
953+ g_assert (!find_window_in_matcher (matcher, window));
954+ g_assert (!bamf_matcher_get_application_by_xid (matcher, xid));
955+
956+ g_free (name);
957+ g_free (class);
958+ g_free (exec);
959+ }
960+
961+ g_object_unref (matcher);
962+ g_object_unref (screen);
963+}
964+
965+static void
966+test_match_desktopless_application (void)
967+{
968+ BamfMatcher *matcher;
969+ BamfLegacyScreen *screen;
970+ BamfLegacyWindow *window;
971+ BamfLegacyWindowTest *test_win;
972+ BamfApplication *app;
973+ GList *test_windows = NULL, *l, *app_children;
974+ guint xid;
975+ const int window_count = 5;
976+
977+ screen = bamf_legacy_screen_get_default();
978+ matcher = bamf_matcher_get_default ();
979+ char *exec = "test-bamf-app";
980+ char *class = "test-bamf-app";
981+
982+ export_matcher_on_bus (matcher);
983+
984+ for (xid = G_MAXUINT; xid > G_MAXUINT-window_count; xid--)
985+ {
986+ gchar *name = g_strdup_printf ("Test Window %u", xid);
987+
988+ test_win = bamf_legacy_window_test_new (xid, name, class, exec);
989+ window = BAMF_LEGACY_WINDOW (test_win);
990+ test_windows = g_list_prepend (test_windows, window);
991+
992+ _bamf_legacy_screen_open_test_window (screen, test_win);
993+ g_free (name);
994+ }
995+
996+ app = bamf_matcher_get_application_by_xid (matcher, G_MAXUINT);
997+ g_assert (app);
998+
999+ app_children = bamf_view_get_children (BAMF_VIEW (app));
1000+ g_assert_cmpuint (g_list_length (app_children), ==, window_count);
1001+
1002+ for (l = test_windows; l; l = l->next)
1003+ {
1004+ g_assert (find_window_in_app (app, BAMF_LEGACY_WINDOW (l->data)));
1005+ }
1006+
1007+ g_list_free (test_windows);
1008+ g_object_unref (matcher);
1009+ g_object_unref (screen);
1010+}
1011+
1012+static void
1013+test_match_desktop_application (void)
1014+{
1015+ BamfMatcher *matcher;
1016+ BamfLegacyScreen *screen;
1017+ BamfLegacyWindow *window;
1018+ BamfLegacyWindowTest *test_win;
1019+ BamfApplication *app;
1020+ GList *test_windows = NULL, *l, *app_children;
1021+ guint xid;
1022+ const int window_count = 5;
1023+
1024+ screen = bamf_legacy_screen_get_default();
1025+ matcher = bamf_matcher_get_default ();
1026+ char *exec = "testbamfapp";
1027+ char *class = "test_bamf_app";
1028+
1029+ export_matcher_on_bus (matcher);
1030+ bamf_matcher_load_desktop_file (matcher, TEST_BAMF_APP_DESKTOP);
1031+
1032+ for (xid = G_MAXUINT; xid > G_MAXUINT-window_count; xid--)
1033+ {
1034+ gchar *name = g_strdup_printf ("Test Window %u", xid);
1035+
1036+ test_win = bamf_legacy_window_test_new (xid, name, class, exec);
1037+ window = BAMF_LEGACY_WINDOW (test_win);
1038+ test_windows = g_list_prepend (test_windows, window);
1039+
1040+ _bamf_legacy_screen_open_test_window (screen, test_win);
1041+ g_free (name);
1042+ }
1043+
1044+ app = bamf_matcher_get_application_by_desktop_file (matcher, TEST_BAMF_APP_DESKTOP);
1045+ g_assert (app);
1046+
1047+ g_assert (bamf_matcher_get_application_by_xid (matcher, G_MAXUINT) == app);
1048+
1049+ app_children = bamf_view_get_children (BAMF_VIEW (app));
1050+ g_assert_cmpuint (g_list_length (app_children), ==, window_count);
1051+
1052+ for (l = test_windows; l; l = l->next)
1053+ {
1054+ g_assert (find_window_in_app (app, BAMF_LEGACY_WINDOW (l->data)));
1055+ }
1056+
1057+ g_list_free (test_windows);
1058+ g_object_unref (matcher);
1059+ g_object_unref (screen);
1060+}
1061+
1062+static void
1063+test_new_desktop_matches_unmatched_windows (void)
1064+{
1065+ BamfMatcher *matcher;
1066+ BamfLegacyScreen *screen;
1067+ BamfLegacyWindowTest *test_win;
1068+ BamfApplication *app;
1069+ GList *app_children;
1070+ guint xid = 0;
1071+ const int window_count = 5;
1072+
1073+ screen = bamf_legacy_screen_get_default();
1074+ matcher = bamf_matcher_get_default ();
1075+ char *exec = "testbamfapp";
1076+ char *class = "test_bamf_app";
1077+
1078+ export_matcher_on_bus (matcher);
1079+ g_assert (!bamf_matcher_get_application_by_desktop_file (matcher, TEST_BAMF_APP_DESKTOP));
1080+
1081+ for (xid = G_MAXUINT; xid > G_MAXUINT-window_count; xid--)
1082+ {
1083+ gchar *name = g_strdup_printf ("Test Window %u", xid);
1084+
1085+ test_win = bamf_legacy_window_test_new (xid, name, class, exec);
1086+ _bamf_legacy_screen_open_test_window (screen, test_win);
1087+
1088+ g_free (name);
1089+ }
1090+
1091+ bamf_matcher_load_desktop_file (matcher, TEST_BAMF_APP_DESKTOP);
1092+
1093+ app = bamf_matcher_get_application_by_desktop_file (matcher, TEST_BAMF_APP_DESKTOP);
1094+ g_assert (app);
1095+
1096+ app_children = bamf_view_get_children (BAMF_VIEW (app));
1097+ g_assert_cmpuint (g_list_length (app_children), ==, window_count);
1098+
1099+ for (xid = G_MAXUINT; xid > G_MAXUINT-window_count; xid--)
1100+ {
1101+ g_assert (bamf_matcher_get_application_by_xid (matcher, xid) == app);
1102+ }
1103+
1104+ g_object_unref (matcher);
1105+ g_object_unref (screen);
1106+}
1107+

Subscribers

People subscribed via source and target branches