/plugins/LoadProgress.cs
using System;
using Gtk;
using WebKit;
using bytex64.WebThing;

public class LoadThrobber : Gtk.DrawingArea {
    public enum Mode {
        LoadStarted,
        LoadInProgress,
        LoadFinished
    };
    public Mode LoadState;
    int r;
    uint idletimer;

    public LoadThrobber(WebThing wt) {
        LoadState = Mode.LoadStarted;

        SetSizeRequest(64, 64);
    }

    public void AttachSignals(WebView wv) {
        wv.LoadStarted += WebView_LoadStarted;
        wv.LoadCommitted += WebView_LoadCommitted;
        wv.LoadProgressChanged += WebView_LoadProgressChanged;
        wv.LoadFinished += WebView_LoadFinished;
    }

    protected override bool OnExposeEvent(Gdk.EventExpose e) {
        Gdk.Window w = e.Window;
        Gdk.GC gc = new Gdk.GC(w);
        int width, height;
        w.GetSize(out width, out height);

        gc.Foreground = new Gdk.Color(0, 0, 0);
        gc.SetLineAttributes(3, Gdk.LineStyle.Solid, Gdk.CapStyle.Butt, Gdk.JoinStyle.Round);
        w.Clear();

        switch(LoadState) {
        case Mode.LoadStarted:
            w.DrawArc(gc, false, 4, 4, width-8, width-8, -r*64, 90*64);
            w.DrawArc(gc, false, 4, 4, width-8, width-8, -r*64 + 180*64, 90*64);
            r += 5;
            break;
        case Mode.LoadInProgress:
        case Mode.LoadFinished:
            w.DrawArc(gc, false, 4, 4, width-8, width-8, 90*64, -r*64);
            break;
        }
        return true;
    }

    void WebView_LoadStarted(object o, LoadStartedArgs e) {
        this.Show();
        //Console.WriteLine("Loading Started");
        LoadState = Mode.LoadStarted;
        idletimer = GLib.Timeout.Add(100, delegate {
            QueueDraw();
            return true;
        });
    }

    void WebView_LoadCommitted(object o, LoadCommittedArgs e) {
        //Console.WriteLine("Loading Committed");
        LoadState = Mode.LoadInProgress;
        GLib.Source.Remove(idletimer);
        r = 0;
        QueueDraw();
    }

    void WebView_LoadProgressChanged(object o, LoadProgressChangedArgs e) {
        //Console.WriteLine("Loading Progress: {0}", e.Progress);
        r = (int) ((e.Progress / 100.0) * 360);
        QueueDraw();
    }

    void WebView_LoadFinished(object o, LoadFinishedArgs e) {
        //Console.WriteLine("Loading Finished");
        LoadState = Mode.LoadFinished;
        this.Hide();
    }
}

public class LoadThrobberPlugin : WebThingPlugin {
    LoadThrobber lt;

    public override void Init(WebThing wt) {
        lt = new LoadThrobber(wt);
        wt.AttachWidget(lt, AttachPoint.Interior);
    }

    public override void InitWebView(WebView wv) {
        lt.AttachSignals(wv);
    }
}