Standalone Silverlight Applications

by Miguel de Icaza

Last year we created a framework to run Silverlight applications as native applications. At the time we called those applications moonlight desklets.

The desklets are Silverlight applications that run in standalone mode, with full access to the entire Mono API stack (as opposed to be limited to the .NET subset for the web) and that can optionally render without frames. This is a screenshot from three desklets running on Linux from last year:

Beyond hack-value, there are in my opinion many reasons why this is valuable. Powerful .NET programming model, powerful graphics and animation framework, reuse the same code base for Web and desktop development, and a sandboxed execution model.

Many people have asked us privately about this.

The Magical mopen Command

To run a standalone desklet, all you have to do run the mopen command, like this:

	$ mopen ruler
	

The above command will look for a directory called "ruler" listed in your PATH, and if the file default.xaml lives inside that directory, it will open that file up. This XAML file can in turn reference managed code.

We did this so applications could be deployed in directories, very much like they are deployed on MacOS. The rules are simple, applications should be self-contained, keep all their data relative to their executable base directory, the foundation for this started with our application deployment guidelines.

It also draws inspiration from the bundles from MacOS X and the `open' command there.

How does this work? Lets consider our enterprise pixel measuring tool, the Moonlight ruler, which is made up of two files:

  • default.xaml, the basic XAML container, it references the managed code in ruler.dll
  • ruler.cs contains the code to draw the ruler.

This is what it looks like when you run it:

Awesome Moonlight desktop ruler.

Details

At LugRadio Live this weekend in San Francisco I decided to turn my Mono talk into a Moonlight talk, and I discussed some of the things that we have been doing with Moonlight.

Let me start with this artist rendition of Moonlight's Core:

The orange pieces were built by the Mono/Moonlight team at Novell. The green pieces are provided by Microsoft (and only for use in the browser context, we will get back to this later) and the blue stuff is stuff that we consume from the community.

The Moonlight Core provides the high-level canvas, the XAML loading, the animation framework, timers, media streaming and demuxing and event dispatching. It also has very few dependencies, it uses Cairo to render graphics and interfaces with our media pipeline and needs codecs to do video (currently ffmpeg if you build from source, or Microsoft's when we release).

Our engine today has three frontends:

The most important one of course is the plugin front-end, the one that is embedded into Firefox and renders the Silverlight content.

The other front-end is a Gtk# widget, a simple Gtk+ host that embeds the Moonlight Core into a widget and allows developers to embed any kind of XAML content (including managed code) inside it. I did a demo of Banshee embedding a grid of video players at LugRadio.

This is a widget that can be used to spice up your application. If you feel that you need some bling for your application, some gratuitous animations and special effects, the GtkSilver widget can help you. Using it is trivial:

	using Gtk.Moonlight;

	[...]
	void SetupWidget ()
	{
		Application.Init ();
	
		GtkSilver surface = new GtkSilver ();

		surface.LoadFile ("MyAnimation.xaml");

	        
		Window w = new Window ("Demo");
		w.Add (surface);
		w.ShowAll ();
		Application.Run ();
	}
	

If you want to get a handle on specific objects, you can just use the FindName method on the surface's canvas:


	MediaElement handler = (MediaElement) surface.Canvas.FindName ("MyVideoPlayer");

	// Start playback.
	handler.Play ();
	

And the third interface is the fabulous mopen command that we previously described (which is conveniently implemented on top of GtkSilver; yes, we know, we are geniuses).

The Two Stacks

As you might suspect from reading about GtkSilver and the browser, the Moonlight managed stack (that is, the C#/.NET APIs) actually comes in two shapes:

  • Browser API: This is what people creating Silverlight applications are familiar with. Its a subset of .NET 3.5 and it has limitations as to what you can do: no local file system access and a sandbox that encapsulates all the actions of Silverlight applications.
  • Full API: We also offer the full API, this is our implementation of .NET 3.5 that has been augmented with the Silverlight APIs.

As you can guess, GtkSilver and the desklets today use the Full API; And our browser plugin uses the more limited Browser API and the security sandbox.

We will get back to this soon.

Adobe Air

Adobe AIR has a great experience for installing native applications on your system, and they are cross platform (Windows, Mac and Linux).

I found a cute twitter application built with it, and have been a happy user of it for a few weeks (see screenshot).

I have no idea how extensive the AIR APIs are, whether they are sandboxed or whether they provide full access to all the APIs like our Moonlight Full API provides, but you can build some cute desktop applications with it.

I like it.

Silverlight Desktop Apps

Part of the reason why our Desklets did not evolve much in the last year was because there were no controls for them. You could build your own, but that was a lot of work, and it was hard to share, and most importantly, everyone knew that Microsoft was going to ship controls for Silverlight.

Now that controls are part of Silverlight 2.0 and that most of the high-level controls have been open sourced and that they are incredibly powerful and great to skin it makes sense to think again about native desktop applications using Silverlight.

We as a team can certainly create a Linux-only platform for these controls, and live happily with mopen, but we would miss an opportunity of having something cross platform like AIR is.

Ideally, Microsoft would follow our direction and implement and distribute the same mopen functionality that we have for Windows and Mac. This would ensure maximum adoption of standalone Silverlight-applications.

In a less ideal world, we (the Mono/Moonlight community) could port Moonlight's mopen command to Windows and MacOS, but with none of the power of influence that Microsoft has.

Directions and Challenges

Michael Hutchinson has suggested that we should have an minstall tool in the same spirit of mopen. This tool would take care of installation on each platform, creating shortcuts, desktop links and using the right icon.

Moonlight currently runs on systems with Cairo, and requires Gtk+ for event processing. It might be interesting to get it running on Win32, OSX and others with the tiniest footprint possible (bundling Gtk+ for Windows and MacOS for native apps sound large).

Another alternative is to use Microsoft's Silverlight on Windows to implement `mopen' as opposed to porting Moonlight. Apparently its possible to instantiate it through COM in some form, but that would still leave OSX out.

The codecs that Microsoft will distribute for use with Moonlight are limited to use inside the browser. This will prevent Moonlight's standalone applications from playing back any vc-1, wmv, wma, mp3 content.

We could add OS-specific codecs; On Linux we could call into Fluendo's commercial codecs, on Windows and Mac use the system codecs.

But we could also standardize on free video and audio codecs for the desktop edition: add support for the free video and audio codecs (BBC's Dirac, which will become VC-2, Vorbis and Theora).

We are currently busy doing Moonlight 1.0, and then we will get busy doing 2.0. So we will not be able to spend time on any of these projects for quite some time, but these are projects that developers in the community could work on or companies interested in pushing Moonlight in that direction.

Discuss.

Posted on 17 Apr 2008