Commit 63e9d221 authored by Erik Reider's avatar Erik Reider

Simplified finding notification widgets when replacing and removing

parent 42d06db3
...@@ -114,7 +114,7 @@ namespace SwayNotificationCenter.Widgets { ...@@ -114,7 +114,7 @@ namespace SwayNotificationCenter.Widgets {
private void prepare_group_removal (NotificationGroup group) { private void prepare_group_removal (NotificationGroup group) {
if (group.name_id.length > 0) { if (group.name_id.length > 0) {
noti_groups_name.unset (group.name_id, null); noti_groups_name.unset (group.name_id);
} }
if (expanded_group == group) { if (expanded_group == group) {
expanded_group = null; expanded_group = null;
...@@ -175,8 +175,8 @@ namespace SwayNotificationCenter.Widgets { ...@@ -175,8 +175,8 @@ namespace SwayNotificationCenter.Widgets {
} }
private void remove_group_internal (NotificationGroup group) { private void remove_group_internal (NotificationGroup group) {
foreach (uint32 id in group.notification_ids) { foreach (uint32 id in group.notification_ids.keys) {
if (noti_groups_id.unset (id, null)) { if (noti_groups_id.unset (id)) {
n_notifications--; n_notifications--;
} }
} }
...@@ -197,6 +197,7 @@ namespace SwayNotificationCenter.Widgets { ...@@ -197,6 +197,7 @@ namespace SwayNotificationCenter.Widgets {
return; return;
} }
if (group.state == NotificationGroupState.MANY) { if (group.state == NotificationGroupState.MANY) {
noti_groups_id.unset (id);
n_notifications--; n_notifications--;
group.remove_notification.begin (id, (obj, result) => { group.remove_notification.begin (id, (obj, result) => {
// Continue the removal logic even if the async result failed // Continue the removal logic even if the async result failed
...@@ -215,8 +216,10 @@ namespace SwayNotificationCenter.Widgets { ...@@ -215,8 +216,10 @@ namespace SwayNotificationCenter.Widgets {
public void replace_notification (uint32 id, NotifyParams new_params) { public void replace_notification (uint32 id, NotifyParams new_params) {
unowned NotificationGroup ?group = noti_groups_id.get (id); unowned NotificationGroup ?group = noti_groups_id.get (id);
if (group != null) { if (group != null) {
noti_groups_id.unset (id, null); noti_groups_id.unset (id);
if (group.replace_notification (id, new_params)) { if (group.replace_notification (id, new_params)) {
// Replace the ID, could be changed depending on the
// replacement method used
noti_groups_id.set (new_params.applied_id, group); noti_groups_id.set (new_params.applied_id, group);
// Position the notification in the beginning of the list // Position the notification in the beginning of the list
list_box.invalidate_sort (); list_box.invalidate_sort ();
...@@ -268,10 +271,10 @@ namespace SwayNotificationCenter.Widgets { ...@@ -268,10 +271,10 @@ namespace SwayNotificationCenter.Widgets {
group.add_css_class ("not-expanded"); group.add_css_class ("not-expanded");
} }
noti_groups_id.set (param.applied_id, group);
group.add_notification (noti); group.add_notification (noti);
noti_groups_id.set (param.applied_id, group);
n_notifications++; n_notifications++;
list_box.invalidate_sort (); list_box.invalidate_sort ();
scroll_to_start (); scroll_to_start ();
......
...@@ -55,7 +55,7 @@ namespace SwayNotificationCenter { ...@@ -55,7 +55,7 @@ namespace SwayNotificationCenter {
} }
internal void request_dismiss_notification_group (string group_name_id, internal void request_dismiss_notification_group (string group_name_id,
Gee.HashSet<uint32> ids, Gee.Set<uint32> ids,
ClosedReasons reason) { ClosedReasons reason) {
debug ("Dismissing notification group with ID:%s, reason:%s", debug ("Dismissing notification group with ID:%s, reason:%s",
group_name_id, reason.to_string ()); group_name_id, reason.to_string ());
......
...@@ -15,9 +15,10 @@ namespace SwayNotificationCenter { ...@@ -15,9 +15,10 @@ namespace SwayNotificationCenter {
private Adw.TimedAnimation animation; private Adw.TimedAnimation animation;
public uint n_children { get; private set; } public uint n_children { get; private set; }
public List<Gtk.Widget> widgets = new List<Gtk.Widget> ();
public List<unowned Gtk.Widget> visible_widgets = new List<unowned Gtk.Widget> (); public List<unowned Gtk.Widget> visible_widgets = new List<unowned Gtk.Widget> ();
List<Gtk.Widget> widgets = new List<Gtk.Widget> ();
public delegate void on_expand_change (bool state); public delegate void on_expand_change (bool state);
private unowned Gtk.Viewport viewport; private unowned Gtk.Viewport viewport;
...@@ -94,12 +95,42 @@ namespace SwayNotificationCenter { ...@@ -94,12 +95,42 @@ namespace SwayNotificationCenter {
bool widget_visible = widget.get_visible (); bool widget_visible = widget.get_visible ();
widget.unparent (); widget.unparent ();
widgets.remove (widget); widgets.remove (widget);
if (get_visible () && widget_visible) { if (widget_visible) {
queue_resize (); queue_resize ();
} }
n_children--; n_children--;
} }
public void remove_all () {
while (!widgets.is_empty ()) {
unowned List<Gtk.Widget> link = widgets.nth (0);
if (link.data != null && link.data is Gtk.Widget) {
remove (link.data);
} else {
widgets.delete_link (link);
}
}
warn_if_fail (widgets.is_empty ());
n_children = 0;
}
public delegate bool WidgetFilterDelegate (Gtk.Widget widget);
public unowned Gtk.Widget ?get_first_widget (WidgetFilterDelegate ? filter = null) {
for (unowned List<Gtk.Widget> ?link = widgets.first ();
link != null;
link = link.next) {
if (link.data != null && (filter == null || filter (link.data))) {
return link.data;
}
}
return null;
}
public inline bool is_empty () {
return widgets.is_empty ();
}
private delegate void compute_height_iter_cb (Gtk.Widget child, private delegate void compute_height_iter_cb (Gtk.Widget child,
WidgetAlloc widget_alloc, WidgetAlloc widget_alloc,
int index, int index,
......
...@@ -8,10 +8,10 @@ namespace SwayNotificationCenter { ...@@ -8,10 +8,10 @@ namespace SwayNotificationCenter {
public class NotificationGroup : Gtk.ListBoxRow { public class NotificationGroup : Gtk.ListBoxRow {
public string name_id; public string name_id;
public Gee.HashSet<uint32> notification_ids { public Gee.HashMap<uint32, unowned Notification> notification_ids {
get; get;
private set; private set;
default = new Gee.HashSet<uint32> (); default = new Gee.HashMap<uint32, unowned Notification> ();
} }
public NotificationGroupState state { public NotificationGroupState state {
...@@ -283,12 +283,11 @@ namespace SwayNotificationCenter { ...@@ -283,12 +283,11 @@ namespace SwayNotificationCenter {
return; return;
} }
unowned Notification first = (Notification) group.widgets.first ().data; unowned Notification ?latest = get_latest_notification ();
unowned NotifyParams param = first.param;
// Get the app icon // Get the app icon
Icon ?icon = null; Icon ?icon = null;
if (param.desktop_app_info != null if (latest != null && latest.param.desktop_app_info != null
&& (icon = param.desktop_app_info.get_icon ()) != null) { && (icon = latest.param.desktop_app_info.get_icon ()) != null) {
app_icon.set_from_gicon (icon); app_icon.set_from_gicon (icon);
} else { } else {
app_icon.set_from_icon_name ("application-x-executable-symbolic"); app_icon.set_from_icon_name ("application-x-executable-symbolic");
...@@ -296,14 +295,12 @@ namespace SwayNotificationCenter { ...@@ -296,14 +295,12 @@ namespace SwayNotificationCenter {
} }
private unowned Notification ?find_notification (uint32 id) { private unowned Notification ?find_notification (uint32 id) {
foreach (unowned Gtk.Widget widget in group.widgets) { unowned Notification ?notification = notification_ids.get (id);
unowned Notification notification = (Notification) widget; if (notification == null || notification.param.applied_id != id) {
if (notification != null && notification.param.applied_id == id) {
return notification;
}
}
return null; return null;
} }
return notification;
}
public void set_expanded (bool state) { public void set_expanded (bool state) {
if (dismissed) { if (dismissed) {
...@@ -324,8 +321,8 @@ namespace SwayNotificationCenter { ...@@ -324,8 +321,8 @@ namespace SwayNotificationCenter {
if (noti.param.urgency == UrgencyLevels.CRITICAL) { if (noti.param.urgency == UrgencyLevels.CRITICAL) {
urgent_notifications.add (noti.param.applied_id); urgent_notifications.add (noti.param.applied_id);
} }
notification_ids.add (noti.param.applied_id);
group.add (noti); group.add (noti);
notification_ids.set (noti.param.applied_id, noti);
update_state (); update_state ();
set_icon (); set_icon ();
...@@ -336,8 +333,8 @@ namespace SwayNotificationCenter { ...@@ -336,8 +333,8 @@ namespace SwayNotificationCenter {
if (notification == null) { if (notification == null) {
return false; return false;
} }
notification_ids.remove (id); notification_ids.unset (id);
notification_ids.add (new_params.applied_id); notification_ids.set (new_params.applied_id, notification);
notification.replace_notification (new_params); notification.replace_notification (new_params);
return true; return true;
} }
...@@ -352,7 +349,7 @@ namespace SwayNotificationCenter { ...@@ -352,7 +349,7 @@ namespace SwayNotificationCenter {
} }
urgent_notifications.remove (notification.param.applied_id); urgent_notifications.remove (notification.param.applied_id);
notification_ids.remove (notification.param.applied_id); notification_ids.unset (notification.param.applied_id);
notification.remove_noti_timeout (); notification.remove_noti_timeout ();
// Only animate individual notifications when there are more than one, // Only animate individual notifications when there are more than one,
...@@ -393,7 +390,7 @@ namespace SwayNotificationCenter { ...@@ -393,7 +390,7 @@ namespace SwayNotificationCenter {
} }
} }
if (group.widgets.is_empty ()) { if (group.is_empty ()) {
debug ("Skiping removal of all notifications as the group is already empty"); debug ("Skiping removal of all notifications as the group is already empty");
return false; return false;
} }
...@@ -403,16 +400,7 @@ namespace SwayNotificationCenter { ...@@ -403,16 +400,7 @@ namespace SwayNotificationCenter {
return false; return false;
} }
while (!group.widgets.is_empty ()) { group.remove_all ();
unowned List<Gtk.Widget> link = group.widgets.nth (0);
unowned Notification ?notification = (Notification) link.data;
if (notification != null) {
notification.remove_noti_timeout ();
}
group.widgets.delete_link (link);
}
warn_if_fail (group.widgets.is_empty ());
return true; return true;
} }
...@@ -421,19 +409,23 @@ namespace SwayNotificationCenter { ...@@ -421,19 +409,23 @@ namespace SwayNotificationCenter {
return; return;
} }
dismissed = true; dismissed = true;
noti_daemon.request_dismiss_notification_group (name_id, notification_ids, noti_daemon.request_dismiss_notification_group (name_id, notification_ids.keys,
ClosedReasons.DISMISSED); ClosedReasons.DISMISSED);
} }
public unowned Notification ?get_latest_notification () { public unowned Notification ?get_latest_notification () {
return (Notification ?) group.widgets.first ().data; return (Notification ?) group.get_first_widget ((widget) => {
unowned Notification ?notification = (Notification ?) widget;
return notification != null && !notification.dismissed;
});
} }
public int64 get_time () { public int64 get_time () {
if (group.widgets.is_empty ()) { unowned Notification ?notification = get_latest_notification ();
if (notification_ids.is_empty || notification == null) {
return -1; return -1;
} }
return ((Notification) group.widgets.first ().data).param.time; return notification.param.time;
} }
public bool get_is_urgent () { public bool get_is_urgent () {
...@@ -446,10 +438,9 @@ namespace SwayNotificationCenter { ...@@ -446,10 +438,9 @@ namespace SwayNotificationCenter {
public void update () { public void update () {
set_icon (); set_icon ();
foreach (unowned Gtk.Widget widget in group.widgets) { foreach (unowned Notification ?notification in notification_ids.values) {
var noti = (Notification) widget; if (notification != null) {
if (noti != null) { notification.set_time ();
noti.set_time ();
} }
} }
} }
......
...@@ -7,6 +7,8 @@ namespace SwayNotificationCenter { ...@@ -7,6 +7,8 @@ namespace SwayNotificationCenter {
unowned AnimatedList list; unowned AnimatedList list;
Gee.HashSet<uint32> inline_reply_notifications = new Gee.HashSet<uint32> (); Gee.HashSet<uint32> inline_reply_notifications = new Gee.HashSet<uint32> ();
Gee.HashMap<uint32, unowned Notification> notification_ids
= new Gee.HashMap<uint32, unowned Notification> ();
private static string ?monitor_name = null; private static string ?monitor_name = null;
...@@ -214,6 +216,18 @@ namespace SwayNotificationCenter { ...@@ -214,6 +216,18 @@ namespace SwayNotificationCenter {
surface.set_input_region (region); surface.set_input_region (region);
} }
private inline unowned Notification ?find_notification (uint32 id) {
unowned Notification ?notification = notification_ids.get (id);
if (notification == null || notification.param.applied_id != id) {
return null;
}
unowned AnimatedListItem ?item = (AnimatedListItem ?) notification.get_parent ();
if (item == null || item.destroying) {
return null;
}
return notification;
}
/** /**
* Hides all notifications. Only invokes the NotificationClosed signal when transient. * Hides all notifications. Only invokes the NotificationClosed signal when transient.
* The optional callback is used to remove select notifications where each * The optional callback is used to remove select notifications where each
...@@ -221,6 +235,7 @@ namespace SwayNotificationCenter { ...@@ -221,6 +235,7 @@ namespace SwayNotificationCenter {
*/ */
public void remove_all_notifications (bool transition, public void remove_all_notifications (bool transition,
notification_filter_func ?filter_func) { notification_filter_func ?filter_func) {
notification_ids.clear ();
inline_reply_notifications.clear (); inline_reply_notifications.clear ();
foreach (unowned AnimatedListItem item in list.children) { foreach (unowned AnimatedListItem item in list.children) {
if (item.destroying) { if (item.destroying) {
...@@ -240,6 +255,7 @@ namespace SwayNotificationCenter { ...@@ -240,6 +255,7 @@ namespace SwayNotificationCenter {
return_if_fail (notification != null); return_if_fail (notification != null);
NotifyParams param = notification.param; NotifyParams param = notification.param;
notification_ids.unset (param.applied_id);
// Disable transitions when not mapped // Disable transitions when not mapped
transition &= get_mapped (); transition &= get_mapped ();
...@@ -285,36 +301,31 @@ namespace SwayNotificationCenter { ...@@ -285,36 +301,31 @@ namespace SwayNotificationCenter {
set_visible (true); set_visible (true);
list.append.begin (noti); list.append.begin (noti);
notification_ids.set (param.applied_id, noti);
} }
/** Removes the notification widget with ID. Doesn't dismiss */ /** Removes the notification widget with ID. Doesn't dismiss */
public void remove_notification (uint32 id) { public void remove_notification (uint32 id) {
foreach (unowned AnimatedListItem item in list.children) { unowned Notification ?notification = find_notification (id);
if (item.destroying) { if (notification != null) {
continue;
}
unowned Notification notification = (Notification) item.child;
if (notification != null && notification.param.applied_id == id) {
remove_notification_internal (notification, true); remove_notification_internal (notification, true);
break;
}
} }
} }
public void replace_notification (uint32 id, NotifyParams new_params) { public void replace_notification (uint32 id, NotifyParams new_params) {
foreach (unowned AnimatedListItem item in list.children) { unowned Notification ?notification = find_notification (id);
if (item.destroying) { if (notification != null) {
continue; // Replace the ID, could be changed depending on the
} // replacement method used
var noti = (Notification) item.child; notification_ids.unset (id);
if (noti != null && noti.param.applied_id == id) { notification_ids.set (new_params.applied_id, notification);
noti.replace_notification (new_params);
notification.replace_notification (new_params);
// Position the notification in the beginning/end of the list // Position the notification in the beginning/end of the list
// and scroll to the new item // and scroll to the new item
list.move_to_beginning (noti, true); list.move_to_beginning (notification, true);
return; return;
} }
}
// Display a new notification if the old one isn't visible // Display a new notification if the old one isn't visible
debug ("Could not find floating notification to replace: %u", id); debug ("Could not find floating notification to replace: %u", id);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment