← Back to team overview

elementary-dev-community team mailing list archive

On Contractor and Luna


Hey guys,

I have some unpleasant things to bring up. Sorry for the long post, I hope
it will not end up being another "TL;DR". (Come on, this is important!)

As I've already reported, the current Contractor API is flawed. It relies
on the client app calling
the string Contractor returns, which is bad for a long list of
The most apparent one is being unable to handle filenames with spaces in
them <https://bugs.launchpad.net/contractor/+bug/1123040>! This particular
bug can be worked around in Contractor in an ugly way, but other issues
remail and the API is not future-proof, so *we'll have to break it and
Granite API/ABI* sooner or later (because Granite provides widgets and
convenience functions for accessing Contractor API). Obviously it's better
done sooner than later, while we don't have much code to transition and
before the relevant Granite widgets get into a stable release.

The more future-proof approach is to return a contract identifier to the
client app and make the app call Contractor again to execute an action,
passing it the identifier and the filename. This way Contractor can use
proper process-launching functions or use completely different last-mile
data transfer mechanisms<https://docs.google.com/document/d/1_w6-XBtr9qXXteytC9Mz0JqXZZoMsOPdfTDXVcoswUY/edit#>,
so we'll be able to add support for streaming data without writing it to
disk or invoking D-bus methods, all without breaking the API in the future.

I've investigated the problems of the current Contractor and wrote a better
detailing its expected behavior and the required API changes. I've
discussed it with the original Python Contractor authors and got the green
light from them. Michael Lazarski (lampe2) has taken a stab at cleaning up
Ammonkey's code and implementing the spec, but he's currently preoccupied
by contracted work (no pun intended). His Contractor branch can be found at

Additionally, I've looked into the state of Contractor support in Granite
and elementary applications. In short, it's not glamorous.

None of the apps use the Granite-provided ContractorMenu widget for the
"Export" button; every single app reinvents the wheel and populates regular
GTK menu with items acquired from Granite's Contractor wrapper. Maya (the
least ugly implementation I've seen so far) even has a dedicated widget
that's a clone of ContractorMenu!

The other Contractor widget, ContractorView, is used only by Eidete where
it doesn't seem to work; not sure if that's Contractor's fault or Eidete's.

Finally, I don't understand why Granite has a wrapper for Contractor - it
doesn't seem to reduce complexity or abstract anything. Using the D-bus API
directly requires almost the same amount of code.

So IMO the proper course of action is the following:
 * Rework Contractor's D-bus API according to my
 * Deprecate/abolish the Contractor wrapper in Granite
 * Update Granite widgets and Pantheon Files to work with the new D-bus API
 * Migrate other applications to using the Granite widgets (currently Maya,
Scratch, Midori and elementary-flavored Simple Scan)

However, I'm not sure this course of action is feasible for Luna.

I'm absolutely not OK with releasing Granite with an API so flawed and
which we're going to break in the future, so the alternative is to replace
the current Contractor wrapper functions with stubs, mark them deprecated
and replace Granite functionality in apps with something else.

The options that spring to mind are:
 * Replace Contractor actions with "Open With"
 * Replace Contractor actions with a roughly similar but severely limited
nautilus-sendto. Despite its name it's not actually related to Nautilus.
This way we get sending files by bluetooth, email and IM; the catch is that
Geary is not supported by nautilus-sendto, so we'll have to implement it
(it should be done sooner or later for decent integration with Ubuntu).
 * Remove the "Export" button from apps altogether


Sergey "Shnatsel" Davidoff
OS architect @ elementary

Follow ups