Merge lp:~donadigo/wingpanel-indicator-notifications/notification-open-app into lp:~elementary-pantheon/wingpanel-indicator-notifications/loki-rc

Proposed by Adam Bieńkowski
Status: Merged
Approved by: Felipe Escoto
Approved revision: 97
Merged at revision: 97
Proposed branch: lp:~donadigo/wingpanel-indicator-notifications/notification-open-app
Merge into: lp:~elementary-pantheon/wingpanel-indicator-notifications/loki-rc
Diff against target: 308 lines (+97/-61)
6 files modified
src/CMakeLists.txt (+1/-1)
src/Services/Notification.vala (+7/-4)
src/Services/NotificationMonitor.vala (+29/-9)
src/Widgets/AppEntry.vala (+9/-0)
src/Widgets/NotificationEntry.vala (+12/-0)
src/Widgets/NotificationsList.vala (+39/-47)
To merge this branch: bzr merge lp:~donadigo/wingpanel-indicator-notifications/notification-open-app
Reviewer Review Type Date Requested Status
WingPanel Devs Pending
Review via email: mp+297946@code.launchpad.net

Commit message

* Fix bug #1594227: "Clicking a notification should open/focus the app".
* General code improvements.

Description of the change

Fixes bug #1594227: "Clicking a notification should open/focus the app".

This branch enables functionality to open / focus the app by clicking on the notification, if the notification has a default action, it will be launched instead of the app.

It also contains a large code improvements, simplifies the method names and makes it more easier to read.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 2016-05-27 15:10:53 +0000
+++ src/CMakeLists.txt 2016-06-20 18:57:25 +0000
@@ -20,7 +20,7 @@
20 Widgets/NotificationEntry.vala20 Widgets/NotificationEntry.vala
21 Widgets/AppEntry.vala21 Widgets/AppEntry.vala
22 Widgets/SeparatorEntry.vala22 Widgets/SeparatorEntry.vala
23 Services/NotificationsMonitor.vala23 Services/NotificationMonitor.vala
24 Services/Notification.vala24 Services/Notification.vala
25 Services/NotifySettings.vala25 Services/NotifySettings.vala
26 Services/Session.vala26 Services/Session.vala
2727
=== modified file 'src/Services/Notification.vala'
--- src/Services/Notification.vala 2016-05-27 15:10:53 +0000
+++ src/Services/Notification.vala 2016-06-20 18:57:25 +0000
@@ -145,7 +145,7 @@
145 }145 }
146146
147 try {147 try {
148 IDBus? dbus_iface = Bus.get_proxy_sync (BusType.SESSION, "org.freedesktop.DBus", "/");148 IDBus? dbus_iface = NotificationMonitor.get_dbus_iface ();
149 if (dbus_iface != null && dbus_iface.name_has_owner (sender)) {149 if (dbus_iface != null && dbus_iface.name_has_owner (sender)) {
150 pid = dbus_iface.get_connection_unix_process_id (sender);150 pid = dbus_iface.get_connection_unix_process_id (sender);
151 }151 }
@@ -157,9 +157,12 @@
157 }157 }
158158
159 public bool run_default_action () {159 public bool run_default_action () {
160 if (DEFAULT_ACTION in actions && NotificationMonitor.get_instance ().notifications_iface != null) {160 if (DEFAULT_ACTION in actions) {
161 NotificationMonitor.get_instance ().notifications_iface.action_invoked (DEFAULT_ACTION, id);161 INotifications? notifications_iface = NotificationMonitor.get_notifications_iface ();
162 return true;162 if (notifications_iface != null) {
163 notifications_iface.action_invoked (DEFAULT_ACTION, id);
164 return true;
165 }
163 }166 }
164167
165 return false;168 return false;
166169
=== renamed file 'src/Services/NotificationsMonitor.vala' => 'src/Services/NotificationMonitor.vala'
--- src/Services/NotificationsMonitor.vala 2016-06-20 12:40:25 +0000
+++ src/Services/NotificationMonitor.vala 2016-06-20 18:57:25 +0000
@@ -23,14 +23,16 @@
23public class NotificationMonitor : Object {23public class NotificationMonitor : Object {
24 private const string NOTIFY_IFACE = "org.freedesktop.Notifications";24 private const string NOTIFY_IFACE = "org.freedesktop.Notifications";
25 private const string NOTIFY_PATH = "/org/freedesktop/Notifications";25 private const string NOTIFY_PATH = "/org/freedesktop/Notifications";
26 private const string DBUS_IFACE = "org.freedesktop.DBus";
27 private const string DBUS_PATH = "/";
26 private const string MATCH_STRING = "eavesdrop='true',type='method_call',interface='org.freedesktop.Notifications',member='Notify'";28 private const string MATCH_STRING = "eavesdrop='true',type='method_call',interface='org.freedesktop.Notifications',member='Notify'";
27 private const uint32 REASON_DISMISSED = 2;29 private const uint32 REASON_DISMISSED = 2;
2830
29 private static NotificationMonitor? instance = null;31 private static NotificationMonitor? instance = null;
32 private static INotifications? notifications_iface = null;
33 private static IDBus? dbus_iface = null;
3034
31 private DBusConnection connection;35 private DBusConnection connection;
32 public INotifications? notifications_iface = null;
33 public IDBus? dbus_iface = null;
34 private uint32 id_counter = 0;36 private uint32 id_counter = 0;
3537
36 public signal void received (DBusMessage message, uint32 id);38 public signal void received (DBusMessage message, uint32 id);
@@ -43,6 +45,30 @@
43 return instance;45 return instance;
44 }46 }
4547
48 public static INotifications? get_notifications_iface () {
49 if (notifications_iface == null) {
50 try {
51 notifications_iface = Bus.get_proxy_sync (BusType.SESSION, NOTIFY_IFACE, NOTIFY_PATH);
52 } catch (Error e) {
53 warning ("%s\n", e.message);
54 }
55 }
56
57 return notifications_iface;
58 }
59
60 public static IDBus? get_dbus_iface () {
61 if (dbus_iface == null) {
62 try {
63 dbus_iface = Bus.get_proxy_sync (BusType.SESSION, DBUS_IFACE, DBUS_PATH);
64 } catch (Error e) {
65 warning ("%s\n", e.message);
66 }
67 }
68
69 return dbus_iface;
70 }
71
46 private NotificationMonitor () {72 private NotificationMonitor () {
47 try {73 try {
48 connection = Bus.get_sync (BusType.SESSION);74 connection = Bus.get_sync (BusType.SESSION);
@@ -61,12 +87,6 @@
61 var body = new Variant.parsed ("(%s,)", MATCH_STRING);87 var body = new Variant.parsed ("(%s,)", MATCH_STRING);
62 message.set_body (body);88 message.set_body (body);
63 89
64 try {
65 notifications_iface = Bus.get_proxy_sync (BusType.SESSION, NOTIFY_IFACE, NOTIFY_PATH);
66 } catch (Error e) {
67 error ("%s\n", e.message);
68 }
69
70 id_counter = get_current_notification_id ();90 id_counter = get_current_notification_id ();
71 try {91 try {
72 connection.send_message (message, DBusSendMessageFlags.NONE, null);92 connection.send_message (message, DBusSendMessageFlags.NONE, null);
@@ -109,7 +129,7 @@
109 hints.insert ("suppress-sound", new Variant.boolean (true));129 hints.insert ("suppress-sound", new Variant.boolean (true));
110 string[] actions = {};130 string[] actions = {};
111 try {131 try {
112 return notifications_iface.notify ("", 0, "", "", "", actions, hints, 1);132 return get_notifications_iface ().notify ("", 0, "", "", "", actions, hints, 1);
113 } catch (Error e) {133 } catch (Error e) {
114 error ("%s\n", e.message);134 error ("%s\n", e.message);
115 }135 }
116136
=== modified file 'src/Widgets/AppEntry.vala'
--- src/Widgets/AppEntry.vala 2016-05-27 15:10:53 +0000
+++ src/Widgets/AppEntry.vala 2016-06-20 18:57:25 +0000
@@ -89,6 +89,15 @@
89 });89 });
90 }90 }
9191
92 public void update_app_window () {
93 if (app_notifications.length () == 0) {
94 return;
95 }
96
97 var notification_entry = app_notifications.nth_data (0);
98 app_window = notification_entry.get_app_window ();
99 }
100
92 public unowned List<NotificationEntry> get_notifications () {101 public unowned List<NotificationEntry> get_notifications () {
93 return app_notifications;102 return app_notifications;
94 }103 }
95104
=== modified file 'src/Widgets/NotificationEntry.vala'
--- src/Widgets/NotificationEntry.vala 2016-05-27 15:10:53 +0000
+++ src/Widgets/NotificationEntry.vala 2016-06-20 18:57:25 +0000
@@ -61,6 +61,18 @@
61 }61 }
62 }62 }
6363
64 public Wnck.Window? get_app_window () {
65 Wnck.Window? window = null;
66 Wnck.Screen.get_default ().get_windows ().@foreach ((_window) => {
67 if (_window.get_pid () == notification.pid) {
68 window = _window;
69 return;
70 }
71 });
72
73 return window;
74 }
75
64 private void add_widgets () {76 private void add_widgets () {
65 var grid = new Gtk.Grid ();77 var grid = new Gtk.Grid ();
66 grid.margin_start = 40;78 grid.margin_start = 40;
6779
=== modified file 'src/Widgets/NotificationsList.vala'
--- src/Widgets/NotificationsList.vala 2016-06-20 12:37:34 +0000
+++ src/Widgets/NotificationsList.vala 2016-06-20 18:57:25 +0000
@@ -49,7 +49,7 @@
49 switch_stack (true);49 switch_stack (true);
5050
51 app_entry.add_notification_entry (entry);51 app_entry.add_notification_entry (entry);
52 resort_from_app_entry (app_entry);52 resort_app_entry (app_entry);
5353
54 entry.clear.connect (() => {54 entry.clear.connect (() => {
55 destroy_notification_entry (entry);55 destroy_notification_entry (entry);
@@ -59,7 +59,7 @@
59 destroy_app_entry (app_entry);59 destroy_app_entry (app_entry);
60 });60 });
6161
62 counter = counter + 2;62 counter += 2;
6363
64 Session.get_instance ().add_notification (entry.notification);64 Session.get_instance ().add_notification (entry.notification);
65 entry.show_all ();65 entry.show_all ();
@@ -116,7 +116,7 @@
116 AppEntry app_entry;116 AppEntry app_entry;
117 bool add = !(entry.notification.app_name in construct_app_names ());117 bool add = !(entry.notification.app_name in construct_app_names ());
118 if (add) {118 if (add) {
119 var window = get_window_from_entry (entry);119 var window = entry.get_app_window ();
120 app_entry = new AppEntry (entry, window);120 app_entry = new AppEntry (entry, window);
121121
122 screen.active_window_changed.connect (() => {122 screen.active_window_changed.connect (() => {
@@ -130,7 +130,7 @@
130 insert (entry, 1);130 insert (entry, 1);
131 table.insert (app_entry.app_name, 0);131 table.insert (app_entry.app_name, 0);
132 } else {132 } else {
133 app_entry = get_app_entry_from_app_name (entry.notification.app_name);133 app_entry = get_from_app_name (entry.notification.app_name);
134 if (app_entry != null) {134 if (app_entry != null) {
135 int insert_pos = table.@get (app_entry.app_name);135 int insert_pos = table.@get (app_entry.app_name);
136 insert (entry, insert_pos + 1); 136 insert (entry, insert_pos + 1);
@@ -140,18 +140,6 @@
140 return app_entry;140 return app_entry;
141 }141 }
142142
143 private Wnck.Window? get_window_from_entry (NotificationEntry entry) {
144 Wnck.Window? window = null;
145 screen.get_windows ().@foreach ((_window) => {
146 if (_window.get_pid () == entry.notification.pid) {
147 window = _window;
148 return;
149 }
150 });
151
152 return window;
153 }
154
155 private async void destroy_notification_entry (NotificationEntry entry) {143 private async void destroy_notification_entry (NotificationEntry entry) {
156 entry.destroy ();144 entry.destroy ();
157 items.remove (entry);145 items.remove (entry);
@@ -186,7 +174,7 @@
186 update_separators ();174 update_separators ();
187 }175 }
188176
189 private void resort_from_app_entry (AppEntry app_entry) {177 private void resort_app_entry (AppEntry app_entry) {
190 if (get_row_at_index (0) != app_entry) {178 if (get_row_at_index (0) != app_entry) {
191 remove (app_entry);179 remove (app_entry);
192 prepend (app_entry);180 prepend (app_entry);
@@ -199,7 +187,7 @@
199 }187 }
200 }188 }
201189
202 private AppEntry? get_app_entry_from_app_name (string app_name) {190 private AppEntry? get_from_app_name (string app_name) {
203 AppEntry? entry = null;191 AppEntry? entry = null;
204 app_entries.@foreach ((_entry) => {192 app_entries.@foreach ((_entry) => {
205 if (_entry.app_name == app_name) {193 if (_entry.app_name == app_name) {
@@ -221,37 +209,41 @@
221 }209 }
222210
223 private void on_row_activated (Gtk.ListBoxRow row) {211 private void on_row_activated (Gtk.ListBoxRow row) {
224 if (row.get_path ().get_object_type () == typeof (AppEntry)) {212 if (row is AppEntry) {
225 if (((AppEntry) row).app_window == null) {213 var app_entry = (AppEntry)row;
226 var window = get_window_from_entry (((AppEntry) row).get_notifications ().nth_data (0));214 if (app_entry.app_window == null) {
227 if (window != null) {215 app_entry.update_app_window ();
228 ((AppEntry) row).app_window = window;216 }
229 }217
230 }218 focus_notification_app (app_entry.app_window,
231219 app_entry.appinfo);
232 if (((AppEntry) row).app_window != null) {220
233 ((AppEntry) row).app_window.unminimize (Gtk.get_current_event_time ());221 app_entry.clear_btn_entry.clicked ();
234 ((AppEntry) row).clear_btn_entry.clicked ();222 close_popover ();
235 close_popover ();223 } else if (row is NotificationEntry) {
236 } else if (((AppEntry) row).appinfo != null) {224 var notification_entry = (NotificationEntry)row;
237 try {225 if (!notification_entry.notification.run_default_action ()) {
238 ((AppEntry) row).appinfo.launch (null, null);226 focus_notification_app (notification_entry.get_app_window (),
239 } catch (Error e) {227 notification_entry.notification.appinfo);
240 error ("%s\n", e.message);228 }
241 }229
242230 notification_entry.clear ();
243 ((AppEntry) row).clear_btn_entry.clicked ();231 notification_entry.active = false;
244 close_popover ();232 close_popover ();
245 }
246 } else {
247 if (((NotificationEntry) row).notification.run_default_action ()) {
248 ((NotificationEntry) row).active = false;
249 close_popover ();
250 }
251
252 ((NotificationEntry) row).clear ();
253 }233 }
254234
255 update_separators ();235 update_separators ();
256 }236 }
237
238 private void focus_notification_app (Wnck.Window? app_window, AppInfo? appinfo) {
239 if (app_window != null) {
240 app_window.unminimize (Gtk.get_current_event_time ());
241 } else if (appinfo != null) {
242 try {
243 appinfo.launch (null, null);
244 } catch (Error e) {
245 warning ("%s\n", e.message);
246 }
247 }
248 }
257}249}

Subscribers

People subscribed via source and target branches