Am 30.05.2017 um 22:03 schrieb Jonathan Wiltshire:
> Control: tag -1 moreinfo
> 
> Hi,
> 
> On Tue, May 30, 2017 at 04:53:41PM +0200, Michael Biebl wrote:
>> Please unblock package gnome-calendar
>>
>> It's a targetted two-line fix for a crasher bug:
>> https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=858924
>>
>> The patch is from upstream, the package has already been uploaded and
>> was successfully built everywhere.
> 
> Unfortunately it's stuck behind a new upstream from March. Is this worth
> trying to revert or do through t-p-u, or better abandoned?

Hm,...
Given the tiny diff between 3.22.3 and 3.22.4 and the fact that 3.22.4
has been in unstable for 2 months without new bug reports, maybe
unblocking 3.22.4-1 would be the best option.

Other then that, I'd be willing to prepare a tpu upload.

Regards,
Michael


-- 
Why is it that all of the instruments seeking intelligent life in the
universe are pointed away from Earth?
diff --git a/NEWS b/NEWS
index 801c6ec..8e490ac 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,6 @@
+Major changes in 3.22.4:
+* Fix outstanding performance issue in Year view
+
 Major changes in 3.22.3:
 * Only decrease search counter when something is removed (Georges Basile Stavracas Neto)
 * Focus entry after calendar selection in quick popover (Mohammed Sadiq)
diff --git a/configure.ac b/configure.ac
index 9741b40..7f304f8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
 dnl -*- mode: m4 -*-
 AC_PREREQ([2.69])
-AC_INIT([gnome-calendar],[3.22.3],[http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-calendar],[gnome-calendar],[https://wiki.gnome.org/Apps/Calendar])
+AC_INIT([gnome-calendar],[3.22.4],[http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-calendar],[gnome-calendar],[https://wiki.gnome.org/Apps/Calendar])
 
 AX_IS_RELEASE([minor-version])
 
diff --git a/data/appdata/org.gnome.Calendar.appdata.xml.in b/data/appdata/org.gnome.Calendar.appdata.xml.in
index e69de4b..3f9851f 100644
--- a/data/appdata/org.gnome.Calendar.appdata.xml.in
+++ b/data/appdata/org.gnome.Calendar.appdata.xml.in
@@ -42,6 +42,16 @@
   <project_group>GNOME</project_group>
 
   <releases>
+    <release date="2017-03-28" version="3.22.4">
+      <description>
+        <p>
+          This is the fifth stable release for GNOME Calendar 3.22, and fixes
+          an outstanding performance issue in Year view.
+        </p>
+        <p>Thanks to all the contributors that worked on GNOME Calendar!</p>
+      </description>
+    </release>
+
     <release date="2017-02-28" version="3.22.3">
       <description>
         <p>
diff --git a/src/gcal-window.c b/src/gcal-window.c
index f4a4945..85c799f 100644
--- a/src/gcal-window.c
+++ b/src/gcal-window.c
@@ -702,7 +702,7 @@ set_new_event_mode (GcalWindow *window,
   /* for now we relaunch the new-event widget */
   if (!enabled && gtk_widget_is_visible (window->quick_add_popover))
     {
-      gtk_widget_set_visible (window->quick_add_popover, FALSE);
+      gtk_popover_popdown (GTK_POPOVER (window->quick_add_popover));
     }
 }
 
@@ -750,7 +750,7 @@ show_new_event_widget (GcalView   *view,
   rect.height = 1;
 
   gtk_popover_set_pointing_to (GTK_POPOVER (window->quick_add_popover), &rect);
-  gtk_widget_show (window->quick_add_popover);
+  gtk_popover_popup (GTK_POPOVER (window->quick_add_popover));
 }
 
 static void
diff --git a/src/gcal-year-view.c b/src/gcal-year-view.c
index e1c5d4c..79612be 100644
--- a/src/gcal-year-view.c
+++ b/src/gcal-year-view.c
@@ -108,6 +108,13 @@ struct _GcalYearView
 
   /* date property */
   icaltimetype *date;
+
+  /*
+   * Array with the events at every month. Events
+   * that span multiple months are added multiple
+   * times to the array.
+   */
+  GPtrArray    *events[12];
 };
 
 enum {
@@ -650,6 +657,45 @@ calculate_day_month_for_coord (GcalYearView *year_view,
   *out_day = day;
   return TRUE;
 }
+static guint
+count_events_at_day (GcalYearView *self,
+                     icaltimetype *today)
+{
+  g_autoptr (GDateTime) today_start, today_end;
+  GPtrArray *events;
+  guint i, n_events;
+
+  events = self->events[today->month - 1];
+  n_events = 0;
+  today_start = icaltime_to_datetime (today);
+  today_end = g_date_time_add_days (today_start, 1);
+
+  for (i = 0; i < events->len; i++)
+    {
+      g_autoptr (GDateTime) event_start, event_end;
+      GcalEvent *event;
+
+      event = g_ptr_array_index (events, i);
+
+      event_start = g_date_time_ref (gcal_event_get_date_start (event));
+
+      if (gcal_event_get_all_day (event))
+          event_end = g_date_time_add_days (gcal_event_get_date_end (event), -1);
+      else
+          event_end = g_date_time_ref (gcal_event_get_date_end (event));
+
+
+      if (datetime_compare_date (event_start, today_end) >= 0 ||
+          datetime_compare_date (event_end, today_start) < 0)
+        {
+          continue;
+        }
+
+      n_events++;
+    }
+
+  return n_events;
+}
 
 static void
 draw_month_grid (GcalYearView *year_view,
@@ -671,8 +717,7 @@ draw_month_grid (GcalYearView *year_view,
   gint days_delay, days, shown_rows, sunday_idx;
   gchar *str, *nr_day, *nr_week;
   gboolean selected_day;
-  GList *events;
-  icaltimetype start_date, end_date;
+  icaltimetype today;
 
   cairo_save (cr);
   context = gtk_widget_get_style_context (widget);
@@ -738,18 +783,13 @@ draw_month_grid (GcalYearView *year_view,
   shown_rows = ceil (days / 7.0);
   sunday_idx = year_view->k * 7 + sw * ((7 - year_view->first_weekday) % 7) + year_view->show_week_numbers * (1 - year_view->k);
 
-  start_date.day    = 1;
-  start_date.month  = month_nr + 1;
-  start_date.year   = year_view->date->year;
-  start_date.hour   = 0;
-  start_date.minute = 0;
-  start_date.second = 0;
-  end_date.day    = 1;
-  end_date.month  = month_nr + 1;
-  end_date.year   = year_view->date->year;
-  end_date.hour   = 23;
-  end_date.minute = 59;
-  end_date.second = 59;
+  today.year = year_view->date->year;
+  today.month = month_nr + 1;
+  today.day = 1;
+  today.hour = 0;
+  today.minute = 0;
+  today.second = 0;
+  today.zone = gcal_manager_get_system_timezone (year_view->manager);
 
   for (i = 0; i < 7 * shown_rows; i++)
     {
@@ -899,23 +939,25 @@ draw_month_grid (GcalYearView *year_view,
                              layout);
         }
 
-      start_date.day = end_date.day = j;
-      events = gcal_manager_get_events (year_view->manager, &start_date, &end_date);
-      if (events != NULL)
+      /* Update the current day, so we can count the events at this day */
+      today.day = j;
+
+      if (count_events_at_day (year_view, &today) > 0)
         {
           gtk_style_context_save (context);
           gtk_style_context_add_class (context, "with-events");
+
           if (selected_day)
             gtk_style_context_add_class (context, "with-events-selected");
           else if (column == sunday_idx)
             gtk_style_context_add_class (context, "with-events-sunday");
-          box_padding_start = (box_side - VISUAL_CLUES_SIDE) / 2 > 0 ? (box_side - VISUAL_CLUES_SIDE) / 2 : 0;
+
+          box_padding_start = MAX (0, (box_side - VISUAL_CLUES_SIDE) / 2);
           gtk_render_background (context, cr,
                                  box_side * column + x + sw * box_padding_start - year_view->k * VISUAL_CLUES_SIDE,
                                  box_side * (row + 1) + y + box_padding_top + layout_height + 2.0,
                                  VISUAL_CLUES_SIDE, VISUAL_CLUES_SIDE);
           gtk_style_context_restore (context);
-          g_list_free_full (events, g_object_unref);
         }
 
       g_free (nr_day);
@@ -1477,6 +1519,7 @@ static void
 gcal_year_view_finalize (GObject *object)
 {
   GcalYearView *year_view = GCAL_YEAR_VIEW (object);
+  guint i;
 
   g_free (year_view->navigator_grid);
   g_free (year_view->selected_data);
@@ -1488,6 +1531,9 @@ gcal_year_view_finalize (GObject *object)
 
   g_clear_object (&year_view->calendar_settings);
 
+  for (i = 0; i < 12; i++)
+    g_clear_pointer (&year_view->events[i], g_ptr_array_unref);
+
   G_OBJECT_CLASS (gcal_year_view_parent_class)->finalize (object);
 }
 
@@ -1674,17 +1720,11 @@ gcal_year_view_component_added (ECalDataModelSubscriber *subscriber,
                                 ECalClient              *client,
                                 ECalComponent           *comp)
 {
-  GcalYearView *year_view = GCAL_YEAR_VIEW (subscriber);
-
+  GcalYearView *self = GCAL_YEAR_VIEW (subscriber);
+  GDateTime *event_start, *event_end;
   GcalEvent *event;
   GError *error;
-  GList **days_widgets_array;
-  GList *l;
-  gint i, days_span;
-
-  ECalComponentDateTime date;
-  time_t event_start, event_end, range_start, range_end;
-  icaltimezone *zone;
+  guint i, start_month, end_month;
 
   error = NULL;
   event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp, &error);
@@ -1696,85 +1736,27 @@ gcal_year_view_component_added (ECalDataModelSubscriber *subscriber,
       return;
     }
 
-  update_selected_dates_from_button_data (year_view);
-  days_span = icaltime_day_of_year(*(year_view->end_selected_date)) - icaltime_day_of_year(*(year_view->start_selected_date)) + 1;
-  days_widgets_array = g_new0 (GList*, days_span);
+  event_start = gcal_event_get_date_start (event);
+  event_end = gcal_event_get_date_end (event);
 
-  /* check if event belongs to range */
-  zone = gcal_manager_get_system_timezone (year_view->manager);
-  range_start = icaltime_as_timet_with_zone (*(year_view->start_selected_date), zone);
-  range_end = icaltime_as_timet_with_zone (*(year_view->end_selected_date), zone);
+  /* Calculate the start & end months */
+  start_month = g_date_time_get_month (event_start) - 1;
+  end_month = g_date_time_get_month (event_end) - 1;
 
-  e_cal_component_get_dtstart (comp, &date);
-  event_start = icaltime_as_timet_with_zone (*(date.value), date.value->zone != NULL ? date.value->zone : zone);
-  e_cal_component_free_datetime (&date);
+  if (g_date_time_get_year (event_start) < self->date->year)
+    start_month = 0;
 
-  e_cal_component_get_dtend (comp, &date);
-  if (date.value != NULL)
-    event_end = icaltime_as_timet_with_zone (*(date.value), date.value->zone != NULL ? date.value->zone : zone);
-  else
-    event_end = event_start;
-  e_cal_component_free_datetime (&date);
+  if (g_date_time_get_year (event_end) > self->date->year)
+    end_month = 11;
 
-  if (!((event_start <= range_start && event_end >= range_end) ||
-        (event_start >= range_start && event_end <= range_end) ||
-        (event_start >= range_start && event_start <= range_end) ||
-        (event_end >= range_start && event_end <= range_end)))
-    {
-      goto out;
-    }
+  /* Add the event to the cache */
+  for (i = start_month; i <= end_month; i++)
+    g_ptr_array_add (self->events[i], event);
 
-  add_event_to_day_array (year_view, event, days_widgets_array, days_span);
-  gtk_stack_set_visible_child_name (GTK_STACK (year_view->navigator_stack), "events-list");
+  update_selected_dates_from_button_data (self);
+  update_sidebar (self);
 
-  for (i = 0; i < days_span; i++)
-    {
-      GList *current_day = days_widgets_array[i];
-      for (l = current_day; l != NULL; l = g_list_next (l))
-        {
-          GtkWidget *child_widget = l->data;
-          gtk_widget_show (child_widget);
-          g_signal_connect (child_widget, "activate", G_CALLBACK (event_activated), year_view);
-          g_object_set_data (G_OBJECT (child_widget), "shift", GINT_TO_POINTER (i));
-          gtk_container_add (GTK_CONTAINER (year_view->events_sidebar), child_widget);
-        }
-
-      g_list_free (current_day);
-    }
-
-  gtk_widget_queue_draw (year_view->navigator);
-
-out:
-  g_clear_object (&event);
-  g_free (days_widgets_array);
-}
-
-static void
-gcal_year_view_component_changed (ECalDataModelSubscriber *subscriber,
-                                  ECalClient              *client,
-                                  ECalComponent           *comp)
-{
-  GcalYearView *year_view = GCAL_YEAR_VIEW (subscriber);
-  GList *children, *l;
-  gchar *uuid;
-
-  uuid = get_uuid_from_component (e_client_get_source (E_CLIENT (client)), comp);
-  children = gtk_container_get_children (GTK_CONTAINER (year_view->events_sidebar));
-  for (l = children; l != NULL; l = g_list_next (l))
-    {
-      GcalEventWidget *child_widget;
-      GcalEvent *event;
-
-      child_widget = GCAL_EVENT_WIDGET (gtk_bin_get_child (GTK_BIN (l->data)));
-      event = gcal_event_widget_get_event (child_widget);
-
-      if (child_widget != NULL && g_strcmp0 (uuid, gcal_event_get_uid (event)) == 0)
-        gtk_widget_destroy (GTK_WIDGET (l->data));
-    }
-  g_list_free (children);
-  g_free (uuid);
-
-  gcal_year_view_component_added (subscriber, client, comp);
+  gtk_widget_queue_draw (GTK_WIDGET (self->navigator));
 }
 
 static void
@@ -1787,6 +1769,7 @@ gcal_year_view_component_removed (ECalDataModelSubscriber *subscriber,
   GList *children, *l;
   ESource *source;
   gchar *uuid;
+  guint i;
   gint number_of_children;
 
   source = e_client_get_source (E_CLIENT (client));
@@ -1823,11 +1806,49 @@ gcal_year_view_component_removed (ECalDataModelSubscriber *subscriber,
       gtk_stack_set_visible_child_name (GTK_STACK (year_view->navigator_stack), "no-events");
     }
 
+  /* Also remove from the cached list of events */
+  for (i = 0; i < 12; i++)
+    {
+      GPtrArray *events;
+      guint j;
+
+      events = year_view->events[i];
+
+      for (j = 0; j < events->len; j++)
+        {
+          GcalEvent *event;
+
+          event = g_ptr_array_index (events, j);
+
+          if (g_strcmp0 (gcal_event_get_uid (event), uuid) != 0)
+            continue;
+
+          g_ptr_array_remove (events, event);
+        }
+    }
+
+  gtk_widget_queue_draw (GTK_WIDGET (year_view->navigator));
+
   g_list_free (children);
   g_free (uuid);
 }
 
 static void
+gcal_year_view_component_changed (ECalDataModelSubscriber *subscriber,
+                                  ECalClient              *client,
+                                  ECalComponent           *comp)
+{
+  ECalComponentId *id;
+
+  id = e_cal_component_get_id (comp);
+
+  gcal_year_view_component_removed (subscriber, client, id->uid, id->rid);
+  gcal_year_view_component_added (subscriber, client, comp);
+
+  g_clear_pointer (&id, e_cal_component_free_id);
+}
+
+static void
 gcal_year_view_freeze (ECalDataModelSubscriber *subscriber)
 {
   ;
@@ -1897,6 +1918,11 @@ gcal_year_view_class_init (GcalYearViewClass *klass)
 static void
 gcal_year_view_init (GcalYearView *self)
 {
+  guint i;
+
+  for (i = 0; i < 12; i++)
+    self->events[i] = g_ptr_array_new ();
+
   gtk_widget_init_template (GTK_WIDGET (self));
 
   if (gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_LTR)

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to