diff --git a/data/notifications.appdata.xml.in b/data/notifications.appdata.xml.in index 741a8ca8..c6f5eff0 100644 --- a/data/notifications.appdata.xml.in +++ b/data/notifications.appdata.xml.in @@ -7,6 +7,18 @@ See missed notifications in the panel preferences-system-notifications + + +

Fixes:

+
    +
  • Reduce delay in initially showing wingpanel when there is a large number of notifications
  • +
+

Minor updates:

+
    +
  • Updated translations
  • +
+
+

Fixes:

diff --git a/src/Indicator.vala b/src/Indicator.vala index e4fa3bea..073785eb 100644 --- a/src/Indicator.vala +++ b/src/Indicator.vala @@ -27,6 +27,7 @@ public class Notifications.Indicator : Wingpanel.Indicator { private Gtk.ModelButton clear_all_btn; private Gtk.Spinner? dynamic_icon = null; private NotificationsList nlist; + private List previous_session = null; public Indicator () { Object ( @@ -45,29 +46,30 @@ public class Notifications.Indicator : Wingpanel.Indicator { public override Gtk.Widget get_display_widget () { if (dynamic_icon == null) { - dynamic_icon = new Gtk.Spinner (); - dynamic_icon.active = true; - - nlist = new NotificationsList (); - - var previous_session = Session.get_instance ().get_session_notifications (); - previous_session.foreach ((notification) => { - nlist.add_entry (notification, false); - }); - Gtk.IconTheme.get_default ().add_resource_path ("/io/elementary/wingpanel/notifications"); var provider = new Gtk.CssProvider (); provider.load_from_resource ("io/elementary/wingpanel/notifications/indicator.css"); + dynamic_icon = new Gtk.Spinner () { + active = true, + tooltip_markup = _("Updating notifications…") + }; + unowned var dynamic_icon_style_context = dynamic_icon.get_style_context (); - dynamic_icon_style_context.add_class ("notification-icon"); dynamic_icon_style_context.add_provider (provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + dynamic_icon_style_context.add_class ("notification-icon"); + + nlist = new NotificationsList (); var monitor = NotificationMonitor.get_instance (); monitor.notification_received.connect (on_notification_received); monitor.notification_closed.connect (on_notification_closed); + notify_settings.changed["do-not-disturb"].connect (() => { + set_display_icon_name (); + }); + dynamic_icon.button_press_event.connect ((e) => { if (e.button == Gdk.BUTTON_MIDDLE) { notify_settings.set_boolean ("do-not-disturb", !notify_settings.get_boolean ("do-not-disturb")); @@ -77,19 +79,27 @@ public class Notifications.Indicator : Wingpanel.Indicator { return Gdk.EVENT_PROPAGATE; }); - notify_settings.changed["do-not-disturb"].connect (() => { - set_display_icon_name (); - }); - - nlist.add.connect (set_display_icon_name); - nlist.remove.connect (set_display_icon_name); + previous_session = Session.get_instance ().get_session_notifications (); + Timeout.add (2000, () => { // Do not block animated drawing of wingpanel + load_session_notifications.begin (() => { // load asynchromously so spinner continues to rotate + set_display_icon_name (); + nlist.add.connect (set_display_icon_name); + nlist.remove.connect (set_display_icon_name); + }); - set_display_icon_name (); + return Source.REMOVE; + }); } return dynamic_icon; } + private async void load_session_notifications () { + foreach (var notification in previous_session) { + yield nlist.add_entry (notification, false); // This is slow as NotificationEntry is complex + } + } + public override Gtk.Widget? get_widget () { if (main_box == null) { var not_disturb_switch = new Granite.SwitchModelButton (_("Do Not Disturb")); @@ -170,7 +180,7 @@ public class Notifications.Indicator : Wingpanel.Indicator { } if (app_settings == null || app_settings.get_boolean (REMEMBER_KEY)) { - nlist.add_entry (notification); + nlist.add_entry.begin (notification, true); } set_display_icon_name (); @@ -216,9 +226,8 @@ public class Notifications.Indicator : Wingpanel.Indicator { } private void update_tooltip () { - uint number_of_notifications = Session.get_instance ().get_session_notifications ().length (); + uint number_of_notifications = Session.get_instance ().count_notifications (); int number_of_apps = nlist.app_entries.size; - string description; string accel_label; diff --git a/src/Services/Session.vala b/src/Services/Session.vala index 166fc6d3..57bd5e5d 100644 --- a/src/Services/Session.vala +++ b/src/Services/Session.vala @@ -78,7 +78,7 @@ public class Notifications.Session : GLib.Object { key.get_string (group, SENDER_KEY), key.get_boolean (group, HAS_TEMP_FILE_KEY) ); - list.append (notification); + list.prepend (notification); } } catch (KeyFileError e) { warning (e.message); @@ -86,9 +86,19 @@ public class Notifications.Session : GLib.Object { warning (e.message); } + list.reverse (); return list; } + public uint count_notifications () { + uint count = 0; + foreach (unowned string group in key.get_groups ()) { + count++; + } + + return count; + } + public void add_notification (Notification notification, bool write_file = true) { string id = notification.id.to_string (); key.set_int64 (id, UNIX_TIME_KEY, notification.timestamp.to_unix ()); @@ -152,11 +162,21 @@ public class Notifications.Session : GLib.Object { } } + private uint write_timeout_id = 0; private void write_contents () { - try { - FileUtils.set_contents (session_file.get_path (), key.to_data ()); - } catch (FileError e) { - warning (e.message); + if (write_timeout_id > 0) { + Source.remove (write_timeout_id); } + + write_timeout_id = Timeout.add (1000, () => { + write_timeout_id = 0; + try { + FileUtils.set_contents (session_file.get_path (), key.to_data ()); + } catch (FileError e) { + warning (e.message); + } + + return Source.REMOVE; + }); } } diff --git a/src/Widgets/NotificationsList.vala b/src/Widgets/NotificationsList.vala index beef513d..58a824ef 100644 --- a/src/Widgets/NotificationsList.vala +++ b/src/Widgets/NotificationsList.vala @@ -46,7 +46,7 @@ public class Notifications.NotificationsList : Gtk.ListBox { row_activated.connect (on_row_activated); } - public void add_entry (Notification notification, bool write_file = true) { + public async void add_entry (Notification notification, bool add_to_session = true, bool write_file = true) { var entry = new NotificationEntry (notification); if (app_entries[notification.desktop_id] != null) { @@ -71,7 +71,12 @@ public class Notifications.NotificationsList : Gtk.ListBox { show_all (); - Session.get_instance ().add_notification (notification, write_file); + Idle.add (add_entry.callback); + yield; + + if (add_to_session) { // If notification was obtained from session do not write it back + Session.get_instance ().add_notification (notification); + } } public void clear_all () {