After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 571742 - Get rid of deprecated libgnomecanvas
Get rid of deprecated libgnomecanvas
Status: RESOLVED FIXED
Product: evolution
Classification: Applications
Component: general
2.26.x (obsolete)
Other Linux
: Normal normal
: ---
Assigned To: Evolution Shell Maintainers Team
Evolution QA team
evolution[cleanup] evolution[etable]
Depends on:
Blocks:
 
 
Reported: 2009-02-14 15:39 UTC by André Klapper
Modified: 2010-06-14 08:02 UTC
See Also:
GNOME target: 3.0
GNOME version: ---



Description André Klapper 2009-02-14 15:39:03 UTC
According to http://live.gnome.org/TwoPointTwentyfive/Platform libgnomecanvas has been deprecated for years and should be removed.


$:\> grep -r "#include <libgnomecanvas/" .
./evolution/addressbook/gui/widgets/e-minicard.c:#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
./evolution/addressbook/gui/widgets/e-minicard.c:#include <libgnomecanvas/gnome-canvas-pixbuf.h>
./evolution/addressbook/gui/widgets/e-minicard-label.c:#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
./evolution/addressbook/gui/widgets/e-minicard.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/addressbook/gui/widgets/e-minicard-label.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/misc/e-canvas-background.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/misc/e-canvas.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/misc/e-reflow.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/misc/e-canvas-utils.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/misc/e-reflow-model.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/misc/e-calendar-item.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/misc/e-canvas-vbox.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/misc/e-gui-utils.c:#include <libgnomecanvas/gnome-canvas-pixbuf.h>
./evolution/widgets/misc/e-calendar.c:#include <libgnomecanvas/gnome-canvas-widget.h>
./evolution/widgets/text/e-text.c:#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
./evolution/widgets/table/e-tree-scrolled.c:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-table-click-to-add.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-cell-toggle.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-table-group.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-tree.c:#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
./evolution/widgets/table/e-table-item.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-table-group-leaf.c:#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
./evolution/widgets/table/e-cell-text.c:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-cell-text.c:#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
./evolution/widgets/table/e-table-group-leaf.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-table.c:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-table.c:#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
./evolution/widgets/table/e-table-group.c:#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
./evolution/widgets/table/e-table.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-cell-vbox.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-cell-hbox.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-cell-popup.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-table-header-item.c:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-table-header-item.c:#include <libgnomecanvas/gnome-canvas-util.h>
./evolution/widgets/table/e-table-header-item.c:#include <libgnomecanvas/gnome-canvas-polygon.h>
./evolution/widgets/table/e-table-header-item.c:#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
./evolution/widgets/table/e-cell-text.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-table-field-chooser.c:#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
./evolution/widgets/table/e-table-group-container.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-table-tooltip.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-cell-tree.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-table-click-to-add.c:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-table-click-to-add.c:#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
./evolution/widgets/table/e-table-click-to-add.c:#include <libgnomecanvas/gnome-canvas-util.h>
./evolution/widgets/table/e-table-header-item.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-table-group-container.c:#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
./evolution/widgets/table/e-cell-checkbox.c:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-cell-toggle.c:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-table-field-chooser-item.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-cell-pixbuf.c:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-table-field-chooser-item.c:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-table-field-chooser-item.c:#include <libgnomecanvas/gnome-canvas-util.h>
./evolution/widgets/table/e-table-field-chooser-item.c:#include <libgnomecanvas/gnome-canvas-polygon.h>
./evolution/widgets/table/e-table-field-chooser-item.c:#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
./evolution/widgets/table/e-tree.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-table-scrolled.c:#include <libgnomecanvas/gnome-canvas.h>
./evolution/widgets/table/e-cell-tree.c:#include <libgnomecanvas/gnome-canvas.h>
./evolution/calendar/gui/e-week-view.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/calendar/gui/e-meeting-time-sel.c:#include <libgnomecanvas/gnome-canvas-widget.h>
./evolution/calendar/gui/e-day-view.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/calendar/gui/e-week-view.c:#include <libgnomecanvas/gnome-canvas-pixbuf.h>
./evolution/calendar/gui/e-day-view.c:#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
./evolution/calendar/gui/weekday-picker.c:#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
./evolution/calendar/gui/weekday-picker.c:#include <libgnomecanvas/gnome-canvas-text.h>
./evolution/calendar/gui/weekday-picker.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/calendar/gui/e-meeting-time-sel.h:#include <libgnomecanvas/gnome-canvas.h>
./evolution/a11y/widgets/ea-calendar-item.c:#include <libgnomecanvas/gnome-canvas.h>
./evolution/a11y/calendar/ea-calendar-helpers.c:#include <libgnomecanvas/gnome-canvas-pixbuf.h>
./evolution/a11y/calendar/ea-jump-button.c:#include <libgnomecanvas/gnome-canvas.h>
./evolution/a11y/calendar/ea-calendar.c:#include <libgnomecanvas/gnome-canvas-pixbuf.h>

./evolution/configure.in: m4_define([libgnomecanvas_minimum_version], [2.0.0])
./evolution/configure.in: libgnomecanvas-2.0 >= libgnomecanvas_minimum_version
Comment 1 Matthew Barnes 2009-02-14 17:04:22 UTC
This is going to be very difficult without a complete rewrite of ETable.
Comment 2 Matthew Barnes 2009-02-15 03:25:01 UTC
Have we even settled on what is to replace libgnomecanvas yet?
Comment 3 André Klapper 2009-02-15 18:44:22 UTC
*shrug* some cairo, and probably also stuff not yet written.
Comment 4 André Klapper 2009-04-03 12:31:55 UTC
Any vague idea how many manhours/days this would take? A week? A month? *shrug*
Comment 5 Matthew Barnes 2009-04-03 12:57:02 UTC
Feels like it could be a sizable project though, even for someone adept at Cairo, which I'm not.  (And that's assuming Cairo is the right replacement here.)  I'm thinking a month, minimum.  Each widget would have to be adapted individually, and that's a pretty long list above.
Comment 6 Federico Mena Quintero 2009-05-04 22:41:14 UTC
Porting Evolution away from libgnomecanvas is:

a) A *huge* project.  Evo has a lot of custom widgetry written with libgnomecanvas, including delicate/big subprojects like ETable.

b) A waste of time, in my opinion.  You could just embed the libgnomecanvas sources within Evolution itself if you really want to kill a library dependency.

c) Something that provides no benefits to the end-user.

One could start by investigating using FooCanvas (embedded in Evolution) instead of libgnomecanvas.
Comment 7 Matthew Barnes 2009-05-05 00:54:33 UTC
(In reply to comment #6)
> b) A waste of time, in my opinion.  You could just embed the libgnomecanvas
> sources within Evolution itself if you really want to kill a library
> dependency.

That's probably what we'll have to do, sadly, along with GtkCList and pieces of libgnomeui.  Evolution is slowly becoming a GNOME ancient history museum.
Comment 8 Javier Jardón (IRC: jjardon) 2009-06-05 02:13:46 UTC
You can see possible gnomecanvas substitutes here: http://live.gnome.org/ProjectRidley/CanvasOverview
Comment 9 André Klapper 2009-06-05 09:30:25 UTC
(In reply to comment #8)
> You can see possible gnomecanvas substitutes here

I basically currently don't want to see another canvas lib going into the stack.
Comment 10 Chenthill P 2009-07-21 08:10:17 UTC
As mentioned previously, we will not be able to get rid of libgnomecanvas. Milan investigated on replacing Etable and has more precise details on the same..
Comment 11 Chenthill P 2009-07-21 08:11:08 UTC
previously = in comments above from federico and mbarnes :-)
Comment 12 Milan Crha 2009-07-21 09:46:34 UTC
Yeah, I agree with Federico and Matt with b), as I did some investigation about ETable removal from evo, using GtkTreeView, (I know many, people told me that it's impossible, but I thought it would be a good thing to retest it with latest gtk+ (2.27.4 in my case)) and it's basically not possible, mainly because of performance issues when filling large tables, like those for mails. The only gain, interestingly in performance, was that the GtkTreeView drawing is much faster than that in ETable, but otherwise it is too slow on filling and has couple of other issues there. Let me summarize what I found:

a) GtkTreeStore is awfully slow when filling it
b) depending on the store size the "expand all" function also takes
   quite a long time, same as clearing whole model. I think it's mainly
   because of two things: 1) lack of freeze/thaw functions on
   view/model; 2) all the signals and internal functions uses
   GtkTreePath, even the documentation says the main way of accessing
   and traversing model is GtkTreeIter. Moreover most view/model signals
   are passing both GtkTreeIter and GtkTreePath pointers, which is,
   from my point of view, not necessary, as the path can be created
   from iter very easily and the receiver of the signal can do that
   itself, as I didn't use the path at all there.
c) multiline renderer - the one used for a wide view
d) Even GtkTreeView can do multiselect, it cannot drag&drop it, one
   loses whole selection even when clicking on already selected row.
e) no custom text in the rows area for empty views.
f) very strange way of column sizing, either I do something wrong or
   resizing the last column is really impossible in a good way,
   partially also because the "autosized" column isn't modified
   on other column resize, the view is too width for a screen estate it
   has set, but as soon as I change the estate the column widths are
   recalculated as expected.

Some of those above can be considered as bugs in GtkTreeView/Store. Some of them has some solutions available already, like from a multiline renderer by Srag, or multisilect in libegg, though the later is quite a big hack from my point of view.

Anyway, I did later some more tests about the slowness of filling. I have a test application and some test changes to gtk just for a "prove of concept", when filling a tree with approximately 60K rows,  and my measurement showed this:

Results of not patched gtk+ are these:
fill_tv took 8350 ms (with freeze/thaw)
expand_tv took 4710 ms (with freeze/thaw)
clear_tv took 500 ms (with freeze/thaw)

pressing fill twice in a row (which will not clear the model, thus there
are data inserted twice) is done in this time:
fill_tv took 8560 ms (with freeze/thaw)
fill_tv took 66600 ms (with freeze/thaw)
expand_tv took 41340 ms (with freeze/thaw)

The freeze/thaw means here only unsetting a model from a tree view
before the operation and setting it back when it's done. Without this
set/unset it's much slower.

With applied patch to gtk+, which basically adds freeze/thaw functions
on gtk_tree_store and doesn't create GtkTreePath for events which has
GtkTreeIter available makes the same things in much better times. Note
that it's just a hack patch to prove the correctness of the idea, it
crashes other applications.

For not checking "freeze/thaw" checkbox, which here means to invoke
signals, but without creating corresponding paths:
fill_tv took 1100 ms (without freeze/thaw)
expand_tv took 4600 ms (without freeze/thaw)
clear_tv took 480 ms (without freeze/thaw)
fill_tv took 1070 ms (without freeze/thaw)
fill_tv took 4110 ms (without freeze/thaw)
expand_tv took 41330 ms (without freeze/thaw)

and the same using freeze/thaw functions:
fill_tv took 460 ms (with freeze/thaw)
expand_tv took 4680 ms (with freeze/thaw)
clear_tv took 140 ms (with freeze/thaw)
fill_tv took 480 ms (with freeze/thaw)
fill_tv took 3470 ms (with freeze/thaw)
expand_tv took 43530 ms (with freeze/thaw)

I didn't investigate further what causes a drastic time increase for the
second filling, but I guess it's something when computing positions or
traversing tree store, as here is always used an append. Maybe adding
also the last children on the GNode might help here a bit.

It's still slow, even with a hack patch on gtk+, but way quicker.

I shared the above information and application with Gtk guys and they told me that freeze/thaw functions are unlikely to be added, as the initial effort was to avoid them. Instead, they plan to add some batch filling function, which will not emit any signals, only one, when the filling is done. I understood it that way at least. I think it makes sense. Though none of that will help with the expand slowness.

(Note: I copied most of the text above from my mail communication with various people, thus if you feel it's slightly out-of-context, then you might be right.)
Comment 13 Matthew Barnes 2009-07-21 12:18:50 UTC
(In reply to comment #10)
> As mentioned previously, we will not be able to get rid of libgnomecanvas.

Okay, so we're gonna own libgnomecanvas.  Can we keep it a separate tarball though, instead of merging it into Evolution as was done with libgal?  Our build process takes long enough as is.  I don't want to have to keep building and rebuilding this thing for no reason.
Comment 14 André Klapper 2009-07-21 12:35:21 UTC
Let's give this the lowest priority possible for GNOME 3 cleanup, please.
I'm personally for keeping gnome-canvas deprecated but not removing it for GNOME 3. Need to find consensus with the rest of release-team.
Comment 15 André Klapper 2009-07-30 15:34:29 UTC
So *IF* we do NOT remove libgnomecanvas for 3.0 it means that someone has to remove libglade stuff from libgnomecanvas plus maybe update deprecated GTK and Glib functionality.

At least it seems like libgnomecanvas does not need libgnome(ui) or Bonobo.


Grepping for "glade" in libgnomecanvas:

./glade/glade-canvas.c: * libglade - a library for building interfaces from XML files at runtime
./glade/glade-canvas.c: * glade-canvas.c: support for canvas widgets in libglade.
./glade/glade-canvas.c:#include <glade/glade-init.h>
./glade/glade-canvas.c:#include <glade/glade-build.h>
./glade/glade-canvas.c:glade_module_register_widgets (void)
./glade/glade-canvas.c:    glade_register_custom_prop (GNOME_TYPE_CANVAS, "anti_aliased", set_aa);
./glade/glade-canvas.c:    glade_register_custom_prop (GNOME_TYPE_CANVAS, "scroll_x1", set_scroll_x1);
./glade/glade-canvas.c:    glade_register_custom_prop (GNOME_TYPE_CANVAS, "scroll_y1", set_scroll_y1);
./glade/glade-canvas.c:    glade_register_custom_prop (GNOME_TYPE_CANVAS, "scroll_x2", set_scroll_x2);
./glade/glade-canvas.c:    glade_register_custom_prop (GNOME_TYPE_CANVAS, "scroll_y2", set_scroll_y2);
./glade/glade-canvas.c:    glade_register_custom_prop (GNOME_TYPE_CANVAS, "pixels_per_unit", set_pixels_per_unit);
./glade/glade-canvas.c:    glade_register_widget (GNOME_TYPE_CANVAS, glade_standard_build_widget, NULL, NULL);
./glade/glade-canvas.c:    glade_provide ("canvas");
./glade/Makefile.am:glademoduledir = $(libdir)/libglade/2.0
./glade/Makefile.am:glademodule_LTLIBRARIES = libcanvas.la
./glade/Makefile.am:	glade-canvas.c
./Makefile.am:SUBDIRS = libgnomecanvas glade demos po tests docs
./libgnomecanvas-zip.in:lib/libglade/2.0/libcanvas.dll
./libgnomecanvas-zip.in:lib/libglade/2.0/libcanvas.dll.a
./configure.in:m4_define([libglade_required_version], [2.0.0])
./configure.in:PKG_CHECK_MODULES(CANVAS_GLADE, $CANVAS_MODULES libglade-2.0 >= libglade_required_version)
./configure.in:glade/Makefile
./po/POTFILES.skip:tests/test-libglade-canvas.glade
./tests/Makefile.am:	test-libglade-canvas
./tests/Makefile.am:	LIBGLADE_MODULE_PATH="$(top_builddir)/glade/.libs:$(LIBGLADE_MODULE_PATH)"
./tests/Makefile.am:	-DGLADEFILE=\""$(srcdir)/test-libglade-canvas.glade"\"
./tests/Makefile.am:test_libglade_canvas_SOURCE = test-libglade-canvas.c
./tests/Makefile.am:EXTRA_DIST = test-libglade-canvas.glade
./tests/test-libglade-canvas.c:#include <glade/glade-xml.h>
./tests/test-libglade-canvas.c:	xml = glade_xml_new (GLADEFILE, NULL, NULL);
./tests/test-libglade-canvas.c:		toplevel = glade_xml_get_widget (xml, "window1");
./tests/test-libglade-canvas.glade:<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd" >
./tests/test-libglade-canvas.glade:<glade-interface>
./tests/test-libglade-canvas.glade:</glade-interface>
Comment 16 André Klapper 2009-07-30 15:41:12 UTC
(In reply to comment #15)
> plus maybe update deprecated GTK and Glib functionality.

There is a patch in bug 567765 for this that requires review.
Federico, or anybody?
Comment 17 André Klapper 2009-07-30 16:18:58 UTC
Filed bug 590284 about libgnomecanvas using libglade.
Comment 18 André Klapper 2009-08-10 09:35:23 UTC
Cough.

libgnomecanvas heavily uses libart_lgpl which is deprecated too.
Porting this to Cairo does not look like a trivial task either.

Filed bug 591304.
Comment 19 Alexander Larsson 2009-08-11 14:17:03 UTC
If you can, I would recommend using FooCanvas. It is a port of the pre-antialiased version of gnome-canvas re-ported to Gtk2, used by e.g. nautilus and gnumeric.

Its a lot smaller and easier to maintain, plus its IMHO better integrated with the Gtk2 redraw cycle. Given that its based on the same code the API is almost identical, but without the AA stuff it doesn't support the antialiased libart mode (although you can still draw AA stuff using cairo) and it doesn't support affine transforms (only translations and scaling).
Comment 20 Srinivasa Ragavan 2009-08-11 17:45:05 UTC
Something I recall now, but not earlier. Though, Evolution uses gnomecanvas for etable and minicard, I remember I mentored an intern to draw everything with cairo inside the canvas. Not sure, how much relevant this information is, but the the UI is completely drawn with cairo & pango/cairo for text. It could be possible to move that drawings to a non-canvas widget as well, or some better alternatives.

The minicard view and the e-table are the major users of libgnomecanvas, other includes some misc widgets. In ETable mainly the Etext and the headers. EText is rendered using Cairo+PangoCairo manually. So it seems to me that GnomeCanvas was a mere carrier here. Not sure, how easy is this to move away from it, but this can trigger some better ideas.

Note: Im not speaking of deprecating Gal/*. But seeing if we can move GAL from libgnomecanvas to something else, with what we had done with Cairo. Ignore this, if it isn't relevant. 
Comment 21 Matthew Barnes 2009-08-14 15:26:21 UTC
I started a private branch to port Evolution to FooCanvas.

It builds and runs without crashing, but has drawing issues -- particularly with the calendar.  Also emits lots of warnings on the terminal.

I had to make assumptions in our FooCanvas subclasses that I'm unsure about:

The signature of GnomeCanvasItem::draw() changed.  GnomeCanvasItem::draw() passes x, y, width and height arguments.  FooCanvasItem::draw() passes a GdkEventExpose pointer instead.  Is the expose->area rectangle equivalent to the previous arguments?

The anti-aliasing parts seemed fairly easy to work around.  I just assumed the canvas->aa flag (which is not present in FooCanvas) is always false, and adapted our logic accordingly.

Some of our subclasses seem to rely heavily on affine transformations, even making direct calls into libart_lgpl.  This is the part I'm least sure about.  I basically just copied things over from libgnomecanvas and libart_lgpl as needed, but I don't know if that's correct.

Also, we're still pulling in libgnomecanvas by way of libgnomeui.  So I guess once again I'm blocked until we migrate off of GnomeDruid.

Help or advise would be appreciated.  I'm setting the branch aside for now.
Comment 22 Federico Mena Quintero 2009-08-14 18:05:38 UTC
Matthew, where do you have that branch?  I'd love to take a look.

I did a quick grep of "art_affine" in the Evo sources, and it seems to mostly use things like

  double i2c[6];
  ArtPoint corner_in_item_coordinates;
  ArtPoint corner_in_canvas_coordinates;

  /* Get me the transformation to go from item coordinates to canvas coordinates */
  gnome_canvas_item_i2c_affine (item, i2c);

  corner_in_item_coordinates.x = foo;
  corner_in_item_coordinates.y = bar;

  art_affine_point (&corner_in_canvas_coordinates, &corner_in_item_coordinates, i2c);

  /* Repeat the above for the other corner */

Then, the transformed coordinates are used to propagate the bounding box to parent items, to figure out tooltip positions in root-window coordinates, to draw with cairo on the canvas window, etc.

I'm not sure how FooCanvas items keep track of their offset within their parent group, but since we don't seem to actually use any affine transformations other than translations, this should be easy to figure out.
Comment 23 Matthew Barnes 2009-08-15 02:10:13 UTC
(In reply to comment #22)
> Matthew, where do you have that branch?  I'd love to take a look.

I just pushed my "foocanvas" branch to git.gnome.org.  Unfortunately it's all in one giant commit.  Had I been smarter I would've kept the simple s/gnome_canvas/foo_canvas/ changes in a separate commit, but I didn't anticipate anyone seeing this.

http://git.gnome.org/cgit/evolution/commit/?h=foocanvas&id=5906d201113d2bc2db811ab2f01a4a8b38380f21

Note that this is a branch off of "kill-bonobo" (soon to be 2.29.1), not "master".
Comment 24 Matthew Barnes 2009-08-15 02:15:52 UTC
Oh and feel free to commit to that branch if you're inclined to hack on this at all.
Comment 25 Alexander Larsson 2009-08-19 06:37:50 UTC
For draw, using expose->area is equivalent to the old stuff. But, as a further optimization you could use expose->regions which may be smaller.

And I agree with federicon on the affines, In my short look there didn't seem to be any use of affines for anything but tranlations, so you should be able to rip out that code and replace it with dx/dy offsets.
Comment 26 Matthew Barnes 2009-08-19 10:49:18 UTC
(In reply to comment #25)
> And I agree with federicon on the affines, In my short look there didn't seem
> to be any use of affines for anything but tranlations, so you should be able to
> rip out that code and replace it with dx/dy offsets.

Thanks.  It would help me to see an example or two, as I know nothing about this stuff.  If I can just get an idea of what that should look like then I can finish the grunt work myself.
Comment 27 Alexander Larsson 2009-08-24 10:49:30 UTC
I'll try to describe how it works. A canvas is a "blank area" where you can add "items" that render themselves, then you can change properties on these items to have them animate, move around, etc.

For instance, a "rectangle" item would have perhaps x1, y1, x2, y2 properties that let you change where its drawn, and a circle one could have x, y, radius properties. 

Additionally, there is a "group" item which has other items as children. The coordinate systems of groups are inherited, so that if you put a bunch of items in a group and then move the group then all items in the group would move on the screen. However the x/y properties of the child items would not change, this is because the cordinates specified by the items are in "item coordinates" which are converted to "world coordinates" when drawing, by walking the item hierarchy.

Additionally, in gnome-canvas (but not in foo-canvas) each item can have a generic affine transformation (affine == linear + translation) applied. This transformation is applied to the coordinate system of the item e.g. when its drawn, etc. So, you can easily rotate your rectangle by just applying a rotation transformation to it. Or you can move it by applying a translation (this would not change the x1/y1/etc properties of the object, just draw it elsewhere).

This last item does not exist in foo-canvas. In foo canvas all item coordinates are purely that of their parent, with the exception of groups. Each group has a position (and thus x/y properties), and this position is added (recursively over the hierarchy) to the offsets of each items positions. Additionally foo canvas has a "translate" item specific method to let you generically move and item by dx/dy (you'd do this by adding a translation in gnome-canvas).

There are various things that this affect. For instance, each item generally has a lot of cached stuff depending on its state, and whenever things that affect the item changes the "update" method gets called to let the item update its cached stuff. In gnome-canvas the update method gets passed a full affine transformation that can be used to map item to world coordinates, whereas in foo-canvas you just get a dx/dy pair to do this mapping.

There seems to be one thing in evo that needs a bit of checking to convert, and 
that is e_canvas_item_move_absolute(). This sets the affine transform of an item to a specified translation, ignoring what was there before. I'm not sure exactly how this is used in evo, but its not directly applicable to foo-canvas as-is, because in foo-canvas if you move an item by a translation that actually just modifies the item properties that affect the position, so you can't really reset the bit that affected the translation. You'll have to figure out how/why this is used and do the same thing in some other way.
Comment 28 Matthew Barnes 2010-01-13 21:12:38 UTC
I've taken down my previous "foocanvas" branch and pushed a new one based on current master.  No changes beyond what was there before, but I've reconstructed the branch as a series of discrete commits instead of one massive commit to make it much easier to review.

The most important commit is this:

"Adapt to API changes between GnomeCanvas and FooCanvas."
http://git.gnome.org/browse/evolution/commit/?h=foocanvas&id=c9c64c23f230d55cc2672ffb1d63ed7951fd3fbc

Right now the branch builds and runs without crashing (for the most part), but things don't render properly.  For example I can see the initial message list, but it doesn't repaint itself properly when I try to scroll.

I'll keep poking at this, but a little help from the experts would be most appreciated.
Comment 29 Matthew Barnes 2010-06-14 03:10:51 UTC
I've embedded libart_lgpl and libgnomecanvas [*] into Evolution for GNOME 3, which makes the "foocanvas" branch pointless.  I hope someday GNOME will finally pick a canvas library so we can dump this baggage.

http://git.gnome.org/browse/evolution/commit/?id=e6972011f01eab9f8d0a4584f32ee1e2a00f3231


[*] I only copied the "libgnomecanvas" directory from the libgnomecanvas module.  No demos, no tests, no libglade dependency.
Comment 30 Hussam Al-Tayeb 2010-06-14 08:02:56 UTC
Why not make it possible to use both internal and system gnomecanvas/lgpl_art?