[gnome-calendar/wip/gbsneto/month-cell-subwindow] month-view: fight the sizing machinery even harder



commit 6ad701adb3f3148749810832dd5446582a3ec23a
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Mon Nov 13 15:21:20 2017 -0200

    month-view: fight the sizing machinery even harder
    
    Make sure something changed in child widgets AND events,
    otherwise just top allocating at all.

 src/views/gcal-month-view.c |   65 +++++++++++++++++++++++++++++++++++++-----
 1 files changed, 57 insertions(+), 8 deletions(-)
---
diff --git a/src/views/gcal-month-view.c b/src/views/gcal-month-view.c
index 0a64e5f..d1950a1 100644
--- a/src/views/gcal-month-view.c
+++ b/src/views/gcal-month-view.c
@@ -121,12 +121,14 @@ struct _GcalMonthView
 
   /* Storage for the accumulated scrolling */
   gdouble             scroll_value;
-
   guint               update_grid_id;
 
   /* property */
   icaltimetype       *date;
   GcalManager        *manager;
+
+  gboolean            pending_event_allocation;
+  gboolean            pending_child_allocation;
 };
 
 #define MIRROR(val,start,end) (start + (val / end) * end + (end - val % end))
@@ -472,8 +474,10 @@ static gboolean
 update_month_cells (GcalMonthView *self)
 {
   g_autoptr (GDateTime) dt;
+  gboolean changed;
   guint row, col;
 
+  changed = FALSE;
   dt = g_date_time_new_local (self->date->year, self->date->month, 1, 0, 0, 0);
 
   for (row = 0; row < 6; row++)
@@ -496,18 +500,27 @@ update_month_cells (GcalMonthView *self)
 
           /* Cell date */
           cell_date = g_date_time_add_days (dt, row * 7 + col - self->days_delay);
+
+          changed |= datetime_compare_date (gcal_month_cell_get_date (cell), cell_date) != 0;
+
           gcal_month_cell_set_date (cell, cell_date);
 
           /* Different month */
           different_month = day < self->days_delay ||
                             day - self->days_delay >= icaltime_days_in_month (self->date->month, 
self->date->year);
 
+          changed |= different_month != gcal_month_cell_get_different_month (cell);
+
           gcal_month_cell_set_different_month (cell, different_month);
 
           if (different_month)
             {
+              changed |= gcal_month_cell_get_selected (cell) != FALSE;
               gcal_month_cell_set_selected (cell, FALSE);
+
+              changed |= gcal_month_cell_get_overflow (cell) != 0;
               gcal_month_cell_set_overflow (cell, 0);
+
               continue;
             }
 
@@ -515,6 +528,8 @@ update_month_cells (GcalMonthView *self)
           if (g_hash_table_contains (self->overflow_cells, GINT_TO_POINTER (day)))
             l = g_hash_table_lookup (self->overflow_cells, GINT_TO_POINTER (day));
 
+          changed |= gcal_month_cell_get_overflow (cell) != g_list_length (l);
+
           gcal_month_cell_set_overflow (cell, l ? g_list_length (l) : 0);
 
           /* Selection */
@@ -538,11 +553,14 @@ update_month_cells (GcalMonthView *self)
                          datetime_compare_date (gcal_month_cell_get_date (cell), selection_end) <= 0;
             }
 
+          changed |= gcal_month_cell_get_selected (cell) != selected;
+
           gcal_month_cell_set_selected (cell, selected);
         }
     }
 
   self->update_grid_id = 0;
+  self->pending_child_allocation = changed;
 
   return G_SOURCE_REMOVE;
 }
@@ -878,11 +896,13 @@ gcal_month_view_component_added (ECalDataModelSubscriber *subscriber,
                                  ECalClient              *client,
                                  ECalComponent           *comp)
 {
+  GcalMonthView *self;
   GtkWidget *event_widget;
   GcalEvent *event;
   GError *error;
 
   error = NULL;
+  self = GCAL_MONTH_VIEW (subscriber);
   event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp, &error);
 
   if (error)
@@ -898,6 +918,8 @@ gcal_month_view_component_added (ECalDataModelSubscriber *subscriber,
   gtk_widget_show (event_widget);
   gtk_container_add (GTK_CONTAINER (subscriber), event_widget);
 
+  self->pending_event_allocation = TRUE;
+
   g_clear_object (&event);
 }
 
@@ -942,6 +964,8 @@ gcal_month_view_component_modified (ECalDataModelSubscriber *subscriber,
       gtk_widget_destroy (new_widget);
     }
 
+  self->pending_event_allocation = TRUE;
+
   g_clear_object (&event);
 }
 
@@ -976,6 +1000,8 @@ gcal_month_view_component_removed (ECalDataModelSubscriber *subscriber,
     }
 
   gtk_widget_destroy (l->data);
+
+  self->pending_event_allocation = TRUE;
 }
 
 static void
@@ -1439,6 +1465,18 @@ gcal_month_view_size_allocate (GtkWidget     *widget,
 
   self = gcal_month_view_get_instance_private (GCAL_MONTH_VIEW (widget));
 
+  /*
+   * If nothing changed, and the month cells didn't request an allocation,
+   * and the size is the same, return early here.
+   */
+  if (!self->pending_event_allocation &&
+      !self->pending_child_allocation &&
+      allocation->width == gtk_widget_get_allocated_width (widget) &&
+      allocation->height == gtk_widget_get_allocated_height (widget))
+    {
+      return;
+    }
+
   /* Remove every widget' parts, but the master widget */
   widgets = g_hash_table_get_values (self->children);
 
@@ -1513,7 +1551,6 @@ gcal_month_view_size_allocate (GtkWidget     *widget,
       all_day = gcal_event_get_all_day (event);
       child_context = gtk_widget_get_style_context (l->data);
 
-      gtk_widget_show (child_widget);
       gtk_widget_get_preferred_height (child_widget, &minimum_height, NULL);
 
       /*
@@ -1622,9 +1659,9 @@ gcal_month_view_size_allocate (GtkWidget     *widget,
           if (cell != 0)
             {
               child_widget = gcal_event_widget_clone (GCAL_EVENT_WIDGET (child_widget));
+              gtk_widget_show (child_widget);
 
               setup_child_widget (self, child_widget);
-              gtk_widget_show (child_widget);
 
               child_context = gtk_widget_get_style_context (child_widget);
 
@@ -1637,7 +1674,7 @@ gcal_month_view_size_allocate (GtkWidget     *widget,
             {
               gint idx;
 
-              gtk_widget_hide (child_widget);
+              gtk_widget_set_child_visible (child_widget, FALSE);
 
               for (idx = cell_idx; idx < cell_idx + length; idx++)
                 {
@@ -1661,7 +1698,7 @@ gcal_month_view_size_allocate (GtkWidget     *widget,
 
           gtk_widget_get_allocation (month_cell, &cell_alloc);
 
-          gtk_widget_get_preferred_height (child_widget, &minimum_height, NULL);
+          gtk_widget_set_child_visible (child_widget, TRUE);
 
           /*
            * Setup the widget's start date as the first day of the row,
@@ -1692,6 +1729,12 @@ gcal_month_view_size_allocate (GtkWidget     *widget,
 
           remove_cell_border_and_padding (month_cell, &pos_x, &pos_y, &width);
 
+          /*
+           * We can only get the minimum height after making all these calculations,
+           * otherwise GTK complains about allocating without calling get_preferred_height.
+           */
+          gtk_widget_get_preferred_height (child_widget, &minimum_height, NULL);
+
           child_allocation.x = pos_x;
           child_allocation.y = pos_y + vertical_cell_space[cell_idx] - size_left[cell_idx];
           child_allocation.width = width - (margin.left + margin.right);
@@ -1740,7 +1783,7 @@ gcal_month_view_size_allocate (GtkWidget     *widget,
           event = gcal_event_widget_get_event (aux->data);
           uuid = gcal_event_get_uid (event);
 
-          if (!gtk_widget_is_visible (child_widget))
+          if (!gtk_widget_get_child_visible (child_widget))
             continue;
 
           gtk_widget_show (child_widget);
@@ -1749,7 +1792,7 @@ gcal_month_view_size_allocate (GtkWidget     *widget,
           /* No space left, add to the overflow and continue */
           if (size_left[cell] < minimum_height)
             {
-              gtk_widget_hide (child_widget);
+              gtk_widget_set_child_visible (child_widget, FALSE);
 
               l = g_hash_table_lookup (self->overflow_cells, GINT_TO_POINTER (cell));
               l = g_list_append (l, child_widget);
@@ -1776,7 +1819,8 @@ gcal_month_view_size_allocate (GtkWidget     *widget,
           child_allocation.y = pos_y + vertical_cell_space[cell] - size_left[cell];
           child_allocation.width = width - (margin.left + margin.right);
           child_allocation.height = minimum_height;
-          gtk_widget_show (child_widget);
+
+          gtk_widget_set_child_visible (child_widget, TRUE);
           gtk_widget_size_allocate (child_widget, &child_allocation);
 
           size_left[cell] -= minimum_height + margin.top + margin.bottom;
@@ -1784,6 +1828,9 @@ gcal_month_view_size_allocate (GtkWidget     *widget,
     }
 
   queue_update_month_cells (self);
+
+  self->pending_event_allocation = FALSE;
+  self->pending_child_allocation = FALSE;
 }
 
 static gboolean
@@ -2007,6 +2054,8 @@ gcal_month_view_init (GcalMonthView *self)
   self->children = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_list_free);
   self->single_cell_children = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) 
g_list_free);
   self->overflow_cells = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) 
g_list_free);
+  self->pending_event_allocation = FALSE;
+  self->pending_child_allocation = FALSE;
 
   self->k = gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]