Merge lp:~donadigo/wingpanel-indicator-notifications/memory-improvements into lp:~wingpanel-devs/wingpanel-indicator-notifications/wingpanel-indicator-notifications

Proposed by Adam Bieńkowski
Status: Merged
Approved by: Felipe Escoto
Approved revision: 109
Merged at revision: 106
Proposed branch: lp:~donadigo/wingpanel-indicator-notifications/memory-improvements
Merge into: lp:~wingpanel-devs/wingpanel-indicator-notifications/wingpanel-indicator-notifications
Diff against target: 705 lines (+178/-230)
6 files modified
src/Indicator.vala (+5/-9)
src/Services/Notification.vala (+28/-18)
src/Services/Session.vala (+17/-20)
src/Widgets/AppEntry.vala (+25/-43)
src/Widgets/NotificationEntry.vala (+5/-8)
src/Widgets/NotificationsList.vala (+98/-132)
To merge this branch: bzr merge lp:~donadigo/wingpanel-indicator-notifications/memory-improvements
Reviewer Review Type Date Requested Status
Felipe Escoto Approve
Review via email: mp+300662@code.launchpad.net

Commit message

- Memory improvements
- Removed unneded code logic
- Code cleanup
- Simplified code
- Fixed: session would not load on startup
- Added: DesktopID key to session to be able to recognize sender

Description of the change

This branch aims to lower the memory use, remove unneded logic and simplify the code for easier reading. It also fixes that the previous session wouldn't load because it was cleared before it actually loaded.

The most changes were made to NotificationsList class where we now don't store all entries, only app entries which already contain every information we need.

Improvements were also made to the Session class where we only store one key file object and use it for both write / read operations. We now also save DesktopID key which will help the indicator recognize the sender from previous session.

The branch does not introduce any new features. However it needs extensive testing & code review before it can get merged.

To post a comment you must log in.
107. By Adam Bieńkowski

Init app_entry with null

108. By Adam Bieńkowski

Use foreach function

109. By Adam Bieńkowski

Rename add_app_entry to add_entry_internal; bring back the resort function for AppEntry

Revision history for this message
Felipe Escoto (philip.scott) wrote :

Still working as intended :) good job!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/Indicator.vala'
2--- src/Indicator.vala 2016-07-18 15:57:23 +0000
3+++ src/Indicator.vala 2016-07-21 12:53:02 +0000
4@@ -117,7 +117,6 @@
5 main_box.pack_end (clear_all_btn, false, false, 0);
6 main_box.show_all ();
7
8- nlist.clear_all ();
9 restore_previous_session ();
10
11 dynamic_icon.set_main_icon_name (get_display_icon_name ());
12@@ -155,7 +154,7 @@
13
14 if (app_settings == null || app_settings.get_boolean (REMEMBER_KEY)) {
15 var entry = new NotificationEntry (notification);
16- nlist.add_item (entry);
17+ nlist.add_entry (entry);
18 }
19
20 dynamic_icon.set_main_icon_name (get_display_icon_name ());
21@@ -174,18 +173,15 @@
22
23 private void restore_previous_session () {
24 var previous_session = Session.get_instance ().get_session_notifications ();
25- if (previous_session.length () > 0) {
26- previous_session.@foreach ((notification) => {
27- var entry = new NotificationEntry (notification);
28- nlist.add_item (entry);
29- });
30- }
31+ previous_session.foreach ((notification) => {
32+ nlist.add_entry (new NotificationEntry (notification));
33+ });
34 }
35
36 private string get_display_icon_name () {
37 if (NotifySettings.get_instance ().do_not_disturb) {
38 return "notification-disabled-symbolic";
39- } else if (nlist != null && nlist.get_items_length () > 0) {
40+ } else if (nlist != null && nlist.get_entries_length () > 0) {
41 return "notification-new-symbolic";
42 }
43
44
45=== modified file 'src/Services/Notification.vala'
46--- src/Services/Notification.vala 2016-07-18 15:42:58 +0000
47+++ src/Services/Notification.vala 2016-07-21 12:53:02 +0000
48@@ -21,7 +21,6 @@
49 public bool data_session;
50
51 public string app_name;
52- public string display_name;
53 public string summary;
54 public string message_body;
55 public string app_icon;
56@@ -63,7 +62,6 @@
57 data_session = false;
58
59 app_name = get_string (body, Column.APP_NAME);
60- display_name = app_name;
61 app_icon = get_string (body, Column.APP_ICON);
62 summary = get_string (body, Column.SUMMARY);
63 message_body = get_string (body, Column.BODY);
64@@ -102,11 +100,10 @@
65
66 public Notification.from_data (uint32 _id, string _app_name, string _app_icon,
67 string _summary, string _message_body,
68- string[] _actions, int64 _unix_time, string _sender) {
69+ string[] _actions, string _desktop_id, int64 _unix_time, string _sender) {
70 data_session = true;
71
72 app_name = _app_name;
73- display_name = app_name;
74 app_icon = _app_icon;
75 summary = _summary;
76 message_body = _message_body;
77@@ -115,15 +112,14 @@
78 id = _id;
79 sender = _sender;
80
81- app_info = Utils.get_appinfo_from_app_name (app_name);
82-
83- setup_pid ();
84-
85 actions = _actions;
86 unix_time = _unix_time;
87 timestamp = new DateTime.from_unix_local (unix_time);
88
89- desktop_id = "";
90+ desktop_id = _desktop_id;
91+ app_info = new DesktopAppInfo (desktop_id);
92+
93+ setup_pid ();
94
95 Timeout.add_seconds_full (Priority.DEFAULT, 60, source_func);
96 }
97@@ -132,6 +128,29 @@
98 return app_info != null;
99 }
100
101+ public bool run_default_action () {
102+ if (DEFAULT_ACTION in actions && NotificationMonitor.get_instance ().notifications_iface != null) {
103+ NotificationMonitor.get_instance ().notifications_iface.action_invoked (DEFAULT_ACTION, id);
104+ return true;
105+ }
106+
107+ return false;
108+ }
109+
110+ public Wnck.Window? get_app_window () {
111+ Wnck.Window? window = null;
112+ if (pid_accuired) {
113+ Wnck.Screen.get_default ().get_windows ().foreach ((_window) => {
114+ if (_window.get_pid () == pid && window == null) {
115+ window = _window;
116+ return;
117+ }
118+ });
119+ }
120+
121+ return window;
122+ }
123+
124 private void setup_pid () {
125 pid_accuired = try_get_pid ();
126 NotifySettings.get_instance ().changed[NotifySettings.DO_NOT_DISTURB_KEY].connect (() => {
127@@ -158,15 +177,6 @@
128 return true;
129 }
130
131- public bool run_default_action () {
132- if (DEFAULT_ACTION in actions && NotificationMonitor.get_instance ().notifications_iface != null) {
133- NotificationMonitor.get_instance ().notifications_iface.action_invoked (DEFAULT_ACTION, id);
134- return true;
135- }
136-
137- return false;
138- }
139-
140 private string get_string (Variant tuple, int column) {
141 var child = tuple.get_child_value (column);
142 return child.dup_string ();
143
144=== modified file 'src/Services/Session.vala'
145--- src/Services/Session.vala 2016-07-17 17:49:54 +0000
146+++ src/Services/Session.vala 2016-07-21 12:53:02 +0000
147@@ -25,14 +25,14 @@
148 private const string SESSION_FILE_NAME = ".notifications.session";
149 private static Session? instance = null;
150
151- private static File? session_file = null;
152- private static string full_path;
153+ private File session_file = null;
154
155 private const string APP_NAME_KEY = "AppName";
156 private const string APP_ICON_KEY = "AppIcon";
157 private const string SUMMARY_KEY = "Summary";
158 private const string BODY_KEY = "Body";
159 private const string ACTIONS_KEY = "Actions";
160+ private const string DESKTOP_ID_KEY = "DesktopID";
161 private const string UNIX_TIME_KEY = "UnixTime";
162 private const string SENDER_KEY = "Sender";
163
164@@ -47,29 +47,29 @@
165 }
166
167 private Session () {
168- full_path = Path.build_filename (Environment.get_user_cache_dir (), SESSION_FILE_NAME);
169- session_file = File.new_for_path (full_path);
170- if (!session_file.query_exists ())
171+ session_file = File.new_for_path (Path.build_filename (Environment.get_user_cache_dir (), SESSION_FILE_NAME));
172+ if (!session_file.query_exists ()) {
173 create_session_file ();
174+ }
175
176 key = new KeyFile ();
177- key.set_list_separator (',');
178+ key.set_list_separator (';');
179 }
180
181 public List<Notification> get_session_notifications () {
182 var list = new List<Notification> ();
183- var _key = new KeyFile ();
184 try {
185- _key.load_from_file (full_path, KeyFileFlags.NONE);
186- foreach (unowned string group in _key.get_groups ()) {
187+ key.load_from_file (session_file.get_path (), KeyFileFlags.NONE);
188+ foreach (unowned string group in key.get_groups ()) {
189 var notification = new Notification.from_data ((uint32)int.parse (group),
190- _key.get_string (group, APP_NAME_KEY),
191- _key.get_string (group, APP_ICON_KEY),
192- _key.get_string (group, SUMMARY_KEY),
193- _key.get_string (group, BODY_KEY),
194- _key.get_string_list (group, ACTIONS_KEY),
195- _key.get_int64 (group, UNIX_TIME_KEY),
196- _key.get_string (group, SENDER_KEY));
197+ key.get_string (group, APP_NAME_KEY),
198+ key.get_string (group, APP_ICON_KEY),
199+ key.get_string (group, SUMMARY_KEY),
200+ key.get_string (group, BODY_KEY),
201+ key.get_string_list (group, ACTIONS_KEY),
202+ key.get_string (group, DESKTOP_ID_KEY),
203+ key.get_int64 (group, UNIX_TIME_KEY),
204+ key.get_string (group, SENDER_KEY));
205 list.append (notification);
206 }
207 } catch (KeyFileError e) {
208@@ -88,6 +88,7 @@
209 key.set_string (id, SUMMARY_KEY, notification.summary);
210 key.set_string (id, BODY_KEY, notification.message_body);
211 key.set_string_list (id, ACTIONS_KEY, notification.actions);
212+ key.set_string (id, DESKTOP_ID_KEY, notification.desktop_id);
213 key.set_int64 (id, UNIX_TIME_KEY, notification.unix_time);
214 key.set_string (id, SENDER_KEY, notification.sender);
215
216@@ -106,7 +107,6 @@
217
218 public void clear () {
219 try {
220- key = new KeyFile ();
221 FileUtils.set_contents (session_file.get_path (), "");
222 } catch (FileError e) {
223 warning (e.message);
224@@ -122,9 +122,6 @@
225 }
226
227 private void write_contents () {
228- if (session_file == null)
229- create_session_file ();
230-
231 try {
232 FileUtils.set_contents (session_file.get_path (), key.to_data ());
233 } catch (FileError e) {
234
235=== modified file 'src/Widgets/AppEntry.vala'
236--- src/Widgets/AppEntry.vala 2016-07-17 18:46:38 +0000
237+++ src/Widgets/AppEntry.vala 2016-07-21 12:53:02 +0000
238@@ -16,49 +16,32 @@
239 */
240
241 public class AppEntry : Gtk.ListBoxRow {
242- public string desktop_id;
243- public Gtk.Button clear_btn_entry;
244- public AppInfo? app_info = null;
245- public Wnck.Window? app_window;
246-
247- public signal void destroy_entry ();
248-
249- private List<NotificationEntry> app_notifications;
250- private string display_name;
251-
252- public AppEntry (NotificationEntry entry, Wnck.Window? _app_window) {
253+ public signal void clear ();
254+
255+ public AppInfo app_info;
256+ public List<NotificationEntry> app_notifications;
257+
258+ public AppEntry (NotificationEntry entry) {
259 margin_bottom = 3;
260 margin_top = 3;
261 margin_start = 12;
262 margin_end = 6;
263
264+ app_notifications = new List<NotificationEntry> ();
265+ add_notification_entry (entry);
266+
267 var notification = entry.notification;
268- desktop_id = notification.desktop_id;
269- app_window = _app_window;
270 app_info = notification.app_info;
271
272- app_notifications = new List<NotificationEntry> ();
273- add_notification_entry (entry);
274-
275 var hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 12);
276
277- /* Capitalize the first letter */
278- char[] utf8 = notification.display_name.to_utf8 ();
279- utf8[0] = utf8[0].toupper ();
280-
281- if (app_info != null) {
282- display_name = app_info.get_name ();
283- } else {
284- display_name = string.join ("", utf8);
285- }
286-
287- var label = new Gtk.Label (display_name);
288+ var label = new Gtk.Label (app_info.get_name ());
289 label.get_style_context ().add_class ("h3");
290
291- clear_btn_entry = new Gtk.Button.from_icon_name ("edit-clear-symbolic", Gtk.IconSize.SMALL_TOOLBAR);
292+ var clear_btn_entry = new Gtk.Button.from_icon_name ("edit-clear-symbolic", Gtk.IconSize.SMALL_TOOLBAR);
293 clear_btn_entry.get_style_context ().add_class ("flat");
294 clear_btn_entry.clicked.connect (() => {
295- destroy_entry ();
296+ clear ();
297 });
298
299 string icon = "";
300@@ -74,33 +57,32 @@
301 hbox.pack_start (label, false, false, 0);
302 hbox.pack_end (clear_btn_entry, false, false, 0);
303
304- connect_entry (entry);
305-
306 add (hbox);
307 show_all ();
308 }
309
310- private void connect_entry (NotificationEntry entry) {
311- entry.clear.connect (() => {
312- if (entry != null) {
313- remove_notification_entry (entry);
314- }
315- });
316- }
317+ public Wnck.Window? get_app_window () {
318+ if (app_notifications.length () == 0) {
319+ return null;
320+ }
321
322- public unowned List<NotificationEntry> get_notifications () {
323- return app_notifications;
324+ var entry = app_notifications.first ().data;
325+ return entry.notification.get_app_window ();
326 }
327
328 public void add_notification_entry (NotificationEntry entry) {
329 app_notifications.prepend (entry);
330- connect_entry (entry);
331+ entry.clear.connect (remove_notification_entry);
332 }
333
334- public void remove_notification_entry (NotificationEntry entry) {
335+ public async void remove_notification_entry (NotificationEntry entry) {
336 app_notifications.remove (entry);
337+ entry.active = false;
338+ entry.destroy ();
339+
340+ Session.get_instance ().remove_notification (entry.notification);
341 if (app_notifications.length () == 0) {
342- destroy_entry ();
343+ clear ();
344 }
345 }
346 }
347
348=== modified file 'src/Widgets/NotificationEntry.vala'
349--- src/Widgets/NotificationEntry.vala 2016-05-27 15:10:53 +0000
350+++ src/Widgets/NotificationEntry.vala 2016-07-21 12:53:02 +0000
351@@ -54,14 +54,7 @@
352 });
353
354 hexpand = true;
355- add_widgets ();
356-
357- if (notification.data_session) {
358- notification.time_changed (notification.timestamp.difference (new DateTime.now_local ()));
359- }
360- }
361-
362- private void add_widgets () {
363+
364 var grid = new Gtk.Grid ();
365 grid.margin_start = 40;
366 grid.margin_end = 6;
367@@ -92,6 +85,10 @@
368
369 add (grid);
370 show_all ();
371+
372+ if (notification.data_session) {
373+ notification.time_changed (notification.timestamp.difference (new DateTime.now_local ()));
374+ }
375 }
376
377 /**
378
379=== modified file 'src/Widgets/NotificationsList.vala'
380--- src/Widgets/NotificationsList.vala 2016-07-17 18:46:38 +0000
381+++ src/Widgets/NotificationsList.vala 2016-07-21 12:53:02 +0000
382@@ -18,13 +18,11 @@
383 public class NotificationsList : Gtk.ListBox {
384 public signal void switch_stack (bool show_list);
385 public signal void close_popover ();
386+
387 private List<AppEntry> app_entries;
388- private List<NotificationEntry> items;
389 private HashTable<string, int> table;
390 private int counter = 0;
391
392- private static Wnck.Screen screen;
393-
394 public NotificationsList () {
395 margin_top = 2;
396
397@@ -32,57 +30,41 @@
398 selection_mode = Gtk.SelectionMode.NONE;
399 row_activated.connect (on_row_activated);
400
401- items = new List<NotificationEntry> ();
402 app_entries = new List<AppEntry> ();
403 table = new HashTable<string, int> (str_hash, str_equal);
404
405- screen = Wnck.Screen.get_default ();
406-
407 vexpand = true;
408 show_all ();
409+
410+ monitor_active_window ();
411 }
412
413- public void add_item (NotificationEntry entry) {
414- var app_entry = add_app_entry (entry);
415+ public void add_entry (NotificationEntry entry) {
416+ var app_entry = add_entry_internal (entry);
417+ if (app_entry == null) {
418+ return;
419+ }
420
421- items.prepend (entry);
422 switch_stack (true);
423
424- app_entry.add_notification_entry (entry);
425- resort_from_app_entry (app_entry);
426-
427- entry.clear.connect (() => {
428- destroy_notification_entry (entry);
429- });
430-
431- app_entry.destroy_entry.connect (() => {
432- destroy_app_entry (app_entry);
433- });
434-
435- counter = counter + 2;
436+ app_entry.clear.connect (clear_app_entry);
437+
438+ counter += 2;
439
440 Session.get_instance ().add_notification (entry.notification);
441- entry.show_all ();
442
443 update_separators ();
444 show_all ();
445 }
446
447
448- public uint get_items_length () {
449- return items.length ();
450+ public uint get_entries_length () {
451+ return app_entries.length ();
452 }
453
454 public void clear_all () {
455- items.@foreach ((item) => {
456- items.remove (item);
457- remove (item);
458- item.active = false;
459- });
460-
461- app_entries.@foreach ((entry) => {
462- app_entries.remove (entry);
463- remove (entry);
464+ app_entries.foreach ((app_entry) => {
465+ app_entry.clear ();
466 });
467
468 counter = 0;
469@@ -93,6 +75,17 @@
470 show_all ();
471 }
472
473+ private void resort_app_entry (AppEntry app_entry) {
474+ if (get_row_at_index (0) != app_entry) {
475+ remove (app_entry);
476+ prepend (app_entry);
477+ app_entry.app_notifications.foreach ((notification_entry) => {
478+ remove (notification_entry);
479+ insert (notification_entry, 1);
480+ });
481+ }
482+ }
483+
484 private void update_separators () {
485 if (get_children ().length () > 0) {
486 foreach (var child in get_children ()) {
487@@ -112,27 +105,24 @@
488 show_all ();
489 }
490
491- private AppEntry add_app_entry (NotificationEntry entry) {
492- AppEntry app_entry;
493+ private AppEntry? add_entry_internal (NotificationEntry entry) {
494+ AppEntry? app_entry = null;
495 bool add = !(entry.notification.desktop_id in construct_desktop_id_list ());
496 if (add) {
497- var window = get_window_from_entry (entry);
498- app_entry = new AppEntry (entry, window);
499-
500- screen.active_window_changed.connect (() => {
501- if (screen.get_active_window () == app_entry.app_window) {
502- app_entry.clear_btn_entry.clicked ();
503- }
504- });
505+ app_entry = new AppEntry (entry);
506
507 app_entries.append (app_entry);
508 prepend (app_entry);
509 insert (entry, 1);
510- table.insert (app_entry.desktop_id, 0);
511+ table.insert (app_entry.app_info.get_id (), 0);
512 } else {
513 app_entry = get_app_entry_from_desktop_id (entry.notification.desktop_id);
514+
515 if (app_entry != null) {
516- int insert_pos = table.@get (app_entry.desktop_id);
517+ resort_app_entry (app_entry);
518+ app_entry.add_notification_entry (entry);
519+
520+ int insert_pos = table.get (app_entry.app_info.get_id ());
521 insert (entry, insert_pos + 1);
522 }
523 }
524@@ -140,118 +130,94 @@
525 return app_entry;
526 }
527
528- private Wnck.Window? get_window_from_entry (NotificationEntry entry) {
529- Wnck.Window? window = null;
530- screen.get_windows ().@foreach ((_window) => {
531- if (_window.get_pid () == entry.notification.pid) {
532- window = _window;
533- return;
534- }
535+ private void monitor_active_window () {
536+ var screen = Wnck.Screen.get_default ();
537+ screen.active_window_changed.connect (() => {
538+ app_entries.foreach ((app_entry) => {
539+ if (screen.get_active_window () == app_entry.get_app_window ()) {
540+ app_entry.clear ();
541+ }
542+ });
543 });
544-
545- return window;
546- }
547-
548- private async void destroy_notification_entry (NotificationEntry entry) {
549- entry.destroy ();
550- items.remove (entry);
551- entry.active = false;
552-
553- Session.get_instance ().remove_notification (entry.notification);
554- if (items.length () == 0) {
555- clear_all ();
556- }
557- }
558-
559- private void destroy_app_entry (AppEntry app_entry) {
560+ }
561+
562+ private void clear_app_entry (AppEntry app_entry) {
563 app_entries.remove (app_entry);
564
565- app_entry.get_notifications ().@foreach ((notification_entry) => {
566- notification_entry.destroy ();
567- items.remove (notification_entry);
568- });
569-
570- Idle.add (() => {
571- if (app_entry != null) {
572- app_entry.destroy ();
573- }
574-
575- return false;
576- });
577-
578- if (items.length () == 0) {
579+ app_entry.app_notifications.foreach ((notification_entry) => {
580+ app_entry.remove_notification_entry.begin (notification_entry);
581+ });
582+
583+ app_entry.destroy ();
584+ update_separators ();
585+
586+ if (get_entries_length () == 0) {
587 clear_all ();
588 }
589-
590- update_separators ();
591- }
592-
593- private void resort_from_app_entry (AppEntry app_entry) {
594- if (get_row_at_index (0) != app_entry) {
595- remove (app_entry);
596- prepend (app_entry);
597- int counter = 1;
598- app_entry.get_notifications ().@foreach ((notification_entry) => {
599- remove (notification_entry);
600- add_item (notification_entry);
601- counter++;
602- });
603- }
604 }
605
606 private AppEntry? get_app_entry_from_desktop_id (string desktop_id) {
607- AppEntry? entry = null;
608- app_entries.@foreach ((_entry) => {
609- if (_entry.desktop_id == desktop_id) {
610- entry = _entry;
611- return;
612+ AppEntry? app_entry = null;
613+ app_entries.foreach ((_app_entry) => {
614+ if (_app_entry.app_info.get_id () == desktop_id && app_entry == null) {
615+ app_entry = _app_entry;
616 }
617 });
618
619- return entry;
620+ return app_entry;
621 }
622
623 private string[] construct_desktop_id_list () {
624 string[] desktop_id_list = {};
625- app_entries.@foreach ((entry) => {
626- desktop_id_list += entry.desktop_id;
627+ app_entries.foreach ((app_entry) => {
628+ desktop_id_list += app_entry.app_info.get_id ();
629 });
630
631 return desktop_id_list;
632 }
633
634 private void on_row_activated (Gtk.ListBoxRow row) {
635- if (row.get_path ().get_object_type () == typeof (AppEntry)) {
636- if (((AppEntry) row).app_window == null) {
637- var window = get_window_from_entry (((AppEntry) row).get_notifications ().nth_data (0));
638- if (window != null) {
639- ((AppEntry) row).app_window = window;
640- }
641- }
642-
643- if (((AppEntry) row).app_window != null) {
644- ((AppEntry) row).app_window.unminimize (Gtk.get_current_event_time ());
645- ((AppEntry) row).clear_btn_entry.clicked ();
646- close_popover ();
647- } else if (((AppEntry) row).app_info != null) {
648- try {
649- ((AppEntry) row).app_info.launch (null, null);
650- } catch (Error e) {
651- error ("%s\n", e.message);
652- }
653-
654- ((AppEntry) row).clear_btn_entry.clicked ();
655- close_popover ();
656- }
657+ bool close = true;
658+
659+ if (row is AppEntry) {
660+ var app_entry = (AppEntry)row;
661+ close = focus_notification_app (app_entry.get_app_window (),
662+ app_entry.app_info);
663+
664+ app_entry.clear ();
665+ } else if (row is NotificationEntry) {
666+ var notification_entry = (NotificationEntry)row;
667+
668+ if (!notification_entry.notification.run_default_action ()) {
669+ close = focus_notification_app (notification_entry.notification.get_app_window (),
670+ notification_entry.notification.app_info);
671+ }
672+
673+ notification_entry.clear ();
674 } else {
675- if (((NotificationEntry) row).notification.run_default_action ()) {
676- ((NotificationEntry) row).active = false;
677- close_popover ();
678- }
679+ close = false;
680+ }
681
682- ((NotificationEntry) row).clear ();
683+ if (close) {
684+ close_popover ();
685 }
686
687 update_separators ();
688 }
689+
690+ private bool focus_notification_app (Wnck.Window? app_window, AppInfo? app_info) {
691+ if (app_window != null) {
692+ app_window.unminimize (Gtk.get_current_event_time ());
693+ return true;
694+ } else if (app_info != null) {
695+ try {
696+ app_info.launch (null, null);
697+ return true;
698+ } catch (Error e) {
699+ warning ("%s\n", e.message);
700+ }
701+ }
702+
703+ return false;
704+ }
705 }

Subscribers

People subscribed via source and target branches

to all changes: