From 426ffbfa044b9c1a8592afdc62dec7e7106205fe Mon Sep 17 00:00:00 2001 From: Rudra Pratap Singh Date: Tue, 12 Aug 2025 02:38:08 +0530 Subject: [PATCH 1/3] upcoming-events: Use GListStore to store event lists We replace the use of `GPtrArray` with a `GListStore` as we can then use it in combination with a `GtkFilterListModel`. Signed-off-by: Rudra Pratap Singh Part-of: --- plugins/upcoming-events/upcoming-events.c | 32 ++++++++++++----------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/plugins/upcoming-events/upcoming-events.c b/plugins/upcoming-events/upcoming-events.c index 05a681858..a517a23d0 100644 --- a/plugins/upcoming-events/upcoming-events.c +++ b/plugins/upcoming-events/upcoming-events.c @@ -38,7 +38,7 @@ struct _PhoshUpcomingEvents { GtkStack *stack; GtkBox *events_box; - GPtrArray *event_lists; + GListModel *event_lists; GListStore *events; GHashTable *event_ids; GDateTime *since; @@ -59,7 +59,7 @@ phosh_upcoming_events_finalize (GObject *object) { PhoshUpcomingEvents *self = PHOSH_UPCOMING_EVENTS (object); - g_ptr_array_free (self->event_lists, TRUE); + g_clear_object (&self->event_lists); g_clear_handle_id (&self->today_changed_timeout_id, g_source_remove); g_cancellable_cancel (self->cancel); g_clear_object (&self->cancel); @@ -162,8 +162,8 @@ update_event_lists_visibility (PhoshUpcomingEvents *self) { int visible_lists = 0; - for (uint i = 0; i < self->event_lists->len; i++) { - PhoshEventList *event_list = PHOSH_EVENT_LIST (self->event_lists->pdata[i]); + for (uint i = 0; i < g_list_model_get_n_items (self->event_lists); i++) { + g_autoptr (PhoshEventList) event_list = g_list_model_get_item (self->event_lists, i); uint events = phosh_event_list_get_n_events (event_list); gboolean visibility = !self->skip_empty || events != 0; @@ -228,8 +228,11 @@ on_events_added_or_updated (PhoshUpcomingEvents *self, GVariant *events) return; /* Changed events might be tz change so refilter days */ - for (int i = 0; i < self->event_lists->len; i++) - phosh_event_list_set_today (g_ptr_array_index (self->event_lists, i), self->since); + for (int i = 0; i < g_list_model_get_n_items (self->event_lists); i++) { + g_autoptr (PhoshEventList) el = g_list_model_get_item (self->event_lists, i); + + phosh_event_list_set_today (el, self->since); + } } #undef EVENT_FORMAT @@ -273,8 +276,11 @@ update_calendar (PhoshUpcomingEvents *self, gboolean force_reload) load_events (self, force_reload); - for (int i = 0; i < self->event_lists->len; i++) - phosh_event_list_set_today (g_ptr_array_index (self->event_lists, i), self->since); + for (int i = 0; i < g_list_model_get_n_items (self->event_lists); i++) { + g_autoptr (PhoshEventList) el = g_list_model_get_item (self->event_lists, i); + + phosh_event_list_set_today (el, self->since); + } /* Rearm timer */ setup_date_change_timeout (self); @@ -375,11 +381,7 @@ on_num_days_changed (PhoshUpcomingEvents *self) g_debug ("Number of days changed to %u; reconfiguring event lists", self->num_days); - for (int i = 0; i < self->event_lists->len; i++) { - GtkWidget *child = g_ptr_array_index (self->event_lists, i); - gtk_container_remove (GTK_CONTAINER (self->events_box), child); - } - g_ptr_array_remove_range (self->event_lists, 0, self->event_lists->len); + g_list_store_remove_all (G_LIST_STORE (self->event_lists)); for (int i = 0; i < self->num_days; i++) { GtkWidget *event_list = g_object_new (PHOSH_TYPE_EVENT_LIST, @@ -389,7 +391,7 @@ on_num_days_changed (PhoshUpcomingEvents *self) "visible", TRUE, NULL); gtk_container_add (GTK_CONTAINER (self->events_box), event_list); - g_ptr_array_add (self->event_lists, event_list); + g_list_store_append (G_LIST_STORE (self->event_lists), event_list); } load_events (self, FALSE); @@ -449,7 +451,7 @@ phosh_upcoming_events_init (PhoshUpcomingEvents *self) self, G_CONNECT_SWAPPED); - self->event_lists = g_ptr_array_new (); + self->event_lists = G_LIST_MODEL (g_list_store_new (PHOSH_TYPE_EVENT_LIST)); self->events = g_list_store_new (PHOSH_TYPE_CALENDAR_EVENT); self->event_ids = g_hash_table_new_full (g_str_hash, -- GitLab From 965444c94af6dcc127ab832529d32074d6650cc1 Mon Sep 17 00:00:00 2001 From: Rudra Pratap Singh Date: Tue, 12 Aug 2025 03:05:54 +0530 Subject: [PATCH 2/3] upcoming-events: Use GtkFilterListModel to filter empty days Additionally make `events_box` a `GtkListBox` instead so as to bind it to the filtered model. Signed-off-by: Rudra Pratap Singh Part-of: --- plugins/upcoming-events/upcoming-events.c | 76 +++++++++++++++++----- plugins/upcoming-events/upcoming-events.ui | 4 +- 2 files changed, 60 insertions(+), 20 deletions(-) diff --git a/plugins/upcoming-events/upcoming-events.c b/plugins/upcoming-events/upcoming-events.c index a517a23d0..959e838f1 100644 --- a/plugins/upcoming-events/upcoming-events.c +++ b/plugins/upcoming-events/upcoming-events.c @@ -11,6 +11,7 @@ #include "event-list.h" #include "calendar-event.h" #include "upcoming-events.h" +#include "gtkfilterlistmodel.h" #include "phosh-plugin-upcoming-events-phosh-calendar-dbus.h" @@ -37,8 +38,9 @@ struct _PhoshUpcomingEvents { GCancellable *cancel; GtkStack *stack; - GtkBox *events_box; + GtkListBox *events_box; GListModel *event_lists; + GtkFilterListModel *event_lists_filtered; GListStore *events; GHashTable *event_ids; GDateTime *since; @@ -59,7 +61,7 @@ phosh_upcoming_events_finalize (GObject *object) { PhoshUpcomingEvents *self = PHOSH_UPCOMING_EVENTS (object); - g_clear_object (&self->event_lists); + g_clear_object (&self->event_lists_filtered); g_clear_handle_id (&self->today_changed_timeout_id, g_source_remove); g_cancellable_cancel (self->cancel); g_clear_object (&self->cancel); @@ -158,23 +160,16 @@ calendar_event_begin_compare (gconstpointer a, static void -update_event_lists_visibility (PhoshUpcomingEvents *self) +refilter_event_lists (PhoshUpcomingEvents *self) { - int visible_lists = 0; + const char *child_name = "no-events"; - for (uint i = 0; i < g_list_model_get_n_items (self->event_lists); i++) { - g_autoptr (PhoshEventList) event_list = g_list_model_get_item (self->event_lists, i); - uint events = phosh_event_list_get_n_events (event_list); - gboolean visibility = !self->skip_empty || events != 0; + gtk_filter_list_model_refilter (self->event_lists_filtered); - gtk_widget_set_visible (GTK_WIDGET (event_list), visibility); - visible_lists += visibility; - } + if (!self->skip_empty || g_list_model_get_n_items (G_LIST_MODEL (self->event_lists_filtered))) + child_name = "events-window"; - if (!self->skip_empty || visible_lists) - gtk_stack_set_visible_child_name (self->stack, "events-window"); - else - gtk_stack_set_visible_child_name (self->stack, "no-events"); + gtk_stack_set_visible_child_name (self->stack, child_name); } @@ -222,7 +217,7 @@ on_events_added_or_updated (PhoshUpcomingEvents *self, GVariant *events) NULL); } - update_event_lists_visibility (self); + refilter_event_lists (self); if (changed == FALSE) return; @@ -261,6 +256,8 @@ on_events_removed (PhoshUpcomingEvents *self, GStrv ids) g_hash_table_remove (self->event_ids, id); } + refilter_event_lists (self); + g_debug ("Removed %d events of %d", removed, g_strv_length (ids)); } @@ -363,7 +360,40 @@ on_skip_empty_changed (PhoshUpcomingEvents *self) gtk_button_set_image (GTK_BUTTON (self->skip_empty_btn), gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_BUTTON)); - update_event_lists_visibility (self); + refilter_event_lists (self); +} + + +static gboolean +filter_event_lists_func (gpointer item, gpointer user_data) +{ + PhoshUpcomingEvents *self = PHOSH_UPCOMING_EVENTS (user_data); + PhoshEventList *event_list = PHOSH_EVENT_LIST (item); + + if (!self->skip_empty) + return TRUE; + + return phosh_event_list_get_n_events (event_list) > 0; +} + + +static GtkWidget * +create_event_list_func (gpointer item, gpointer user_data) +{ + PhoshUpcomingEvents *self = PHOSH_UPCOMING_EVENTS (user_data); + PhoshEventList *el; + int day_offset; + + g_object_get (G_OBJECT (item), "day-offset", &day_offset, NULL); + + el = g_object_new (PHOSH_TYPE_EVENT_LIST, + "day-offset", day_offset, + "today", self->since, + "model", self->events, + "visible", TRUE, + NULL); + + return GTK_WIDGET (el); } @@ -390,10 +420,16 @@ on_num_days_changed (PhoshUpcomingEvents *self) "model", self->events, "visible", TRUE, NULL); - gtk_container_add (GTK_CONTAINER (self->events_box), event_list); + g_list_store_append (G_LIST_STORE (self->event_lists), event_list); } + gtk_list_box_bind_model (self->events_box, + G_LIST_MODEL (self->event_lists_filtered), + create_event_list_func, + self, + NULL); + load_events (self, FALSE); } @@ -452,6 +488,10 @@ phosh_upcoming_events_init (PhoshUpcomingEvents *self) G_CONNECT_SWAPPED); self->event_lists = G_LIST_MODEL (g_list_store_new (PHOSH_TYPE_EVENT_LIST)); + self->event_lists_filtered = gtk_filter_list_model_new (self->event_lists, + filter_event_lists_func, + self, + NULL); self->events = g_list_store_new (PHOSH_TYPE_CALENDAR_EVENT); self->event_ids = g_hash_table_new_full (g_str_hash, diff --git a/plugins/upcoming-events/upcoming-events.ui b/plugins/upcoming-events/upcoming-events.ui index 78aa3e2cc..33c64ad37 100644 --- a/plugins/upcoming-events/upcoming-events.ui +++ b/plugins/upcoming-events/upcoming-events.ui @@ -40,9 +40,9 @@ never 1 - + 1 - vertical + none -- GitLab From 3019f4666c16d6faad84dbd376c4d88e8ec2d132 Mon Sep 17 00:00:00 2001 From: Rudra Pratap Singh Date: Fri, 24 Oct 2025 17:16:02 +0530 Subject: [PATCH 3/3] upcoming-events: Add CSS class for PhoshEventList listbox Allows us to keep styling separate for event-list listbox and events listbox. Signed-off-by: Rudra Pratap Singh Part-of: --- plugins/upcoming-events/event-list.ui | 3 +++ plugins/upcoming-events/stylesheet/common.css | 14 +++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/plugins/upcoming-events/event-list.ui b/plugins/upcoming-events/event-list.ui index b65d04377..744ec1a1a 100644 --- a/plugins/upcoming-events/event-list.ui +++ b/plugins/upcoming-events/event-list.ui @@ -38,6 +38,9 @@ 1 none + events diff --git a/plugins/upcoming-events/stylesheet/common.css b/plugins/upcoming-events/stylesheet/common.css index 123fe6b4b..5e0553e05 100644 --- a/plugins/upcoming-events/stylesheet/common.css +++ b/plugins/upcoming-events/stylesheet/common.css @@ -5,19 +5,27 @@ phosh-upcoming-events { } phosh-upcoming-events list { + background: none; +} + +phosh-upcoming-events list row { + background: none; +} + +phosh-upcoming-events .event-list-listbox { background-color: transparent; } -phosh-upcoming-events row { +phosh-upcoming-events .event-list-listbox row { border-radius: 6px; background: shade(@phosh_notification_bg_color, 1.3); } -phosh-upcoming-events row:hover { +phosh-upcoming-events .event-list-listbox row:hover { background: shade(@phosh_notification_bg_color, 1.5); } -phosh-upcoming-events row:active { +phosh-upcoming-events .event-list-listbox row:active { background: shade(@phosh_notification_bg_color, 1.8); } -- GitLab