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