diff -up evolution-3.8.5/calendar/gui/e-calendar-view.c.calendar-tooltip-hide evolution-3.8.5/calendar/gui/e-calendar-view.c --- evolution-3.8.5/calendar/gui/e-calendar-view.c.calendar-tooltip-hide 2013-08-10 23:38:42.000000000 +0200 +++ evolution-3.8.5/calendar/gui/e-calendar-view.c 2014-08-25 17:37:19.166154934 +0200 @@ -1863,26 +1863,31 @@ e_calendar_view_send (ECalendarView *cal g_object_unref (send_comp); } -static gboolean -tooltip_grab (GtkWidget *tooltip, - GdkEvent *key_event, - ECalendarView *view) +static void +tooltip_ungrab (ECalendarView *view, + guint32 event_time) { - GtkWidget *widget; GdkDevice *keyboard; - guint32 event_time; - - widget = g_object_get_data (G_OBJECT (view), "tooltip-window"); - if (widget == NULL) - return TRUE; - - event_time = gdk_event_get_time (key_event); while (!g_queue_is_empty (&view->priv->grabbed_keyboards)) { keyboard = g_queue_pop_head (&view->priv->grabbed_keyboards); gdk_device_ungrab (keyboard, event_time); g_object_unref (keyboard); } +} + +static gboolean +tooltip_key_event (GtkWidget *tooltip, + GdkEvent *key_event, + ECalendarView *view) +{ + GtkWidget *widget; + + widget = g_object_get_data (G_OBJECT (view), "tooltip-window"); + if (widget == NULL) + return TRUE; + + tooltip_ungrab (view, gdk_event_get_time (key_event)); gtk_widget_destroy (widget); g_object_set_data (G_OBJECT (view), "tooltip-window", NULL); @@ -1949,6 +1954,16 @@ e_calendar_view_move_tip (GtkWidget *wid gtk_widget_show (widget); } +static void +tooltip_window_destroyed_cb (gpointer user_data, + GObject *gone) +{ + ECalendarView *view = user_data; + + tooltip_ungrab (view, GDK_CURRENT_TIME); + g_object_unref (view); +} + /* * It is expected to show the tooltips in this below format * @@ -2189,9 +2204,10 @@ e_calendar_view_get_tooltips (const ECal g_signal_connect ( pevent->tooltip, "key-press-event", - G_CALLBACK (tooltip_grab), data->cal_view); + G_CALLBACK (tooltip_key_event), data->cal_view); pevent->timeout = -1; + g_object_weak_ref (G_OBJECT (pevent->tooltip), tooltip_window_destroyed_cb, g_object_ref (data->cal_view)); g_object_set_data (G_OBJECT (data->cal_view), "tooltip-window", pevent->tooltip); g_object_unref (newcomp); diff -up evolution-3.8.5/calendar/gui/e-day-view.c.calendar-tooltip-hide evolution-3.8.5/calendar/gui/e-day-view.c --- evolution-3.8.5/calendar/gui/e-day-view.c.calendar-tooltip-hide 2014-08-25 17:37:19.145154935 +0200 +++ evolution-3.8.5/calendar/gui/e-day-view.c 2014-08-25 17:38:55.403150856 +0200 @@ -405,6 +405,7 @@ static void e_day_view_queue_layout (EDa static void e_day_view_cancel_layout (EDayView *day_view); static gboolean e_day_view_layout_timeout_cb (gpointer data); static void tooltip_destroy (EDayView *day_view, GnomeCanvasItem *item); +static EDayViewEvent *tooltip_get_view_event (EDayView *day_view, gint day, gint event_num); enum { PROP_0, @@ -4068,7 +4069,13 @@ e_day_view_show_popup_menu (EDayView *da gint day, gint event_num) { - tooltip_destroy (day_view, NULL); + EDayViewEvent *pevent = NULL; + + if (event_num >= 0) + pevent = tooltip_get_view_event (day_view, day, event_num); + + if (pevent && pevent->canvas_item) + tooltip_destroy (day_view, pevent->canvas_item); day_view->popup_event_day = day; day_view->popup_event_num = event_num; diff -up evolution-3.8.5/calendar/gui/e-week-view.c.calendar-tooltip-hide evolution-3.8.5/calendar/gui/e-week-view.c --- evolution-3.8.5/calendar/gui/e-week-view.c.calendar-tooltip-hide 2014-08-25 17:37:19.147154935 +0200 +++ evolution-3.8.5/calendar/gui/e-week-view.c 2014-08-25 17:42:49.982140916 +0200 @@ -3212,6 +3212,28 @@ tooltip_destroy (EWeekView *week_view, } static gboolean +e_week_view_handle_tooltip_timeout (gpointer user_data) +{ + ECalendarViewEventData *data = user_data; + + g_return_val_if_fail (data != NULL, FALSE); + + return e_calendar_view_get_tooltips (data); +} + +static void +e_week_view_destroy_tooltip_timeout_data (gpointer ptr) +{ + ECalendarViewEventData *data = ptr; + + if (data) { + g_object_set_data ((GObject *) data->cal_view, "tooltip-timeout", NULL); + g_object_unref (data->cal_view); + g_free (data); + } +} + +static gboolean tooltip_event_cb (GnomeCanvasItem *item, GdkEvent *event, EWeekView *view) @@ -3232,14 +3254,14 @@ tooltip_event_cb (GnomeCanvasItem *item, pevent->y = ((GdkEventCrossing *) event)->y_root; pevent->tooltip = NULL; - data->cal_view = (ECalendarView *) view; + data->cal_view = g_object_ref (view); data->day = -1; data->event_num = event_num; data->get_view_event = (ECalendarViewEvent * (*)(ECalendarView *, int, gint)) tooltip_get_view_event; pevent->timeout = g_timeout_add_full ( G_PRIORITY_DEFAULT, 500, - (GSourceFunc) e_calendar_view_get_tooltips, - data, (GDestroyNotify) g_free); + e_week_view_handle_tooltip_timeout, + data, e_week_view_destroy_tooltip_timeout_data); g_object_set_data ((GObject *) view, "tooltip-timeout", GUINT_TO_POINTER (pevent->timeout)); return TRUE; @@ -3910,14 +3932,14 @@ e_week_view_on_text_item_event (GnomeCan pevent->y = (gint) event_y_root; pevent->tooltip = NULL; - data->cal_view = (ECalendarView *) week_view; + data->cal_view = g_object_ref (week_view); data->day = -1; data->event_num = nevent; data->get_view_event = (ECalendarViewEvent * (*)(ECalendarView *, int, gint)) tooltip_get_view_event; pevent->timeout = g_timeout_add_full ( G_PRIORITY_DEFAULT, 500, - (GSourceFunc) e_calendar_view_get_tooltips, - data, (GDestroyNotify) g_free); + e_week_view_handle_tooltip_timeout, + data, e_week_view_destroy_tooltip_timeout_data); g_object_set_data ((GObject *) week_view, "tooltip-timeout", GUINT_TO_POINTER (pevent->timeout)); return TRUE; @@ -4709,6 +4731,14 @@ e_week_view_show_popup_menu (EWeekView * GdkEvent *button_event, gint event_num) { + guint timeout; + + timeout = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (week_view), "tooltip-timeout")); + if (timeout) { + g_source_remove (timeout); + g_object_set_data (G_OBJECT (week_view), "tooltip-timeout", NULL); + } + week_view->popup_event_num = event_num; e_calendar_view_popup_event (E_CALENDAR_VIEW (week_view), button_event);