Mono Validates Swing Architecture

The Mono project is working on creating a portable version of the System.Winforms .NET library. Like most such efforts to create a cross-platform GUI toolkit, they had two main choices that I'm calling "Bare Canvas" and "Native Controls":
  • "Bare Canvas": Use only a bare canvas from the underlying windowing system and render all controls themselves.
  • "Native Controls": Use higher-level controls (buttons, labels, combo boxes, etc.) from the underlying windowing system and try to hide differences in behavior between different systems.
Here the Mono WinForms folks describe their choice of "Bare Canvas":
   System.Windows.Forms in Mono is implemented using System.Drawing. All
   controls are natively drawn through System.Drawing.

   System.Windows.Forms implements it's own driver interface to
   communicate with the host OS windowing system.
And the primary rationale:
   The Gtk effort had the following problems:
     * Mapping one toolkit semantics to another was very hard.
The Mono folks, regardless of your political views of Mono, are clearly bright and energetic folks, having implemented a lot of high-quality code in a short amount of time. For them to choose "Bare Canvas" is a clear sign that the same decision made by the Swing team some years back was the right one.

Problems with "Native Controls" Style

The problem with the Native Controls style, as groups like the SWT team are finding, is that it is more difficult to make many different, complicated native controls on different platforms work alike using wrappers than it is to build those controls on top of a simple abstraction layer, the bare canvas.

Let's say that right-clicking on a button produces an event on platform A but nothing on platform B. Platform A advocates will insist that feature be available in the toolkit to ensure equality with native apps. But in order for apps to work the same on all platforms, suddenly the toolkit must support a feature that isn't available natively on platform B. So now there are several ugly alternatives:

  • Leave out the feature entirely from the toolkit. Users of platform A miss the feature. The toolkit is missing useful functionality. However, apps are guaranteed to work on all platforms. Also, it is hard to add support for new platforms since a new platform that has fewer features in some area will not even meet the "least common denominator" requirements. Then the toolkit has to have that feature removed (breaking apps that use it) or the feature has to be emulated, which leads us to the next item...
  • Try to emulate platform A behavior on platform B. Perhaps put a transparent window over the button, pass through left-clicks and handle right-clicks. This requires potentially a lot of work on platform B. It also means that on each successive platform that comes along, if the feature is missing it must be custom-coded, no matter how complex, in order to guarantee that apps run the same. This has huge time costs and can make porting to new platforms prohibitively expensive. However, applications are guaranteed to work on all platforms.
  • Give up on full cross-platform compatibility. Use neat features on platforms that have them, but don't implement them on platforms that make it too difficult. The toolkit is much easier to create now. Portability is much easier, since if a feature is too hard you can punt on it altogether. Of course using the toolkit is now an exercise in masochism. Want to use a toolkit control? Better check that it works on your platform of interest. Want it on platform B? Better write it yourself. This is scarcely better than writing the GUI separately for each native windowing system and avoiding the toolkit altogether.

Last modified on 21 Dec 2005 by AO

Copyright © 2020 Andrew Oliver