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.