You are viewing mbarnes

Evolution Will Soon Bid Farewell to Bonobo

This is a combination announcement, history lesson, status report and call for help.

For nearly a year I've been laboring over an Evolution branch named kill-bonobo, whose goal is exactly that: eradicate Bonobo from Evolution once and for all. According to the GNOME release schedule, I'm due for a status report. (Note, this only pertains to the application itself. The data server is already being ported from Bonobo to D-Bus by Ross Burton. The two projects are independent.)

The kill-bonobo branch is strictly an internal cleanup effort, albeit a massive one. It's not about adding features or radically changing the end-user experience. It's about making Evolution easier to maintain and enhance as we enter into the GNOME 3 era. So if I've done a good job, users will hardly notice any difference when the branch is finally merged.

Those who are interested in testing the branch can skip to the "How to Help" section.

Why We Need It

I was not present for the early evolution of Evolution, so this account is based on historical research and discussions with some of the old-timers. Hopefully they won't clobber me for getting the details wrong, or for calling them old-timers.

Evolution's original design consisted of a simple skeletal "shell" which served as the framework for out-of-process Bonobo components. Each component managed different types of information: one for email, one for calendar events, one for contacts, etc. The components talked amongst themselves via CORBA, which handled all the IPC. Ettore Perazzoli, in his paper for the 2001 Ottawa Linux Symposium, wrote:
It is interesting to note that the various pieces of Evolution are currently out-of-process components, and that CORBA deals with the inter-process communication nicely and transparently; it would be possible to turn these components into shared libraries without any substantial changes to the code.
And that's exactly what happened. The components were turned into shared libraries sometime later to help address some design issues and to make the application more debuggable. Evolution then became — and has remained — one monolithic process. Most of its functionality is still supplied by in-process Bonobo components loaded at run-time. Bonobo was kept around in part for the menu merging capabilities of libbonoboui, but also because it was already very deeply ingrained in the application by then. To this day, Bonobo still handles all the inter-component communication, even though it's all one process.

Fast forward to present day. Bonobo has fallen out of favor with the rest of the GNOME community and its libraries are now deprecated (or planned to be deprecated — the distinction is unclear). GTK+ has gained a menu merging capability in GtkUIManager, GObject has gained a module loading system in GTypeModule, and developers are scrambling to migrate code away from deprecated libraries and API in preparation for GNOME 3.

Moreover, the inability of Evolution components to interact directly with the central shell continues to be a major design impediment. Certain bugs cannot be fixed and enhancements cannot be implemented with Bonobo in the way. Even something as simple as setting the proper relationship between a dialog window and the main application window can't be done under the current design without breaking the component/shell abstraction.

In short, Bonobo's time has passed and it needs to get gone.

What's Finished

A New Shell

I have rewritten Evolution's shell from scratch. While still adhering to the original design principles, it now loads components (I'm calling them "shell backends" just to get away from the CORBA nomenclature) at startup via GTypeModule. Each main shell window provides a central GtkUIManager instance for shell backends to merge and un-merge their menus and tool bars. The new shell provides a bunch of other convenient services that it didn't, or couldn't, before. The API is now mostly stable, and it's documented! (A trend I hope to continue.)

The shell itself is a subclass of UniqueApp from libunique, so Evolution is still a single instance application. In fact, that feature has improved. Starting a second Evolution instance with no command-line options will now raise and focus the current window instead of opening a new one; a behavior greatly preferred by users. Also, Evolution will now terminate when it's finished handling a command-line URI and there are no other Evolution windows running.

Infrastructure

Beyond the shell, it's mostly been a matter of slogging through the rest of the code and adapting it to the new shell API and the more modern GTK+ APIs. Turns out, Evolution has a lot of code, and a lot of infrastructure that piggybacks on Bonobo. Needless to say, that's why it's taking so long.

All of the menus and tool bars, and many of the stand-alone buttons and combo boxes, are now proxy widgets for GtkActions. EMenu and EPopup — the mechanisms that allow plugins to extend menus — are being phased out in favor of EPluginUI, which works with GtkUIManager. In fact, many of the plugins themselves are being phased out — their features being properly integrated into the application.

Asynchronous activity tracking — that's those percent-complete and error messages in the status bar — is now more object-oriented. The shell even lends a hand in routing and tracking these activities. I have a number of ideas for leveraging this new framework. Eventually I'd like to eliminate pop-up error dialogs altogether in favor of something less obnoxious, such as "inline" alert messages similar to those in Firefox, gedit, Sound Juicer and Evince. Also, better shutdown management — where Evolution tells you what network activities are keeping it from shutting down and allows you to cancel them.

Just getting the thing to build was another challenge. What I assume was once a nice layered design with clean separation of concerns has grown into a tangled mess of circular dependencies. I've managed to resolve most of the linking issues by shuffling source code around and routing application-wide events through the shell. But there's still the issue of library modules linking to library modules (plugins linking to shell backends and shell backends linking to one another), which is not portable and in fact prevents Evolution from building on Mac OS X.

Shell Backends

The contact, memo and task backends are done, and I'm currently wrapping up some loose ends on the mailer. All are usable and ready for testing. I personally have been using the kill-bonobo branch for daily email and task management since February.

Calendars, however, are another story. See below.

What's Unfinished

The branch is about 75% complete. It's usable, but there's still significant work to be done.

The Calendar

The calendar is half-finished and is not yet usable. This is the last major piece left.

I was attempting to split up the massive GnomeCalendar class into smaller, more manageable pieces. But I got burnt out and had to set it aside for awhile, and then never got back to it. At this point I'm in favor of just getting it working as quickly as possible. I can take another shot at refactoring it later when I'm feeling masochistic again.

Plugins

Many of the plugins still have to be adapted to EPluginUI and the new shell. This is a highly parallelizable area where I could use some help from volunteers. The working and non-working plugins are listed in "configure.ac" (search for PLUGINS NOT BUILDING YET).

Evolution Exchange

Evolution Exchange (formerly the "Ximian Connector for Microsoft Exchange Server") presents an interesting problem. The evolution-exchange-storage process is the last out-of-process Bonobo component that talks to the shell. Ximian originally released this software under a non-free license, and used the split process design to bypass the linking restrictions imposed by the GPL. Later, after Ximian was acquired by Novell, it was released under an open-source license. But the design remained unchanged, even after Evolution was collapsed into a single process application.

I'm uncertain of what to do with this. To me, the best solution would be to convert the storage process to shared library modules for the Evolution and Evolution Data Server processes. But that could take some doing, and time is short. Plus, Evolution Exchange is being phased out by Evolution MAPI anyway. Another option is to hack together a quick and dirty D-Bus API for the shell, which the storage process can use. But I'm hesitant to expose a poorly thought out D-Bus API just for a corner case.

Third-Party Extensions

Third-party extensions such as evolution-rss, evolution-brutus, and evolution-jescs will likely require some re-design. I will lend a hand here as much as possible.

How to Help

The best way to help right now is to test drive the kill-bonobo branch and file Evolution bug reports at http://bugzilla.gnome.org/. Since this is an unofficial branch I have my own little system for tracking reports in Bugzilla. But really, if you do file a bug just mention that you're running the kill-bonobo branch and I'll take care of the rest.
  • Existing bugs that the branch may be able to address are tagged with evolution[kill-bonobo] in the Status Whiteboard field. (Bug List)

  • Existing bugs that the branch has successfully addressed are tagged with evolution[kill-bonobo] in the Status Whiteboard field and the Summary field prefixed with [KB-Fixed]. (Bug List)

  • Regressions that the branch has introduced get tagged with evolution[kill-bonobo] in the Status Whiteboard field and the Summary field prefixed with [regression]. These are what I'm looking for. (Bug List)

Evolution developers and contributors looking to hack on stuff could start by picking a non-working plugin and getting it back on its feet (see the previous section). That would probably acquaint you with the new shell API, and possibly expose bugs or shortcomings in the design. Catch me on GimpNet (channel #evolution) if you're interested in this.

For Fedora users, I will attempt to publish a kill-bonobo RPM repository for Fedora 12 / Rawhide in the near future. Stay tuned.

Credits

Finally, I have to give props to my employer for humoring me through this ordeal, especially since I've consistently underestimated the workload. While the work has been largely exploratory and at times overwhelming, in the end it's been highly educational and satisfying.

Comments

(Anonymous)

Speed enhancement

Hi, great work for that major rewrite, can you tell us about performance impact ? Is it faster ? Thanks !

Re: Speed enhancement

I've observed no change in performance. Most of the affected code is just interactive UI stuff.

(Anonymous)

you truly are a hero for dealing with this. you should get a lot of beer at GUADEC!

-- Emmanuele | http://blogs.gnome.org/ebassi

(Anonymous)

Beers at GUADEC

This is awesome news! I can't dedicate time but can dedicate beers to the cause :)

-- Neil (njpatel)

evolution-exchange

I always found evolution-exchange to be so unstable as to be completely useless anyway. It's been a couple of years since I last used it now, so maybe it's improved since then, but meh.
Hooray!

(Anonymous)

Thanks!

Thanks for all the efforts you made for this branch and Evolution so far! You rock!
Wow, sounds like great work!

Nice...

That's pretty good to hear, still I'd have liked it better if we got a evolution-daemon, kind of like evolution-data-server but with email checking and fetching and different interfaces for mail, contacts and calendar on top of it, as the current evolution interface sometimes feels limited because of it multiple purposes (and has the biggest menu ever)

Re: Nice...

That's being considered for after 3.0, but Ross' E-D-S/D-Bus branch has to land first.

(Anonymous)

Re: Nice...

I really hope for that, too.

The only reason I use evolution is contacts and calendar and it's annoying that you have to setup an account with an email for that if you don't want to use email functionality.

(Anonymous)

"Also, better shutdown management — where Evolution tells you what network activities are keeping it from shutting down and allows you to cancel them."
Yey, that would be great! When my ISP is down (but the network is "online") I always have to kill Evolution.

(Anonymous)

evolution-exchange-storage

Not sure how hard this would be, but since evolution-exchange is itself deprecated, maybe you could just leave it using bonobo, and just write an evolution-exchange-storage-bonobo-bridge shell backend, which would speak shell-backend-ese on one side and bonobo on the other, and then evolution-exchange-storage itself could remain unchanged. Maybe something like that could be used temporarily with the other third-party backends too?

(Anonymous)

Components

Does the switch to GTypeModule mean that I can pull out the calendar and have it run as its own app if I write the wrapper code?

Re: Components

That would fall under the "not radically changing the end-user experience" part I mentioned. Not yet, but it's a step in that direction.
sorry, if it's wrong place for this question, but..
what about idle in imap at evo? I can't use it at my fork without idle :(
a hate mozilla and all about it, but I have to use thunderbird :(

(Anonymous)

Excellent!

Wonderful work Matthew! Keep on it and hopefully you'll get over the line by the time of 3.0. It would be great if other Evo developers pitched in, so that we get it in time for 2.28... One can only hope :-)
Great view I recently hit on your blog and have been reading along. I thought I would leave my incipient comment. I don’t know what todiscloseexcept that I have enjoyed reading. Correct blog. I will keep visiting this blog very each.

June 2012

S M T W T F S
     12
3456789
10111213141516
17181920212223
24252627282930
Powered by LiveJournal.com