month-view: fight the sizing machinery even harder
Make sure something changed in child widgets AND events, otherwise just top allocating at all.
This commit is contained in:
+58
-11
@@ -121,12 +121,14 @@ struct _GcalMonthView
|
|||||||
|
|
||||||
/* Storage for the accumulated scrolling */
|
/* Storage for the accumulated scrolling */
|
||||||
gdouble scroll_value;
|
gdouble scroll_value;
|
||||||
|
|
||||||
guint update_grid_id;
|
guint update_grid_id;
|
||||||
|
|
||||||
/* property */
|
/* property */
|
||||||
icaltimetype *date;
|
icaltimetype *date;
|
||||||
GcalManager *manager;
|
GcalManager *manager;
|
||||||
|
|
||||||
|
gboolean pending_event_allocation;
|
||||||
|
gboolean pending_child_allocation;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MIRROR(val,start,end) (start + (val / end) * end + (end - val % end))
|
#define MIRROR(val,start,end) (start + (val / end) * end + (end - val % end))
|
||||||
@@ -472,8 +474,10 @@ static gboolean
|
|||||||
update_month_cells (GcalMonthView *self)
|
update_month_cells (GcalMonthView *self)
|
||||||
{
|
{
|
||||||
g_autoptr (GDateTime) dt;
|
g_autoptr (GDateTime) dt;
|
||||||
|
gboolean changed;
|
||||||
guint row, col;
|
guint row, col;
|
||||||
|
|
||||||
|
changed = FALSE;
|
||||||
dt = g_date_time_new_local (self->date->year, self->date->month, 1, 0, 0, 0);
|
dt = g_date_time_new_local (self->date->year, self->date->month, 1, 0, 0, 0);
|
||||||
|
|
||||||
for (row = 0; row < 6; row++)
|
for (row = 0; row < 6; row++)
|
||||||
@@ -496,18 +500,27 @@ update_month_cells (GcalMonthView *self)
|
|||||||
|
|
||||||
/* Cell date */
|
/* Cell date */
|
||||||
cell_date = g_date_time_add_days (dt, row * 7 + col - self->days_delay);
|
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);
|
gcal_month_cell_set_date (cell, cell_date);
|
||||||
|
|
||||||
/* Different month */
|
/* Different month */
|
||||||
different_month = day < self->days_delay ||
|
different_month = day < self->days_delay ||
|
||||||
day - self->days_delay >= icaltime_days_in_month (self->date->month, self->date->year);
|
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);
|
gcal_month_cell_set_different_month (cell, different_month);
|
||||||
|
|
||||||
if (different_month)
|
if (different_month)
|
||||||
{
|
{
|
||||||
|
changed |= gcal_month_cell_get_selected (cell) != FALSE;
|
||||||
gcal_month_cell_set_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);
|
gcal_month_cell_set_overflow (cell, 0);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,6 +528,8 @@ update_month_cells (GcalMonthView *self)
|
|||||||
if (g_hash_table_contains (self->overflow_cells, GINT_TO_POINTER (day)))
|
if (g_hash_table_contains (self->overflow_cells, GINT_TO_POINTER (day)))
|
||||||
l = g_hash_table_lookup (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);
|
gcal_month_cell_set_overflow (cell, l ? g_list_length (l) : 0);
|
||||||
|
|
||||||
/* Selection */
|
/* Selection */
|
||||||
@@ -538,11 +553,14 @@ update_month_cells (GcalMonthView *self)
|
|||||||
datetime_compare_date (gcal_month_cell_get_date (cell), selection_end) <= 0;
|
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);
|
gcal_month_cell_set_selected (cell, selected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self->update_grid_id = 0;
|
self->update_grid_id = 0;
|
||||||
|
self->pending_child_allocation = changed;
|
||||||
|
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
@@ -878,11 +896,13 @@ gcal_month_view_component_added (ECalDataModelSubscriber *subscriber,
|
|||||||
ECalClient *client,
|
ECalClient *client,
|
||||||
ECalComponent *comp)
|
ECalComponent *comp)
|
||||||
{
|
{
|
||||||
|
GcalMonthView *self;
|
||||||
GtkWidget *event_widget;
|
GtkWidget *event_widget;
|
||||||
GcalEvent *event;
|
GcalEvent *event;
|
||||||
GError *error;
|
GError *error;
|
||||||
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
|
self = GCAL_MONTH_VIEW (subscriber);
|
||||||
event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp, &error);
|
event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp, &error);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
@@ -898,6 +918,8 @@ gcal_month_view_component_added (ECalDataModelSubscriber *subscriber,
|
|||||||
gtk_widget_show (event_widget);
|
gtk_widget_show (event_widget);
|
||||||
gtk_container_add (GTK_CONTAINER (subscriber), event_widget);
|
gtk_container_add (GTK_CONTAINER (subscriber), event_widget);
|
||||||
|
|
||||||
|
self->pending_event_allocation = TRUE;
|
||||||
|
|
||||||
g_clear_object (&event);
|
g_clear_object (&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -942,6 +964,8 @@ gcal_month_view_component_modified (ECalDataModelSubscriber *subscriber,
|
|||||||
gtk_widget_destroy (new_widget);
|
gtk_widget_destroy (new_widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->pending_event_allocation = TRUE;
|
||||||
|
|
||||||
g_clear_object (&event);
|
g_clear_object (&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -976,6 +1000,8 @@ gcal_month_view_component_removed (ECalDataModelSubscriber *subscriber,
|
|||||||
}
|
}
|
||||||
|
|
||||||
gtk_widget_destroy (l->data);
|
gtk_widget_destroy (l->data);
|
||||||
|
|
||||||
|
self->pending_event_allocation = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1439,6 +1465,18 @@ gcal_month_view_size_allocate (GtkWidget *widget,
|
|||||||
|
|
||||||
self = gcal_month_view_get_instance_private (GCAL_MONTH_VIEW (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 */
|
/* Remove every widget' parts, but the master widget */
|
||||||
widgets = g_hash_table_get_values (self->children);
|
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);
|
all_day = gcal_event_get_all_day (event);
|
||||||
child_context = gtk_widget_get_style_context (l->data);
|
child_context = gtk_widget_get_style_context (l->data);
|
||||||
|
|
||||||
gtk_widget_show (child_widget);
|
|
||||||
gtk_widget_get_preferred_height (child_widget, &minimum_height, NULL);
|
gtk_widget_get_preferred_height (child_widget, &minimum_height, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1622,9 +1659,9 @@ gcal_month_view_size_allocate (GtkWidget *widget,
|
|||||||
if (cell != 0)
|
if (cell != 0)
|
||||||
{
|
{
|
||||||
child_widget = gcal_event_widget_clone (GCAL_EVENT_WIDGET (child_widget));
|
child_widget = gcal_event_widget_clone (GCAL_EVENT_WIDGET (child_widget));
|
||||||
|
gtk_widget_show (child_widget);
|
||||||
|
|
||||||
setup_child_widget (self, child_widget);
|
setup_child_widget (self, child_widget);
|
||||||
gtk_widget_show (child_widget);
|
|
||||||
|
|
||||||
child_context = gtk_widget_get_style_context (child_widget);
|
child_context = gtk_widget_get_style_context (child_widget);
|
||||||
|
|
||||||
@@ -1637,7 +1674,7 @@ gcal_month_view_size_allocate (GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
gint idx;
|
gint idx;
|
||||||
|
|
||||||
gtk_widget_hide (child_widget);
|
gtk_widget_set_child_visible (child_widget, FALSE);
|
||||||
|
|
||||||
for (idx = cell_idx; idx < cell_idx + length; idx++)
|
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_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,
|
* 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);
|
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.x = pos_x;
|
||||||
child_allocation.y = pos_y + vertical_cell_space[cell_idx] - size_left[cell_idx];
|
child_allocation.y = pos_y + vertical_cell_space[cell_idx] - size_left[cell_idx];
|
||||||
child_allocation.width = width - (margin.left + margin.right);
|
child_allocation.width = width - (margin.left + margin.right);
|
||||||
@@ -1740,16 +1783,12 @@ gcal_month_view_size_allocate (GtkWidget *widget,
|
|||||||
event = gcal_event_widget_get_event (aux->data);
|
event = gcal_event_widget_get_event (aux->data);
|
||||||
uuid = gcal_event_get_uid (event);
|
uuid = gcal_event_get_uid (event);
|
||||||
|
|
||||||
if (!gtk_widget_is_visible (child_widget))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
gtk_widget_show (child_widget);
|
|
||||||
gtk_widget_get_preferred_height (child_widget, &minimum_height, NULL);
|
gtk_widget_get_preferred_height (child_widget, &minimum_height, NULL);
|
||||||
|
|
||||||
/* No space left, add to the overflow and continue */
|
/* No space left, add to the overflow and continue */
|
||||||
if (size_left[cell] < minimum_height)
|
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_hash_table_lookup (self->overflow_cells, GINT_TO_POINTER (cell));
|
||||||
l = g_list_append (l, child_widget);
|
l = g_list_append (l, child_widget);
|
||||||
@@ -1762,6 +1801,8 @@ gcal_month_view_size_allocate (GtkWidget *widget,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gtk_widget_set_child_visible (child_widget, TRUE);
|
||||||
|
|
||||||
child_context = gtk_widget_get_style_context (child_widget);
|
child_context = gtk_widget_get_style_context (child_widget);
|
||||||
|
|
||||||
gtk_style_context_get_margin (child_context, gtk_style_context_get_state (child_context), &margin);
|
gtk_style_context_get_margin (child_context, gtk_style_context_get_state (child_context), &margin);
|
||||||
@@ -1776,7 +1817,8 @@ gcal_month_view_size_allocate (GtkWidget *widget,
|
|||||||
child_allocation.y = pos_y + vertical_cell_space[cell] - size_left[cell];
|
child_allocation.y = pos_y + vertical_cell_space[cell] - size_left[cell];
|
||||||
child_allocation.width = width - (margin.left + margin.right);
|
child_allocation.width = width - (margin.left + margin.right);
|
||||||
child_allocation.height = minimum_height;
|
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);
|
gtk_widget_size_allocate (child_widget, &child_allocation);
|
||||||
|
|
||||||
size_left[cell] -= minimum_height + margin.top + margin.bottom;
|
size_left[cell] -= minimum_height + margin.top + margin.bottom;
|
||||||
@@ -1784,6 +1826,9 @@ gcal_month_view_size_allocate (GtkWidget *widget,
|
|||||||
}
|
}
|
||||||
|
|
||||||
queue_update_month_cells (self);
|
queue_update_month_cells (self);
|
||||||
|
|
||||||
|
self->pending_event_allocation = FALSE;
|
||||||
|
self->pending_child_allocation = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -2007,6 +2052,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->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->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->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;
|
self->k = gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user