Merge lp:~mhr3/bamf/non-chatty-signals into lp:bamf/0.4

Proposed by Michal Hruby
Status: Merged
Approved by: Marco Trevisan (Treviño)
Approved revision: 465
Merged at revision: 430
Proposed branch: lp:~mhr3/bamf/non-chatty-signals
Merge into: lp:bamf/0.4
Prerequisite: lp:~3v1n0/bamf/libbamf-net-dbus-hints
Diff against target: 453 lines (+220/-26)
4 files modified
src/bamf-application.c (+4/-8)
src/bamf-application.h (+2/-2)
src/bamf-matcher.c (+207/-16)
src/org.ayatana.bamf.xml (+7/-0)
To merge this branch: bzr merge lp:~mhr3/bamf/non-chatty-signals
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) Approve
Mikkel Kamstrup Erlandsen (community) Approve
Review via email: mp+88462@code.launchpad.net

This proposal supersedes a proposal from 2012-01-13.

Description of the change

Added method and signal to list desktop file paths of running applications, this is needed for application lens, which should exclude running applications from the default results and we need to minimize the number of wakeups of the lens daemon.

To post a comment you must log in.
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Looks good to me.

review: Approve
Revision history for this message
Unity Merger (unity-merger) wrote :

The prerequisite lp:~3v1n0/bamf/libbamf-net-dbus-hints has not yet been merged into lp:bamf.

Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

This looks awesome, just one thing:

  192 + priv->idle_cb_id = g_idle_add (emit_paths_changed, self);

Can you make this a longer timeout? There's no point in guaranteeing super fine granularity in the updates when we have a signal suitable for batching. I am thinking 200ms or maybe as much as 500ms...

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

Changed the idle to 500ms timeout.

Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

Likes!

review: Approve
Revision history for this message
Unity Merger (unity-merger) wrote :

The prerequisite lp:~3v1n0/bamf/libbamf-net-dbus-hints has not yet been merged into lp:bamf.

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

Please fix the small conflict that this branch has with newest trunk, then it's ready to go in! :)

review: Needs Fixing
lp:~mhr3/bamf/non-chatty-signals updated
465. By Michal Hruby

Merge trunk

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) :
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-01-03 16:23:18 +0000
3+++ src/bamf-application.c 2012-01-20 16:06:24 +0000
4@@ -65,30 +65,26 @@
5 return g_strdup (application->priv->app_type);
6 }
7
8-char *
9+const char *
10 bamf_application_get_desktop_file (BamfApplication *application)
11 {
12 BamfApplicationPrivate *priv;
13- char *result = NULL;
14
15 g_return_val_if_fail (BAMF_IS_APPLICATION (application), NULL);
16 priv = application->priv;
17
18- result = g_strdup (priv->desktop_file);
19- return result;
20+ return priv->desktop_file;
21 }
22
23-char *
24+const char *
25 bamf_application_get_wmclass (BamfApplication *application)
26 {
27 BamfApplicationPrivate *priv;
28- char *result = NULL;
29
30 g_return_val_if_fail (BAMF_IS_APPLICATION (application), NULL);
31 priv = application->priv;
32
33- result = g_strdup (priv->wmclass);
34- return result;
35+ return priv->wmclass;
36 }
37
38 static gboolean
39
40=== modified file 'src/bamf-application.h'
41--- src/bamf-application.h 2011-12-22 00:33:12 +0000
42+++ src/bamf-application.h 2012-01-20 16:06:24 +0000
43@@ -53,7 +53,7 @@
44
45 GType bamf_application_get_type (void) G_GNUC_CONST;
46
47-char * bamf_application_get_desktop_file (BamfApplication *application);
48+const char * bamf_application_get_desktop_file (BamfApplication *application);
49 void bamf_application_set_desktop_file (BamfApplication *application,
50 const char * desktop_file);
51
52@@ -65,7 +65,7 @@
53 gboolean bamf_application_contains_similar_to_window (BamfApplication *app,
54 BamfWindow *window);
55
56-char * bamf_application_get_wmclass (BamfApplication *application);
57+const char * bamf_application_get_wmclass (BamfApplication *application);
58 void bamf_application_set_wmclass (BamfApplication *application,
59 const char *wmclass);
60
61
62=== modified file 'src/bamf-matcher.c'
63--- src/bamf-matcher.c 2012-01-10 14:43:24 +0000
64+++ src/bamf-matcher.c 2012-01-20 16:06:24 +0000
65@@ -40,6 +40,12 @@
66 LAST_SIGNAL,
67 };
68
69+typedef enum
70+{
71+ VIEW_ADDED = 0,
72+ VIEW_REMOVED
73+} ViewChangeType;
74+
75 static guint matcher_signals[LAST_SIGNAL] = { 0 };
76
77 struct _BamfMatcherPrivate
78@@ -50,11 +56,13 @@
79 GHashTable * desktop_file_table;
80 GHashTable * desktop_class_table;
81 GHashTable * registered_pids;
82+ GHashTable * opened_closed_paths_table;
83 GList * views;
84 GList * monitors;
85 GList * favorites;
86 BamfView * active_app;
87 BamfView * active_win;
88+ guint dispatch_changes_id;
89 };
90
91 static void
92@@ -117,6 +125,106 @@
93
94 static void bamf_matcher_unregister_view (BamfMatcher *self, BamfView *view, gboolean unref);
95
96+static gboolean
97+emit_paths_changed (gpointer user_data)
98+{
99+ BamfMatcher *matcher;
100+ BamfMatcherPrivate *priv;
101+ GHashTableIter iter;
102+ guint ht_size;
103+ ViewChangeType change_type;
104+ gpointer key, value;
105+ gchar **opened_apps, **closed_apps;
106+ gint i, j;
107+
108+ g_return_val_if_fail (BAMF_IS_MATCHER (user_data), FALSE);
109+
110+ matcher = (BamfMatcher*) user_data;
111+ priv = matcher->priv;
112+
113+ ht_size = g_hash_table_size (priv->opened_closed_paths_table);
114+ /* these will end with NULL pointer */
115+ opened_apps = g_new0 (gchar*, ht_size+1);
116+ closed_apps = g_new0 (gchar*, ht_size+1);
117+ i = 0;
118+ j = 0;
119+
120+ g_hash_table_iter_init (&iter, priv->opened_closed_paths_table);
121+ while (g_hash_table_iter_next (&iter, &key, &value))
122+ {
123+ change_type = (ViewChangeType) GPOINTER_TO_INT (value);
124+ if (change_type == VIEW_ADDED)
125+ opened_apps[i++] = (gchar*) key;
126+ else
127+ closed_apps[j++] = (gchar*) key;
128+ }
129+
130+ /* the strings are owned by the hashtable, so emit the signal and clear
131+ * the hashtable then */
132+ g_signal_emit_by_name (matcher, "running-applications-changed",
133+ opened_apps, closed_apps);
134+
135+ g_hash_table_remove_all (priv->opened_closed_paths_table);
136+
137+ g_free (closed_apps);
138+ g_free (opened_apps);
139+
140+ priv->dispatch_changes_id = 0;
141+
142+ return FALSE;
143+}
144+
145+static void bamf_matcher_prepare_path_change (BamfMatcher *self, const gchar *desktop_file, ViewChangeType change_type)
146+{
147+ GList *l;
148+ BamfView *view;
149+ BamfMatcherPrivate *priv;
150+ const char *app_desktop;
151+ gboolean found = FALSE;
152+
153+ if (desktop_file == NULL) return;
154+
155+ g_return_if_fail (BAMF_IS_MATCHER (self));
156+
157+ priv = self->priv;
158+
159+ for (l = priv->views; l; l = l->next)
160+ {
161+ view = l->data;
162+
163+ if (!BAMF_IS_APPLICATION (view) || !bamf_view_is_running (view))
164+ continue;
165+
166+ app_desktop = bamf_application_get_desktop_file (BAMF_APPLICATION (view));
167+ if (!app_desktop) continue;
168+
169+ if (g_strcmp0 (desktop_file, app_desktop) == 0)
170+ {
171+ found = TRUE;
172+ break;
173+ }
174+ }
175+
176+ /* the app was already running (ADDED) / had more instances which are still
177+ * there (REMOVED) */
178+ if (found) return;
179+
180+ if (!priv->opened_closed_paths_table)
181+ {
182+ priv->opened_closed_paths_table = g_hash_table_new_full (g_str_hash,
183+ g_str_equal,
184+ g_free, NULL);
185+ }
186+
187+ g_hash_table_insert (priv->opened_closed_paths_table,
188+ g_strdup (desktop_file), GINT_TO_POINTER (change_type));
189+
190+ if (priv->dispatch_changes_id == 0)
191+ {
192+ priv->dispatch_changes_id = g_timeout_add (500, emit_paths_changed, self);
193+ }
194+}
195+
196 static void
197 on_view_closed (BamfView *view, BamfMatcher *self)
198 {
199@@ -139,6 +247,13 @@
200 g_signal_connect (G_OBJECT (view), "active-changed",
201 (GCallback) on_view_active_changed, self);
202
203+
204+ if (BAMF_IS_APPLICATION (view))
205+ {
206+ bamf_matcher_prepare_path_change (self,
207+ bamf_application_get_desktop_file (BAMF_APPLICATION (view)), VIEW_ADDED);
208+ }
209+
210 self->priv->views = g_list_prepend (self->priv->views, view);
211 g_object_ref (view);
212
213@@ -166,6 +281,14 @@
214 if (unref)
215 {
216 self->priv->views = g_list_remove (self->priv->views, view);
217+
218+ if (BAMF_IS_APPLICATION (view))
219+ {
220+ bamf_matcher_prepare_path_change (self,
221+ bamf_application_get_desktop_file (BAMF_APPLICATION (view)),
222+ VIEW_REMOVED);
223+ }
224+
225 g_object_unref (view);
226 }
227 }
228@@ -1462,8 +1585,8 @@
229 BamfLegacyWindow *window;
230 GList *views, *a;
231 const char *win_class;
232- char *desktop_file;
233- char *app_class;
234+ const char *desktop_file;
235+ const char *app_class;
236 BamfApplication *app = NULL, *best = NULL;
237 BamfView *view;
238
239@@ -1512,9 +1635,6 @@
240 if (bamf_application_contains_similar_to_window (app, bamf_window) && (!best || !g_strcmp0 (win_class, app_class)))
241 best = app;
242 }
243-
244- g_free (desktop_file);
245- g_free (app_class);
246 }
247
248 if (!best)
249@@ -1723,7 +1843,7 @@
250 {
251 GList *possible_apps, *l;
252 GList *views, *a;
253- char *desktop_file;
254+ const char *desktop_file;
255 BamfApplication *app = NULL, *best = NULL;
256 BamfView *view;
257
258@@ -1761,8 +1881,6 @@
259 }
260 }
261 }
262-
263- g_free (desktop_file);
264 }
265
266 if (!best)
267@@ -1991,7 +2109,7 @@
268 bamf_matcher_application_is_running (BamfMatcher *matcher,
269 const char *application)
270 {
271- char * desktop_file;
272+ const char * desktop_file;
273 GList *l;
274 BamfView *view;
275 BamfMatcherPrivate *priv;
276@@ -2010,10 +2128,8 @@
277 desktop_file = bamf_application_get_desktop_file (BAMF_APPLICATION (view));
278 if (g_strcmp0 (desktop_file, application) == 0)
279 {
280- g_free (desktop_file);
281 return bamf_view_is_running (view);
282 }
283- g_free (desktop_file);
284 }
285
286 return FALSE;
287@@ -2084,7 +2200,7 @@
288 const char *application)
289 {
290 const char * path = "";
291- char * desktop_file;
292+ const char * desktop_file;
293 GList *l;
294 BamfView *view;
295 BamfMatcherPrivate *priv;
296@@ -2105,7 +2221,6 @@
297 {
298 path = bamf_view_get_path (view);
299 }
300- g_free (desktop_file);
301 }
302
303 return path;
304@@ -2176,6 +2291,59 @@
305 }
306
307 GVariant *
308+bamf_matcher_running_applications_desktop_files (BamfMatcher *matcher)
309+{
310+ GList *l;
311+ BamfView *view;
312+ BamfMatcherPrivate *priv;
313+ GSequence *paths;
314+ GSequenceIter *iter;
315+ const char *desktop_file;
316+ GVariantBuilder b;
317+
318+ g_return_val_if_fail (BAMF_IS_MATCHER (matcher), NULL);
319+
320+ g_variant_builder_init (&b, G_VARIANT_TYPE ("(as)"));
321+ g_variant_builder_open (&b, G_VARIANT_TYPE ("as"));
322+
323+ paths = g_sequence_new (NULL);
324+
325+ priv = matcher->priv;
326+
327+ for (l = priv->views; l; l = l->next)
328+ {
329+ view = l->data;
330+
331+ if (!BAMF_IS_APPLICATION (view) || !bamf_view_is_running (view))
332+ continue;
333+
334+ desktop_file = bamf_application_get_desktop_file (BAMF_APPLICATION (view));
335+ if (!desktop_file) continue;
336+
337+ if (g_sequence_lookup (paths, (gpointer) desktop_file,
338+ (GCompareDataFunc) g_strcmp0, NULL) == NULL)
339+ {
340+ g_sequence_insert_sorted (paths, (gpointer) desktop_file,
341+ (GCompareDataFunc) g_strcmp0, NULL);
342+ }
343+ }
344+
345+ iter = g_sequence_get_begin_iter (paths);
346+ while (!g_sequence_iter_is_end (iter))
347+ {
348+ g_variant_builder_add (&b, "s", g_sequence_get (iter));
349+
350+ iter = g_sequence_iter_next (iter);
351+ }
352+
353+ g_sequence_free (paths);
354+
355+ g_variant_builder_close (&b);
356+
357+ return g_variant_builder_end (&b);
358+}
359+
360+GVariant *
361 bamf_matcher_tab_dbus_paths (BamfMatcher *matcher)
362 {
363 GVariantBuilder b;
364@@ -2192,7 +2360,7 @@
365 {
366 GVariantBuilder b;
367 GVariant *xids;
368- char * desktop_file;
369+ const char * desktop_file;
370 GList *l;
371 BamfView *view;
372 BamfMatcherPrivate *priv;
373@@ -2213,10 +2381,8 @@
374 if (g_strcmp0 (desktop_file, application) == 0)
375 {
376 xids = bamf_application_get_xids (BAMF_APPLICATION (view));
377- g_free (desktop_file);
378 break;
379 }
380- g_free (desktop_file);
381 }
382
383 if (!xids)
384@@ -2288,6 +2454,17 @@
385 }
386
387 static gboolean
388+on_dbus_handle_running_applications_desktop_files (BamfDBusMatcher *interface,
389+ GDBusMethodInvocation *invocation,
390+ BamfMatcher *self)
391+{
392+ GVariant *paths = bamf_matcher_running_applications_desktop_files (self);
393+ g_dbus_method_invocation_return_value (invocation, paths);
394+
395+ return TRUE;
396+}
397+
398+static gboolean
399 on_dbus_handle_active_application (BamfDBusMatcher *interface,
400 GDBusMethodInvocation *invocation,
401 BamfMatcher *self)
402@@ -2436,6 +2613,9 @@
403 g_signal_connect (self, "handle-running-applications",
404 G_CALLBACK (on_dbus_handle_running_applications), self);
405
406+ g_signal_connect (self, "handle-running-applications-desktop-files",
407+ G_CALLBACK (on_dbus_handle_running_applications_desktop_files), self);
408+
409 g_signal_connect (self, "handle-active-window",
410 G_CALLBACK (on_dbus_handle_active_window), self);
411
412@@ -2497,6 +2677,17 @@
413 g_hash_table_destroy (priv->desktop_class_table);
414 g_hash_table_destroy (priv->registered_pids);
415
416+ if (priv->opened_closed_paths_table)
417+ {
418+ g_hash_table_destroy (priv->opened_closed_paths_table);
419+ }
420+
421+ if (priv->dispatch_changes_id != 0)
422+ {
423+ g_source_remove (priv->dispatch_changes_id);
424+ priv->dispatch_changes_id = 0;
425+ }
426+
427 g_list_free_full (priv->views, g_object_unref);
428
429 g_signal_handlers_disconnect_by_func (screen, handle_window_opened, self);
430
431=== modified file 'src/org.ayatana.bamf.xml'
432--- src/org.ayatana.bamf.xml 2012-01-10 14:28:44 +0000
433+++ src/org.ayatana.bamf.xml 2012-01-20 16:06:24 +0000
434@@ -30,6 +30,9 @@
435 <method name="RunningApplications">
436 <arg name="paths" type="as" direction="out"/>
437 </method>
438+ <method name="RunningApplicationsDesktopFiles">
439+ <arg name="paths" type="as" direction="out"/>
440+ </method>
441 <method name="RegisterFavorites">
442 <arg name="favorites" type="as" direction="in"/>
443 </method>
444@@ -79,5 +82,9 @@
445 </signal>
446 <signal name="StackingOrderChanged">
447 </signal>
448+ <signal name="RunningApplicationsChanged">
449+ <arg name="opened_desktop_files" type="as"/>
450+ <arg name="closed_desktop_files" type="as"/>
451+ </signal>
452 </interface>
453 </node>

Subscribers

People subscribed via source and target branches