Merge lp:~donadigo/wingpanel-indicator-notifications/close-notification-support-new into lp:~wingpanel-devs/wingpanel-indicator-notifications/wingpanel-indicator-notifications

Proposed by Adam Bieńkowski
Status: Merged
Approved by: Corentin Noël
Approved revision: 128
Merged at revision: 126
Proposed branch: lp:~donadigo/wingpanel-indicator-notifications/close-notification-support-new
Merge into: lp:~wingpanel-devs/wingpanel-indicator-notifications/wingpanel-indicator-notifications
Diff against target: 251 lines (+95/-46)
5 files modified
src/Indicator.vala (+15/-1)
src/Services/Notification.vala (+5/-0)
src/Services/NotificationsMonitor.vala (+69/-45)
src/Widgets/NotificationEntry.vala (+2/-0)
src/Widgets/NotificationsList.vala (+4/-0)
To merge this branch: bzr merge lp:~donadigo/wingpanel-indicator-notifications/close-notification-support-new
Reviewer Review Type Date Requested Status
Corentin Noël Approve
Review via email: mp+312735@code.launchpad.net

Commit message

Add support for withdrawing the notifications from the indicator

Description of the change

Fixes bug #1631470: "Allow apps to withdraw a notification".

This branch adds support for withdrawing the notifications from the indicator. Note, that this will not work at the moment with GLib based applications, this is issue within the GLib itself, more info and patch here: https://bugzilla.gnome.org/show_bug.cgi?id=775765

Changes include the removal of hacky sending the notification to the server by the indicator to determine the notification ID. This is now done by waiting for server to return the ID of the notification and then it gets displayed in the UI. This doesn't change the time the notification arrives in the indicator, we only wait for the response, not the actual show / hide of the notification, that's up to the server.

Please test extensively.

To post a comment you must log in.
Revision history for this message
Corentin Noël (tintou) wrote :

Everything seems nice here

review: Approve
Revision history for this message
RabbitBot (rabbitbot-a) wrote :

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

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-08-03 06:28:36 +0000
3+++ src/Indicator.vala 2016-12-12 20:06:10 +0000
4@@ -102,7 +102,10 @@
5
6 nlist.close_popover.connect (() => close ());
7 nlist.switch_stack.connect (on_switch_stack);
8- NotificationMonitor.get_instance ().received.connect (on_notification_received);
9+
10+ var monitor = NotificationMonitor.get_instance ();
11+ monitor.notification_received.connect (on_notification_received);
12+ monitor.notification_closed.connect (on_notification_closed);
13
14 NotifySettings.get_instance ().changed[NotifySettings.DO_NOT_DISTURB_KEY].connect (() => {
15 not_disturb_switch.get_switch ().active = NotifySettings.get_instance ().do_not_disturb;
16@@ -171,6 +174,17 @@
17 dynamic_icon.set_main_icon_name (get_display_icon_name ());
18 }
19
20+ private void on_notification_closed (uint32 id) {
21+ foreach (var app_entry in nlist.get_entries ()) {
22+ foreach (var item in app_entry.app_notifications) {
23+ if (item.notification.id == id) {
24+ item.notification.close ();
25+ return;
26+ }
27+ }
28+ }
29+ }
30+
31 private void restore_previous_session () {
32 var previous_session = Session.get_instance ().get_session_notifications ();
33 previous_session.foreach ((notification) => {
34
35=== modified file 'src/Services/Notification.vala'
36--- src/Services/Notification.vala 2016-08-03 06:28:36 +0000
37+++ src/Services/Notification.vala 2016-12-12 20:06:10 +0000
38@@ -37,6 +37,7 @@
39 public string desktop_id;
40 public AppInfo? app_info = null;
41
42+ public signal void closed ();
43 public signal bool time_changed (TimeSpan span);
44
45 private enum Column {
46@@ -129,6 +130,10 @@
47 return app_info != null && hints.lookup_value (X_CANONICAL_PRIVATE_KEY, null) == null;
48 }
49
50+ public void close () {
51+ closed ();
52+ }
53+
54 public bool run_default_action () {
55 if (DEFAULT_ACTION in actions && NotificationMonitor.get_instance ().notifications_iface != null) {
56 NotificationMonitor.get_instance ().notifications_iface.action_invoked (DEFAULT_ACTION, id);
57
58=== modified file 'src/Services/NotificationsMonitor.vala'
59--- src/Services/NotificationsMonitor.vala 2016-06-20 12:40:25 +0000
60+++ src/Services/NotificationsMonitor.vala 2016-12-12 20:06:10 +0000
61@@ -23,17 +23,18 @@
62 public class NotificationMonitor : Object {
63 private const string NOTIFY_IFACE = "org.freedesktop.Notifications";
64 private const string NOTIFY_PATH = "/org/freedesktop/Notifications";
65- private const string MATCH_STRING = "eavesdrop='true',type='method_call',interface='org.freedesktop.Notifications',member='Notify'";
66+ private const string METHOD_CALL_MATCH_STRING = "eavesdrop='true',type='method_call',interface='org.freedesktop.Notifications'";
67+ private const string METHOD_RETURN_MATCH_STRING = "eavesdrop='true',type='method_return'";
68+ private const string ERROR_MATCH_STRING = "eavesdrop='true',type='error'";
69 private const uint32 REASON_DISMISSED = 2;
70
71 private static NotificationMonitor? instance = null;
72
73 private DBusConnection connection;
74- public INotifications? notifications_iface = null;
75- public IDBus? dbus_iface = null;
76- private uint32 id_counter = 0;
77+ private DBusMessage? awaiting_reply = null;
78
79- public signal void received (DBusMessage message, uint32 id);
80+ public signal void notification_received (DBusMessage message, uint32 id);
81+ public signal void notification_closed (uint32 id);
82
83 public static NotificationMonitor get_instance () {
84 if (instance == null) {
85@@ -43,75 +44,98 @@
86 return instance;
87 }
88
89+ public INotifications? notifications_iface = null;
90+
91 private NotificationMonitor () {
92 try {
93 connection = Bus.get_sync (BusType.SESSION);
94- add_filter ();
95+ add_rule (ERROR_MATCH_STRING);
96+ add_rule (METHOD_CALL_MATCH_STRING);
97+ add_rule (METHOD_RETURN_MATCH_STRING);
98+ connection.add_filter (message_filter);
99 } catch (Error e) {
100 error ("%s\n", e.message);
101 }
102+
103+ try {
104+ notifications_iface = Bus.get_proxy_sync (BusType.SESSION, NOTIFY_IFACE, NOTIFY_PATH);
105+ } catch (Error e) {
106+ error ("%s\n", e.message);
107+ }
108 }
109
110- private void add_filter () {
111+ private void add_rule (string rule) {
112 var message = new DBusMessage.method_call ("org.freedesktop.DBus",
113 "/org/freedesktop/DBus",
114 "org.freedesktop.DBus",
115 "AddMatch");
116
117- var body = new Variant.parsed ("(%s,)", MATCH_STRING);
118+ var body = new Variant.parsed ("(%s,)", rule);
119 message.set_body (body);
120
121 try {
122- notifications_iface = Bus.get_proxy_sync (BusType.SESSION, NOTIFY_IFACE, NOTIFY_PATH);
123- } catch (Error e) {
124- error ("%s\n", e.message);
125- }
126-
127- id_counter = get_current_notification_id ();
128- try {
129 connection.send_message (message, DBusSendMessageFlags.NONE, null);
130 } catch (Error e) {
131 error ("%s\n", e.message);
132 }
133-
134- connection.add_filter (message_filter);
135 }
136
137 private DBusMessage message_filter (DBusConnection con, owned DBusMessage message, bool incoming) {
138- if (incoming) {
139- if ((message.get_message_type () == DBusMessageType.METHOD_CALL) &&
140- (message.get_interface () == NOTIFY_IFACE) &&
141- (message.get_member () == "Notify")) {
142- uint32 replaces_id = message.get_body ().get_child_value (1).get_uint32 ();
143- uint32 current_id = replaces_id;
144-
145- if (replaces_id == 0) {
146- id_counter++;
147- current_id = id_counter;
148- }
149-
150+ if (incoming && message.get_interface () == NOTIFY_IFACE && message.get_message_type () == DBusMessageType.METHOD_CALL) {
151+ if (message.get_member () == "Notify") {
152+ try {
153+ awaiting_reply = message.copy ();
154+ } catch (Error e) {
155+ warning (e.message);
156+ }
157+ } else if (message.get_member () == "CloseNotification") {
158+ var body = message.get_body ();
159+ if (body.n_children () != 1) {
160+ return message;
161+ }
162+
163+ var child = body.get_child_value (0);
164+ if (!child.is_of_type (VariantType.UINT32)) {
165+ return message;
166+ }
167+
168+ uint32 id = child.get_uint32 ();
169 Idle.add (() => {
170- this.received (message, current_id);
171- message = null;
172+ notification_closed (id);
173 return false;
174 });
175-
176- return null;
177+ }
178+
179+ return null;
180+ } else if (awaiting_reply != null && awaiting_reply.get_serial () == message.get_reply_serial ()) {
181+ if (message.get_message_type () == DBusMessageType.METHOD_RETURN) {
182+ var body = message.get_body ();
183+ if (body.n_children () != 1) {
184+ return message;
185+ }
186+
187+ var child = body.get_child_value (0);
188+ if (!child.is_of_type (VariantType.UINT32)) {
189+ return message;
190+ }
191+
192+ uint32 id = child.get_uint32 ();
193+ try {
194+ var copy = awaiting_reply.copy ();
195+ Idle.add (() => {
196+ notification_received (copy, id);
197+ return false;
198+ });
199+ } catch (Error e) {
200+ warning (e.message);
201+ }
202+
203+ awaiting_reply = null;
204+ } else if (message.get_message_type () == DBusMessageType.ERROR) {
205+ awaiting_reply = null;
206 }
207 }
208
209 return message;
210 }
211-
212- /* Check what's the current notification id */
213- private uint32 get_current_notification_id () {
214- var hints = new HashTable<string, Variant> (str_hash, str_equal);
215- hints.insert ("suppress-sound", new Variant.boolean (true));
216- string[] actions = {};
217- try {
218- return notifications_iface.notify ("", 0, "", "", "", actions, hints, 1);
219- } catch (Error e) {
220- error ("%s\n", e.message);
221- }
222- }
223 }
224
225=== modified file 'src/Widgets/NotificationEntry.vala'
226--- src/Widgets/NotificationEntry.vala 2016-07-20 20:36:57 +0000
227+++ src/Widgets/NotificationEntry.vala 2016-12-12 20:06:10 +0000
228@@ -53,6 +53,8 @@
229 return active;
230 });
231
232+ notification.closed.connect (() => clear ());
233+
234 hexpand = true;
235
236 var grid = new Gtk.Grid ();
237
238=== modified file 'src/Widgets/NotificationsList.vala'
239--- src/Widgets/NotificationsList.vala 2016-11-20 13:30:03 +0000
240+++ src/Widgets/NotificationsList.vala 2016-12-12 20:06:10 +0000
241@@ -58,6 +58,10 @@
242 }
243
244
245+ public unowned List<AppEntry> get_entries () {
246+ return app_entries;
247+ }
248+
249 public uint get_entries_length () {
250 return app_entries.length ();
251 }

Subscribers

People subscribed via source and target branches

to all changes: