event-widget: properly draw dnd icon
Instead of using a pixbuf and relying on the underlying GdkWindow, simply perform a custom draw() over a manually created cairo context and avoid nasty crashes.
This commit is contained in:
+23
-12
@@ -40,9 +40,6 @@ struct _GcalEventWidget
|
|||||||
|
|
||||||
GcalEvent *event;
|
GcalEvent *event;
|
||||||
|
|
||||||
/* Drag n' Drop icon */
|
|
||||||
GdkPixbuf *dnd_pixbuf;
|
|
||||||
|
|
||||||
GtkOrientation orientation;
|
GtkOrientation orientation;
|
||||||
|
|
||||||
GdkWindow *event_window;
|
GdkWindow *event_window;
|
||||||
@@ -290,7 +287,6 @@ gcal_event_widget_finalize (GObject *object)
|
|||||||
|
|
||||||
/* releasing properties */
|
/* releasing properties */
|
||||||
g_clear_pointer (&self->css_class, g_free);
|
g_clear_pointer (&self->css_class, g_free);
|
||||||
g_clear_object (&self->dnd_pixbuf);
|
|
||||||
g_clear_object (&self->event);
|
g_clear_object (&self->event);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gcal_event_widget_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gcal_event_widget_parent_class)->finalize (object);
|
||||||
@@ -678,13 +674,30 @@ gcal_event_widget_button_release_event (GtkWidget *widget,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_surface_t*
|
||||||
|
get_dnd_icon (GtkWidget *widget)
|
||||||
|
{
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
|
/* Make it transparent */
|
||||||
|
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||||
|
gtk_widget_get_allocated_width (widget),
|
||||||
|
gtk_widget_get_allocated_height (widget));
|
||||||
|
|
||||||
|
cr = cairo_create (surface);
|
||||||
|
|
||||||
|
gtk_widget_draw (widget, cr);
|
||||||
|
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gcal_event_widget_drag_begin (GtkWidget *widget,
|
gcal_event_widget_drag_begin (GtkWidget *widget,
|
||||||
GdkDragContext *context)
|
GdkDragContext *context)
|
||||||
{
|
{
|
||||||
GcalEventWidget *self = GCAL_EVENT_WIDGET (widget);
|
GcalEventWidget *self = GCAL_EVENT_WIDGET (widget);
|
||||||
|
cairo_surface_t *surface;
|
||||||
g_clear_object (&self->dnd_pixbuf);
|
|
||||||
|
|
||||||
if (self->read_only)
|
if (self->read_only)
|
||||||
{
|
{
|
||||||
@@ -693,13 +706,11 @@ gcal_event_widget_drag_begin (GtkWidget *widget,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Setup the drag n' drop icon */
|
/* Setup the drag n' drop icon */
|
||||||
self->dnd_pixbuf = gdk_pixbuf_get_from_window (self->event_window,
|
surface = get_dnd_icon (widget);
|
||||||
0,
|
|
||||||
0,
|
|
||||||
gtk_widget_get_allocated_width (widget),
|
|
||||||
gtk_widget_get_allocated_height (widget));
|
|
||||||
|
|
||||||
gtk_drag_set_icon_pixbuf (context, self->dnd_pixbuf, 0, 0);
|
gtk_drag_set_icon_surface (context, surface);
|
||||||
|
|
||||||
|
g_clear_pointer (&surface, cairo_surface_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|||||||
Reference in New Issue
Block a user