[goffice] Canvas: avoid anted cursor crash in Gnumeric.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] Canvas: avoid anted cursor crash in Gnumeric.
- Date: Sat, 6 Dec 2014 21:14:44 +0000 (UTC)
commit 6b5d824784090931ad63eede1e9042df325257ff
Author: Morten Welinder <terra gnome org>
Date: Sat Dec 6 16:13:15 2014 -0500
Canvas: avoid anted cursor crash in Gnumeric.
With this patch we will be more careful in removing items from a canvas.
The canvas stores direct pointers to some items and we now clear them
consistently.
ChangeLog | 15 +++++++++++++++
NEWS | 1 +
goffice/canvas/goc-canvas.c | 32 +++++++++++++++++++++++++++++---
goffice/canvas/goc-canvas.h | 2 ++
goffice/canvas/goc-group.c | 6 ++++--
goffice/canvas/goc-item.c | 4 ----
6 files changed, 51 insertions(+), 9 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index bf6e4cb..e5e9955 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2014-12-06 Morten Welinder <terra gnome org>
+
+ * goffice/canvas/goc-canvas.c (goc_canvas_draw): Plug leak.
+ (_goc_canvas_remove_item): New function. Use of this fixes
+ several crashes.
+
+ * goffice/canvas/goc-group.c (goc_group_remove_child): Don't mess
+ directly with the canvas' members here. Tell the canvas that
+ child is gone.
+ (goc_group_add_child): If the canvas changes, tell the old canvas
+ that child is gone.
+
+ * goffice/canvas/goc-item.c (goc_item_dispose): Don't mess
+ directly with the canvas' members here.
+
2014-11-26 Jean Brefort <jean brefort normalesup org>
reviewed by: <delete if not using a buddy>
diff --git a/NEWS b/NEWS
index 91e409e..1521bf6 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ Jean:
Morten:
* Dead kitten salvage.
+ * Fix canvas issues when removing items.
--------------------------------------------------------------------------
goffice 0.10.18:
diff --git a/goffice/canvas/goc-canvas.c b/goffice/canvas/goc-canvas.c
index 03acc86..ea9f85b 100644
--- a/goffice/canvas/goc-canvas.c
+++ b/goffice/canvas/goc-canvas.c
@@ -87,9 +87,12 @@ goc_canvas_draw (GtkWidget *widget, cairo_t *cr)
}
return TRUE;
}
+
+ cairo_region_destroy (region);
}
+
goc_item_get_bounds (GOC_ITEM (canvas->root),&x0, &y0, &x1, &y1);
- for (i= 0; i < l->num_rectangles; i++) {
+ for (i= 0; i < l->num_rectangles; i++) {
clip_x1 = l->rectangles[i].x;
clip_y1 = l->rectangles[i].y;
clip_x2 = clip_x1 + l->rectangles[i].width;
@@ -292,8 +295,6 @@ goc_canvas_finalize (GObject *obj)
GocCanvas *canvas = GOC_CANVAS (obj);
GocCanvasPrivate *priv = (GocCanvasPrivate *) canvas->priv;
g_object_unref (canvas->root);
- if (priv->invalid_region != NULL)
- cairo_region_destroy (priv->invalid_region);
g_free (canvas->priv);
parent_klass->finalize (obj);
}
@@ -768,3 +769,28 @@ goc_canvas_get_bounds (GocCanvas *canvas, double *x0, double *y0, double *x1, do
goc_item_get_bounds (GOC_ITEM (canvas->root), x0, y0, x1, y1);
}
+/*
+ * Item is leaving this canvas. Get rid of direct pointers.
+ */
+void
+_goc_canvas_remove_item (GocCanvas *canvas, GocItem *item)
+{
+ GocCanvasPrivate *priv;
+
+ g_return_if_fail (GOC_IS_CANVAS (canvas));
+ g_return_if_fail (GOC_IS_ITEM (item));
+
+ priv = (GocCanvasPrivate *) canvas->priv;
+
+ if (canvas->last_item == item)
+ canvas->last_item = NULL;
+ if (canvas->grabbed_item == item)
+ canvas->grabbed_item = NULL;
+ if (priv->invalidated_item == item) {
+ if (priv->invalid_region != NULL) {
+ cairo_region_destroy (priv->invalid_region);
+ priv->invalid_region = NULL;
+ }
+ priv->invalidated_item = NULL;
+ }
+}
diff --git a/goffice/canvas/goc-canvas.h b/goffice/canvas/goc-canvas.h
index 41f205e..f55b951 100644
--- a/goffice/canvas/goc-canvas.h
+++ b/goffice/canvas/goc-canvas.h
@@ -93,6 +93,8 @@ void goc_canvas_c2w (GocCanvas *canvas, double x, double y, int *x_, int *y_);
void goc_canvas_render (GocCanvas *canvas, cairo_t *cr, double x0, double y0, double x1, double
y1);
void goc_canvas_get_bounds (GocCanvas *canvas, double *x0, double *y0, double *x1, double *y1);
+void _goc_canvas_remove_item (GocCanvas *canvas, GocItem *item);
+
G_END_DECLS
#endif /* GOC_CANVAS_H */
diff --git a/goffice/canvas/goc-group.c b/goffice/canvas/goc-group.c
index 389f1cb..24bf144 100644
--- a/goffice/canvas/goc-group.c
+++ b/goffice/canvas/goc-group.c
@@ -354,6 +354,8 @@ goc_group_add_child (GocGroup *parent, GocItem *item)
item->canvas = parent->base.canvas;
/* Notify of changes. */
+ if (old_canvas && item->canvas != old_canvas)
+ _goc_canvas_remove_item (old_canvas, item);
g_object_notify (G_OBJECT (item), "parent");
if (item->canvas != old_canvas)
g_object_notify (G_OBJECT (item), "canvas");
@@ -377,8 +379,8 @@ goc_group_remove_child (GocGroup *parent, GocItem *item)
g_return_if_fail (GOC_IS_GROUP (parent));
g_return_if_fail (GOC_IS_ITEM (item));
g_return_if_fail (item->parent == parent);
- if (item->canvas && item->canvas->last_item == item)
- item->canvas->last_item = NULL;
+ if (item->canvas)
+ _goc_canvas_remove_item (item->canvas, item);
if (GOC_ITEM (parent)->realized)
_goc_item_unrealize (item);
parent->children = g_list_remove (parent->children, item);
diff --git a/goffice/canvas/goc-item.c b/goffice/canvas/goc-item.c
index e04c240..3e2aa2c 100644
--- a/goffice/canvas/goc-item.c
+++ b/goffice/canvas/goc-item.c
@@ -221,10 +221,6 @@ goc_item_dispose (GObject *object)
GtkStyleContext *context;
if (item->canvas) {
- if (item->canvas->last_item == item)
- item->canvas->last_item = NULL;
- if (item->canvas->grabbed_item == item)
- item->canvas->grabbed_item = NULL;
item->cached_bounds = TRUE; /* avoids a call to update_bounds */
goc_item_invalidate (item);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]